win-pvdrivers

changeset 991:e9903455ba9d

Fix low gref resource handling. again.
Tidy up.
author James Harper <james.harper@bendigoit.com.au>
date Fri Sep 21 23:25:36 2012 +1000 (2012-09-21)
parents 20ea0ca954e4
children 58899e6ed48f
files xenvbd/xenvbd_storport.c
line diff
     1.1 --- a/xenvbd/xenvbd_storport.c	Fri Sep 21 23:24:00 2012 +1000
     1.2 +++ b/xenvbd/xenvbd_storport.c	Fri Sep 21 23:25:36 2012 +1000
     1.3 @@ -51,11 +51,11 @@ ULONGLONG parse_numeric_string(PCHAR str
     1.4    return val;
     1.5  }
     1.6  
     1.7 +/* called with StartIoLock held */
     1.8  static blkif_shadow_t *
     1.9  get_shadow_from_freelist(PXENVBD_DEVICE_DATA xvdd)
    1.10  {
    1.11 -  if (xvdd->shadow_free == 0)
    1.12 -  {
    1.13 +  if (xvdd->shadow_free == 0) {
    1.14      KdPrint((__DRIVER_NAME "     No more shadow entries\n"));
    1.15      return NULL;
    1.16    }
    1.17 @@ -65,12 +65,14 @@ get_shadow_from_freelist(PXENVBD_DEVICE_
    1.18    return &xvdd->shadows[xvdd->shadow_free_list[xvdd->shadow_free]];
    1.19  }
    1.20  
    1.21 +/* called with StartIoLock held */
    1.22  static VOID
    1.23  put_shadow_on_freelist(PXENVBD_DEVICE_DATA xvdd, blkif_shadow_t *shadow)
    1.24  {
    1.25    xvdd->shadow_free_list[xvdd->shadow_free] = (USHORT)(shadow->req.id & SHADOW_ID_ID_MASK);
    1.26    shadow->srb = NULL;
    1.27    shadow->reset = FALSE;
    1.28 +  shadow->aligned_buffer_in_use = FALSE;
    1.29    xvdd->shadow_free++;
    1.30  }
    1.31  
    1.32 @@ -433,6 +435,7 @@ XenVbd_PutSrbOnList(PXENVBD_DEVICE_DATA 
    1.33    InsertTailList(&xvdd->srb_list, (PLIST_ENTRY)srb_entry);
    1.34  }
    1.35  
    1.36 +/* called with StartIoLock held */
    1.37  static VOID
    1.38  XenVbd_PutQueuedSrbsOnRing(PXENVBD_DEVICE_DATA xvdd)
    1.39  {
    1.40 @@ -448,18 +451,17 @@ XenVbd_PutQueuedSrbsOnRing(PXENVBD_DEVIC
    1.41    int notify;
    1.42    int i;
    1.43    PVOID system_address;
    1.44 +  BOOLEAN failed;
    1.45  
    1.46    //if (dump_mode) FUNCTION_ENTER();
    1.47  
    1.48    while(!xvdd->aligned_buffer_in_use && xvdd->shadow_free && (srb_entry = (srb_list_entry_t *)RemoveHeadList(&xvdd->srb_list)) != (srb_list_entry_t *)&xvdd->srb_list)
    1.49    {
    1.50      srb = srb_entry->srb;
    1.51 -    ASSERT(srb);
    1.52 -    if (srb->Function != SRB_FUNCTION_EXECUTE_SCSI)
    1.53 -    {
    1.54 +    NT_ASSERT(srb);
    1.55 +    if (srb->Function != SRB_FUNCTION_EXECUTE_SCSI) {
    1.56        KdPrint((__DRIVER_NAME "     SRB_FUNCTION_%02x retrieved from ring\n", srb->Function));
    1.57 -      if (xvdd->shadow_free != SHADOW_ENTRIES)
    1.58 -      {
    1.59 +      if (xvdd->shadow_free != SHADOW_ENTRIES) {
    1.60          KdPrint((__DRIVER_NAME "     busy\n"));
    1.61          /* put it back at the end of the list just in case something is queued that needs to be processed */
    1.62          InsertTailList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
    1.63 @@ -474,19 +476,15 @@ XenVbd_PutQueuedSrbsOnRing(PXENVBD_DEVIC
    1.64        }
    1.65      }
    1.66  
    1.67 -    if (!dump_mode)
    1.68 -    {
    1.69 -      if (StorPortGetSystemAddress(xvdd, srb, &system_address) != STOR_STATUS_SUCCESS)
    1.70 -      {
    1.71 +    if (!dump_mode) {
    1.72 +      if (StorPortGetSystemAddress(xvdd, srb, &system_address) != STOR_STATUS_SUCCESS) {
    1.73          KdPrint((__DRIVER_NAME "     Failed to map DataBuffer\n"));
    1.74          srb->SrbStatus = SRB_STATUS_BUSY;
    1.75          StorPortNotification(RequestComplete, xvdd, srb);
    1.76          continue;
    1.77        }
    1.78        system_address = (PUCHAR)system_address + srb_entry->offset;
    1.79 -    }
    1.80 -    else
    1.81 -    {
    1.82 +    } else {
    1.83        //KdPrint((__DRIVER_NAME "     DataBuffer = %p\n", srb->DataBuffer));
    1.84        system_address = (PUCHAR)srb->DataBuffer + srb_entry->offset;
    1.85      }
    1.86 @@ -495,18 +493,17 @@ XenVbd_PutQueuedSrbsOnRing(PXENVBD_DEVIC
    1.87      block_count *= xvdd->bytes_per_sector / 512;
    1.88      sector_number *= xvdd->bytes_per_sector / 512;
    1.89  
    1.90 -    ASSERT(block_count * 512 == srb->DataTransferLength);
    1.91 -    
    1.92 +    NT_ASSERT(block_count * 512 == srb->DataTransferLength);
    1.93      
    1.94      sector_number += srb_entry->offset / 512;
    1.95      block_count -= srb_entry->offset / 512;
    1.96  
    1.97 +    NT_ASSERT(block_count > 0);
    1.98 +
    1.99      /* look for pending writes that overlap this one */
   1.100      /* we get warnings from drbd if we don't */
   1.101 -    if (srb_entry->offset == 0)
   1.102 -    {
   1.103 -      for (i = 0; i < MAX_SHADOW_ENTRIES; i++)
   1.104 -      {
   1.105 +    if (srb_entry->offset == 0) {
   1.106 +      for (i = 0; i < MAX_SHADOW_ENTRIES; i++) {
   1.107          PSCSI_REQUEST_BLOCK srb2;
   1.108          ULONGLONG sector_number2;
   1.109          ULONG block_count2;
   1.110 @@ -532,21 +529,19 @@ XenVbd_PutQueuedSrbsOnRing(PXENVBD_DEVIC
   1.111          InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
   1.112          break; /* stall the queue */
   1.113        }
   1.114 -      if (i != MAX_SHADOW_ENTRIES)
   1.115 -      {
   1.116 +      if (i != MAX_SHADOW_ENTRIES) {
   1.117          break; /* stall the queue but submit any outstanding requests */
   1.118        }
   1.119      }
   1.120      
   1.121      shadow = get_shadow_from_freelist(xvdd);
   1.122 -    if (!shadow)
   1.123 -    {
   1.124 +    if (!shadow) {
   1.125        /* put the srb back at the start of the queue */
   1.126        InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
   1.127        break; /* stall the queue but submit any outstanding requests */
   1.128      }
   1.129 -    ASSERT(!shadow->aligned_buffer_in_use);
   1.130 -    ASSERT(!shadow->srb);
   1.131 +    NT_ASSERT(!shadow->aligned_buffer_in_use);
   1.132 +    NT_ASSERT(!shadow->srb);
   1.133      shadow->req.sector_number = sector_number;
   1.134      shadow->req.handle = 0;
   1.135      shadow->req.operation = decode_cdb_is_read(srb)?BLKIF_OP_READ:BLKIF_OP_WRITE;
   1.136 @@ -556,10 +551,8 @@ XenVbd_PutQueuedSrbsOnRing(PXENVBD_DEVIC
   1.137      shadow->system_address = system_address;
   1.138      shadow->reset = FALSE;
   1.139  
   1.140 -    if (!dump_mode)
   1.141 -    {
   1.142 -      if ((ULONG_PTR)shadow->system_address & 511)
   1.143 -      {
   1.144 +    if (!dump_mode) {
   1.145 +      if ((ULONG_PTR)shadow->system_address & 511) {
   1.146          xvdd->aligned_buffer_in_use = TRUE;
   1.147          /* limit to aligned_buffer_size */
   1.148          block_count = min(block_count, xvdd->aligned_buffer_size / 512);
   1.149 @@ -567,16 +560,12 @@ XenVbd_PutQueuedSrbsOnRing(PXENVBD_DEVIC
   1.150          if (!decode_cdb_is_read(srb))
   1.151            memcpy(ptr, shadow->system_address, block_count * 512);
   1.152          shadow->aligned_buffer_in_use = TRUE;
   1.153 -      }
   1.154 -      else
   1.155 -      {
   1.156 +      } else {
   1.157          ptr = (PUCHAR)shadow->system_address;
   1.158          shadow->aligned_buffer_in_use = FALSE;
   1.159        }
   1.160 -    }
   1.161 -    else
   1.162 -    {
   1.163 -      ASSERT(!((ULONG_PTR)shadow->system_address & 511));
   1.164 +    } else {
   1.165 +      NT_ASSERT(!((ULONG_PTR)shadow->system_address & 511));
   1.166        ptr = shadow->system_address;
   1.167        shadow->aligned_buffer_in_use = FALSE;
   1.168      }
   1.169 @@ -591,80 +580,64 @@ XenVbd_PutQueuedSrbsOnRing(PXENVBD_DEVIC
   1.170      //KdPrint((__DRIVER_NAME "     operation = %d\n", shadow->req.operation));
   1.171      
   1.172      remaining = block_count * 512;
   1.173 -    while (remaining > 0 && shadow->req.nr_segments < BLKIF_MAX_SEGMENTS_PER_REQUEST)
   1.174 -    {
   1.175 +    failed = FALSE;
   1.176 +    while (remaining > 0 && shadow->req.nr_segments < BLKIF_MAX_SEGMENTS_PER_REQUEST) {
   1.177        PHYSICAL_ADDRESS physical_address;
   1.178  
   1.179 -      if (!dump_mode)
   1.180 -      {
   1.181 +      if (!dump_mode) {
   1.182          physical_address = MmGetPhysicalAddress(ptr);
   1.183 -      }
   1.184 -      else
   1.185 -      {
   1.186 +      } else {
   1.187          ULONG length;       
   1.188          physical_address = StorPortGetPhysicalAddress(xvdd, srb, ptr, &length);
   1.189        }
   1.190        gref = xvdd->vectors.GntTbl_GrantAccess(xvdd->vectors.context,
   1.191               (ULONG)(physical_address.QuadPart >> PAGE_SHIFT), FALSE, INVALID_GRANT_REF, xvdd->grant_tag);
   1.192 -      if (gref == INVALID_GRANT_REF)
   1.193 -      {
   1.194 +      if (gref == INVALID_GRANT_REF) {
   1.195          ULONG i;
   1.196 -        for (i = 0; i < shadow->req.nr_segments; i++)
   1.197 -        {
   1.198 +        for (i = 0; i < shadow->req.nr_segments; i++) {
   1.199            xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
   1.200              shadow->req.seg[i].gref, FALSE, xvdd->grant_tag);
   1.201          }
   1.202 -        if (shadow->aligned_buffer_in_use)
   1.203 -        {
   1.204 +        if (shadow->aligned_buffer_in_use) {
   1.205            shadow->aligned_buffer_in_use = FALSE;
   1.206            xvdd->aligned_buffer_in_use = FALSE;
   1.207          }
   1.208          /* put the srb back at the start of the queue */
   1.209 -        InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
   1.210 +        InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb_entry);
   1.211          put_shadow_on_freelist(xvdd, shadow);
   1.212          KdPrint((__DRIVER_NAME "     Out of gref's. Deferring\n"));
   1.213 +        failed = TRUE;
   1.214 +        /* what if there are no requests currently in progress to kick the queue again?? */
   1.215          break; /* stall the queue but submit any outstanding requests */
   1.216        }
   1.217        offset = physical_address.LowPart & (PAGE_SIZE - 1);
   1.218        length = min(PAGE_SIZE - offset, remaining);
   1.219 -      //if (dump_mode) KdPrint((__DRIVER_NAME "     length = %d\n", length));
   1.220 -      //if (dump_mode) KdPrint((__DRIVER_NAME "     offset = %d\n", length));
   1.221 -      ASSERT((offset & 511) == 0);
   1.222 -      ASSERT((length & 511) == 0);
   1.223 -      ASSERT(offset + length <= PAGE_SIZE);
   1.224 +      NT_ASSERT((offset & 511) == 0);
   1.225 +      NT_ASSERT((length & 511) == 0);
   1.226 +      NT_ASSERT(offset + length <= PAGE_SIZE);
   1.227        shadow->req.seg[shadow->req.nr_segments].gref = gref;
   1.228        shadow->req.seg[shadow->req.nr_segments].first_sect = (UCHAR)(offset / 512);
   1.229        shadow->req.seg[shadow->req.nr_segments].last_sect = (UCHAR)(((offset + length) / 512) - 1);
   1.230 -      //if (dump_mode) KdPrint((__DRIVER_NAME "     gref = %d\n", shadow->req.seg[shadow->req.nr_segments].gref));
   1.231 -      //if (dump_mode) KdPrint((__DRIVER_NAME "     first_sect = %d\n", shadow->req.seg[shadow->req.nr_segments].first_sect));
   1.232 -      //if (dump_mode) KdPrint((__DRIVER_NAME "     last_sect = %d\n", shadow->req.seg[shadow->req.nr_segments].last_sect));
   1.233        remaining -= length;
   1.234        ptr += length;
   1.235        shadow->length += length;
   1.236        shadow->req.nr_segments++;
   1.237      }
   1.238 +    if (failed)
   1.239 +      break;
   1.240      srb_entry->offset += shadow->length;
   1.241      srb_entry->outstanding_requests++;
   1.242 -    //KdPrint((__DRIVER_NAME "     outstanding_requests   = %p\n", srb_entry->outstanding_requests));
   1.243 -    //KdPrint((__DRIVER_NAME "     offset   = %d, length = %d\n", srb_entry->offset, srb_entry->length));
   1.244 -    //KdPrint((__DRIVER_NAME "     ptr   = %p\n", ptr));
   1.245 -    if (srb_entry->offset < srb_entry->length)
   1.246 -    {
   1.247 +    if (srb_entry->offset < srb_entry->length) {
   1.248        if (dump_mode) KdPrint((__DRIVER_NAME "     inserting back into list\n"));
   1.249        /* put the srb back at the start of the queue to continue on the next request */
   1.250        InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb_entry);
   1.251      }
   1.252 -
   1.253      XenVbd_PutRequest(xvdd, &shadow->req);
   1.254    }
   1.255    RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xvdd->ring, notify);
   1.256 -  if (notify)
   1.257 -  {
   1.258 -    //KdPrint((__DRIVER_NAME "     Notifying\n"));
   1.259 +  if (notify) {
   1.260      xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
   1.261    }
   1.262 -    
   1.263 -  //if (dump_mode) FUNCTION_EXIT();
   1.264  }
   1.265  
   1.266  static ULONG
   1.267 @@ -1161,9 +1134,9 @@ XenVbd_HandleEventSynchronised(PVOID Dev
   1.268          else
   1.269          {
   1.270            srb = shadow->srb;
   1.271 -          ASSERT(srb);
   1.272 +          NT_ASSERT(srb);
   1.273            srb_entry = srb->SrbExtension;
   1.274 -          ASSERT(srb_entry);
   1.275 +          NT_ASSERT(srb_entry);
   1.276            /* a few errors occur in dump mode because Xen refuses to allow us to map pages we are using for other stuff. Just ignore them */
   1.277            if (rep->status == BLKIF_RSP_OKAY || (dump_mode &&  dump_mode_errors++ < DUMP_MODE_ERROR_LIMIT))
   1.278              srb->SrbStatus = SRB_STATUS_SUCCESS;
   1.279 @@ -1178,7 +1151,7 @@ XenVbd_HandleEventSynchronised(PVOID Dev
   1.280            }
   1.281            if (shadow->aligned_buffer_in_use)
   1.282            {
   1.283 -            ASSERT(xvdd->aligned_buffer_in_use);
   1.284 +            NT_ASSERT(xvdd->aligned_buffer_in_use);
   1.285              xvdd->aligned_buffer_in_use = FALSE;
   1.286              if (srb->SrbStatus == SRB_STATUS_SUCCESS && decode_cdb_is_read(srb))
   1.287                memcpy((PUCHAR)shadow->system_address, xvdd->aligned_buffer, shadow->length);
   1.288 @@ -1202,9 +1175,6 @@ XenVbd_HandleEventSynchronised(PVOID Dev
   1.289              StorPortNotification(RequestComplete, xvdd, srb);
   1.290            }
   1.291          }
   1.292 -        shadow->aligned_buffer_in_use = FALSE;
   1.293 -        shadow->srb = NULL;
   1.294 -        shadow->reset = FALSE;
   1.295          put_shadow_on_freelist(xvdd, shadow);
   1.296          break;
   1.297        }
   1.298 @@ -1222,7 +1192,6 @@ XenVbd_HandleEventSynchronised(PVOID Dev
   1.299      }
   1.300    }
   1.301  
   1.302 -  //if (start_ring_detect_state == RING_DETECT_STATE_COMPLETE)
   1.303    XenVbd_PutQueuedSrbsOnRing(xvdd);
   1.304  
   1.305    if (suspend_resume_state_pdo == SR_STATE_SUSPENDING)
   1.306 @@ -1955,8 +1924,8 @@ XenVbd_HwStorAdapterControl(PVOID Device
   1.307        KdPrint((__DRIVER_NAME "     inactive - nothing to do\n"));
   1.308        break;
   1.309      }
   1.310 -    ASSERT(IsListEmpty(&xvdd->srb_list));
   1.311 -    ASSERT(xvdd->shadow_free == SHADOW_ENTRIES);
   1.312 +    NT_ASSERT(IsListEmpty(&xvdd->srb_list));
   1.313 +    NT_ASSERT(xvdd->shadow_free == SHADOW_ENTRIES);
   1.314      break;
   1.315    case ScsiRestartAdapter:
   1.316      KdPrint((__DRIVER_NAME "     ScsiRestartAdapter\n"));