win-pvdrivers

changeset 790:467005e7f509

Big messy changes. Add grant ref tagging to better track when things go wrong (debug build only).
Fix a race in xennet that causes crashes under heavy traffic conditions on driver shutdown.
author James Harper <james.harper@bendigoit.com.au>
date Fri Mar 12 09:38:42 2010 +1100 (2010-03-12)
parents 65a687a0933e
children 150118f124a1
files common/include/xen_windows.h xennet/xennet_rx.c xennet/xennet_tx.c xenpci/gnttbl.c xenpci/xenbus.c xenpci/xenpci.h xenpci/xenpci_fdo.c xenpci/xenpci_pdo.c xenvbd/xenvbd.c xenvbd/xenvbd.h
line diff
     1.1 --- a/common/include/xen_windows.h	Fri Mar 12 09:35:56 2010 +1100
     1.2 +++ b/common/include/xen_windows.h	Fri Mar 12 09:38:42 2010 +1100
     1.3 @@ -331,16 +331,16 @@ typedef BOOLEAN
     1.4  (*PXEN_EVTCHN_SYNC)(PVOID Context, PXEN_EVTCHN_SYNC_ROUTINE sync_routine, PVOID sync_context);
     1.5  
     1.6  typedef grant_ref_t
     1.7 -(*PXEN_GNTTBL_GRANTACCESS)(PVOID Context, domid_t domid, uint32_t frame, int readonly, grant_ref_t ref);
     1.8 +(*PXEN_GNTTBL_GRANTACCESS)(PVOID Context, domid_t domid, uint32_t frame, int readonly, grant_ref_t ref, ULONG tag);
     1.9  
    1.10  typedef BOOLEAN
    1.11 -(*PXEN_GNTTBL_ENDACCESS)(PVOID Context, grant_ref_t ref, BOOLEAN keepref);
    1.12 +(*PXEN_GNTTBL_ENDACCESS)(PVOID Context, grant_ref_t ref, BOOLEAN keepref, ULONG tag);
    1.13  
    1.14  typedef VOID
    1.15 -(*PXEN_GNTTBL_PUTREF)(PVOID Context, grant_ref_t ref);
    1.16 +(*PXEN_GNTTBL_PUTREF)(PVOID Context, grant_ref_t ref, ULONG tag);
    1.17  
    1.18  typedef grant_ref_t
    1.19 -(*PXEN_GNTTBL_GETREF)(PVOID Context);
    1.20 +(*PXEN_GNTTBL_GETREF)(PVOID Context, ULONG tag);
    1.21  
    1.22  
    1.23  typedef VOID
    1.24 @@ -386,7 +386,7 @@ XenPci_FreeMem(PVOID Ptr)
    1.25    ExFreePoolWithTag(Ptr, XENPCI_POOL_TAG);
    1.26  }
    1.27  
    1.28 -#define XEN_DATA_MAGIC 0x12345678
    1.29 +#define XEN_DATA_MAGIC 0x12345679
    1.30  
    1.31  typedef struct {
    1.32    ULONG magic;
     2.1 --- a/xennet/xennet_rx.c	Fri Mar 12 09:35:56 2010 +1100
     2.2 +++ b/xennet/xennet_rx.c	Fri Mar 12 09:38:42 2010 +1100
     2.3 @@ -615,7 +615,8 @@ XenNet_RxBufferCheck(PKDPC dpc, PVOID co
     2.4  
     2.5    //FUNCTION_ENTER();
     2.6  
     2.7 -  ASSERT(xi->connected);
     2.8 +  if (!xi->connected)
     2.9 +    return; /* a delayed DPC could let this come through... just do nothing */
    2.10  
    2.11    KeAcquireSpinLockAtDpcLevel(&xi->rx_lock);
    2.12    
    2.13 @@ -855,7 +856,7 @@ XenNet_BufferFree(struct xennet_info *xi
    2.14    {
    2.15      NdisFreeBuffer(pb->buffer);
    2.16      xi->vectors.GntTbl_EndAccess(xi->vectors.context,
    2.17 -        pb->gref, FALSE);
    2.18 +        pb->gref, FALSE, (ULONG)'XNRX');
    2.19      NdisFreeMemory(pb->virtual, PAGE_SIZE, 0);
    2.20    }
    2.21  }
    2.22 @@ -897,7 +898,7 @@ XenNet_BufferAlloc(xennet_info_t *xi)
    2.23        break;
    2.24      }
    2.25      xi->rx_pbs[i].gref = (grant_ref_t)xi->vectors.GntTbl_GrantAccess(xi->vectors.context, 0,
    2.26 -              (ULONG)(MmGetPhysicalAddress(xi->rx_pbs[i].virtual).QuadPart >> PAGE_SHIFT), FALSE, INVALID_GRANT_REF);
    2.27 +              (ULONG)(MmGetPhysicalAddress(xi->rx_pbs[i].virtual).QuadPart >> PAGE_SHIFT), FALSE, INVALID_GRANT_REF, (ULONG)'XNRX');
    2.28      if (xi->rx_pbs[i].gref == INVALID_GRANT_REF)
    2.29      {
    2.30        NdisFreeMemory(xi->rx_pbs[i].virtual, PAGE_SIZE, 0);
    2.31 @@ -908,7 +909,7 @@ XenNet_BufferAlloc(xennet_info_t *xi)
    2.32      if (status != STATUS_SUCCESS)
    2.33      {
    2.34        xi->vectors.GntTbl_EndAccess(xi->vectors.context,
    2.35 -          xi->rx_pbs[i].gref, FALSE);
    2.36 +          xi->rx_pbs[i].gref, FALSE, (ULONG)'XNRX');
    2.37        NdisFreeMemory(xi->rx_pbs[i].virtual, PAGE_SIZE, 0);
    2.38        break;
    2.39      }
     3.1 --- a/xennet/xennet_tx.c	Fri Mar 12 09:35:56 2010 +1100
     3.2 +++ b/xennet/xennet_tx.c	Fri Mar 12 09:38:42 2010 +1100
     3.3 @@ -52,7 +52,7 @@ XenNet_PutCbOnRing(struct xennet_info *x
     3.4    ASSERT(xi->tx_shadows[tx->id].gref == INVALID_GRANT_REF);
     3.5    ASSERT(!xi->tx_shadows[tx->id].cb);
     3.6    xi->tx_shadows[tx->id].cb = coalesce_buf;
     3.7 -  tx->gref = xi->vectors.GntTbl_GrantAccess(xi->vectors.context, 0, (ULONG)(MmGetPhysicalAddress(coalesce_buf).QuadPart >> PAGE_SHIFT), FALSE, gref);
     3.8 +  tx->gref = xi->vectors.GntTbl_GrantAccess(xi->vectors.context, 0, (ULONG)(MmGetPhysicalAddress(coalesce_buf).QuadPart >> PAGE_SHIFT), FALSE, gref, (ULONG)'XNTX');
     3.9    xi->tx_shadows[tx->id].gref = tx->gref;
    3.10    tx->offset = 0;
    3.11    tx->size = (USHORT)length;
    3.12 @@ -88,7 +88,7 @@ XenNet_HWSendPacket(struct xennet_info *
    3.13    
    3.14    //FUNCTION_ENTER();
    3.15  
    3.16 -  gref = xi->vectors.GntTbl_GetRef(xi->vectors.context);
    3.17 +  gref = xi->vectors.GntTbl_GetRef(xi->vectors.context, (ULONG)'XNTX');
    3.18    if (gref == INVALID_GRANT_REF)
    3.19    {
    3.20      KdPrint((__DRIVER_NAME "     out of grefs\n"));
    3.21 @@ -97,7 +97,7 @@ XenNet_HWSendPacket(struct xennet_info *
    3.22    coalesce_buf = NdisAllocateFromNPagedLookasideList(&xi->tx_lookaside_list);
    3.23    if (!coalesce_buf)
    3.24    {
    3.25 -    xi->vectors.GntTbl_PutRef(xi->vectors.context, gref);
    3.26 +    xi->vectors.GntTbl_PutRef(xi->vectors.context, gref, (ULONG)'XNTX');
    3.27      KdPrint((__DRIVER_NAME "     out of memory\n"));
    3.28      return FALSE;
    3.29    }
    3.30 @@ -139,7 +139,7 @@ XenNet_HWSendPacket(struct xennet_info *
    3.31    /* if we have enough space on the ring then we have enough id's so no need to check for that */
    3.32    if (xi->tx_ring_free < frags + 1)
    3.33    {
    3.34 -    xi->vectors.GntTbl_PutRef(xi->vectors.context, gref);
    3.35 +    xi->vectors.GntTbl_PutRef(xi->vectors.context, gref, (ULONG)'XNTX');
    3.36      NdisFreeToNPagedLookasideList(&xi->tx_lookaside_list, coalesce_buf);
    3.37      //KdPrint((__DRIVER_NAME "     Full on send - ring full\n"));
    3.38      return FALSE;
    3.39 @@ -276,7 +276,7 @@ XenNet_HWSendPacket(struct xennet_info *
    3.40        PVOID va;
    3.41        if (!coalesce_buf)
    3.42        {
    3.43 -        gref = xi->vectors.GntTbl_GetRef(xi->vectors.context);
    3.44 +        gref = xi->vectors.GntTbl_GetRef(xi->vectors.context, (ULONG)'XNTX');
    3.45          if (gref == INVALID_GRANT_REF)
    3.46          {
    3.47            KdPrint((__DRIVER_NAME "     out of grefs - partial send\n"));
    3.48 @@ -285,7 +285,7 @@ XenNet_HWSendPacket(struct xennet_info *
    3.49          coalesce_buf = NdisAllocateFromNPagedLookasideList(&xi->tx_lookaside_list);
    3.50          if (!coalesce_buf)
    3.51          {
    3.52 -          xi->vectors.GntTbl_PutRef(xi->vectors.context, gref);
    3.53 +          xi->vectors.GntTbl_PutRef(xi->vectors.context, gref, (ULONG)'XNTX');
    3.54            KdPrint((__DRIVER_NAME "     out of memory - partial send\n"));
    3.55            break;
    3.56          }
    3.57 @@ -331,7 +331,7 @@ XenNet_HWSendPacket(struct xennet_info *
    3.58      {
    3.59        ULONG offset;
    3.60        
    3.61 -      gref = xi->vectors.GntTbl_GetRef(xi->vectors.context);
    3.62 +      gref = xi->vectors.GntTbl_GetRef(xi->vectors.context, (ULONG)'XNTX');
    3.63        if (gref == INVALID_GRANT_REF)
    3.64        {
    3.65          KdPrint((__DRIVER_NAME "     out of grefs - partial send\n"));
    3.66 @@ -345,7 +345,7 @@ XenNet_HWSendPacket(struct xennet_info *
    3.67        offset = MmGetMdlByteOffset(pi.curr_buffer) + pi.curr_mdl_offset;
    3.68        pfn = MmGetMdlPfnArray(pi.curr_buffer)[offset >> PAGE_SHIFT];
    3.69        txN->offset = (USHORT)offset & (PAGE_SIZE - 1);
    3.70 -      txN->gref = xi->vectors.GntTbl_GrantAccess(xi->vectors.context, 0, (ULONG)pfn, FALSE, gref);
    3.71 +      txN->gref = xi->vectors.GntTbl_GrantAccess(xi->vectors.context, 0, (ULONG)pfn, FALSE, gref, (ULONG)'XNTX');
    3.72        ASSERT(xi->tx_shadows[txN->id].gref == INVALID_GRANT_REF);
    3.73        xi->tx_shadows[txN->id].gref = txN->gref;
    3.74        //ASSERT(sg->Elements[sg_element].Length > sg_offset);
    3.75 @@ -432,7 +432,8 @@ XenNet_TxBufferGC(PKDPC dpc, PVOID conte
    3.76  
    3.77    //FUNCTION_ENTER();
    3.78  
    3.79 -  ASSERT(xi->connected);
    3.80 +  if (!xi->connected)
    3.81 +    return; /* a delayed DPC could let this come through... just do nothing */
    3.82    ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
    3.83  
    3.84    KeAcquireSpinLockAtDpcLevel(&xi->tx_lock);
    3.85 @@ -473,7 +474,7 @@ XenNet_TxBufferGC(PKDPC dpc, PVOID conte
    3.86        if (shadow->gref != INVALID_GRANT_REF)
    3.87        {
    3.88          xi->vectors.GntTbl_EndAccess(xi->vectors.context,
    3.89 -          shadow->gref, FALSE);
    3.90 +          shadow->gref, FALSE, (ULONG)'XNTX');
    3.91          shadow->gref = INVALID_GRANT_REF;
    3.92        }
    3.93        
     4.1 --- a/xenpci/gnttbl.c	Fri Mar 12 09:35:56 2010 +1100
     4.2 +++ b/xenpci/gnttbl.c	Fri Mar 12 09:38:42 2010 +1100
     4.3 @@ -20,26 +20,42 @@ Foundation, Inc., 51 Franklin Street, Fi
     4.4  #include "xenpci.h"
     4.5  
     4.6  VOID
     4.7 -GntTbl_PutRef(PVOID Context, grant_ref_t ref)
     4.8 +GntTbl_PutRef(PVOID Context, grant_ref_t ref, ULONG tag)
     4.9  {
    4.10    PXENPCI_DEVICE_DATA xpdd = Context;
    4.11  
    4.12 +  UNREFERENCED_PARAMETER(tag);
    4.13 +  
    4.14 +#if DBG
    4.15 +  if (xpdd->gnttab_tag[ref] != tag)
    4.16 +    KdPrint((__DRIVER_NAME "     Grant Entry %d for %.4s doesn't match %.4s\n", ref, (PUCHAR)&tag, (PUCHAR)&xpdd->gnttab_tag[ref]));
    4.17 +  ASSERT(xpdd->gnttab_tag[ref] == tag);
    4.18 +  xpdd->gnttab_tag[ref] = 0;
    4.19 +#endif
    4.20    stack_push(xpdd->gnttab_ss, (PVOID)ref);
    4.21  }
    4.22  
    4.23  grant_ref_t
    4.24 -GntTbl_GetRef(PVOID Context)
    4.25 +GntTbl_GetRef(PVOID Context, ULONG tag)
    4.26  {
    4.27    PXENPCI_DEVICE_DATA xpdd = Context;
    4.28    unsigned int ref;
    4.29    PVOID ptr_ref;
    4.30  
    4.31 +  UNREFERENCED_PARAMETER(tag);
    4.32 +
    4.33    if (!stack_pop(xpdd->gnttab_ss, &ptr_ref))
    4.34    {
    4.35      KdPrint((__DRIVER_NAME "     No free grant refs\n"));
    4.36      return INVALID_GRANT_REF;
    4.37    }
    4.38    ref = (grant_ref_t)(ULONG_PTR)ptr_ref;
    4.39 +#if DBG
    4.40 +  if (xpdd->gnttab_tag[ref])
    4.41 +    KdPrint((__DRIVER_NAME "     Grant Entry %d for %.4s in use by %.4s\n", ref, (PUCHAR)&tag, (PUCHAR)&xpdd->gnttab_tag[ref]));
    4.42 +  ASSERT(!xpdd->gnttab_tag[ref]);
    4.43 +  xpdd->gnttab_tag[ref] = tag;
    4.44 +#endif
    4.45  
    4.46    return ref;
    4.47  }
    4.48 @@ -72,32 +88,37 @@ GntTbl_GrantAccess(
    4.49    domid_t domid,
    4.50    uint32_t frame, // xen api limits pfn to 32bit, so no guests over 8TB
    4.51    int readonly,
    4.52 -  grant_ref_t ref)
    4.53 +  grant_ref_t ref,
    4.54 +  ULONG tag)
    4.55  {
    4.56    PXENPCI_DEVICE_DATA xpdd = Context;
    4.57  
    4.58    //KdPrint((__DRIVER_NAME " --> GntTbl_GrantAccess\n"));
    4.59  
    4.60 -  //KdPrint((__DRIVER_NAME "     Granting access to frame %08x\n", frame));
    4.61 -
    4.62    if (ref == INVALID_GRANT_REF)
    4.63 -    ref = GntTbl_GetRef(Context);
    4.64 +    ref = GntTbl_GetRef(Context, tag);
    4.65    if (ref == INVALID_GRANT_REF)
    4.66      return ref;
    4.67 +
    4.68 +  ASSERT(xpdd->gnttab_tag[ref] == tag);
    4.69    
    4.70    xpdd->gnttab_table[ref].frame = frame;
    4.71    xpdd->gnttab_table[ref].domid = domid;
    4.72  
    4.73    if (xpdd->gnttab_table[ref].flags)
    4.74 -    KdPrint((__DRIVER_NAME "     WARNING: Attempting to re-use grant entry that is already in use!\n"));
    4.75 +  {
    4.76 +#if DBG
    4.77 +    KdPrint((__DRIVER_NAME "     Grant Entry %d for %.4s still in use by %.4s\n", ref, (PUCHAR)&tag, (PUCHAR)&xpdd->gnttab_tag[ref]));
    4.78 +#else
    4.79 +    KdPrint((__DRIVER_NAME "     Grant Entry %d for %.4s still in use\n", ref, (PUCHAR)&tag));
    4.80 +#endif
    4.81 +  }
    4.82    ASSERT(!xpdd->gnttab_table[ref].flags);
    4.83  
    4.84    KeMemoryBarrier();
    4.85    readonly *= GTF_readonly;
    4.86    xpdd->gnttab_table[ref].flags = GTF_permit_access | (uint16_t)readonly;
    4.87  
    4.88 -  //KdPrint((__DRIVER_NAME " <-- GntTbl_GrantAccess (ref = %d)\n", ref));
    4.89 -
    4.90    return ref;
    4.91  }
    4.92  
    4.93 @@ -105,27 +126,27 @@ BOOLEAN
    4.94  GntTbl_EndAccess(
    4.95    PVOID Context,
    4.96    grant_ref_t ref,
    4.97 -  BOOLEAN keepref)
    4.98 +  BOOLEAN keepref,
    4.99 +  ULONG tag)
   4.100  {
   4.101    PXENPCI_DEVICE_DATA xpdd = Context;
   4.102    unsigned short flags, nflags;
   4.103  
   4.104 -  //KdPrint((__DRIVER_NAME " --> GntTbl_EndAccess\n"));
   4.105 -
   4.106    ASSERT(ref != INVALID_GRANT_REF);
   4.107 +  ASSERT(xpdd->gnttab_tag[ref] == tag);
   4.108    
   4.109    nflags = xpdd->gnttab_table[ref].flags;
   4.110    do {
   4.111      if ((flags = nflags) & (GTF_reading|GTF_writing))
   4.112      {
   4.113 -      KdPrint((__DRIVER_NAME "     WARNING: g.e. %d still in use!\n", ref));
   4.114 +      KdPrint((__DRIVER_NAME "     Grant Entry %d for %.4s still use\n", ref, (PUCHAR)&tag));
   4.115        return FALSE;
   4.116      }
   4.117    } while ((nflags = InterlockedCompareExchange16(
   4.118      (volatile SHORT *)&xpdd->gnttab_table[ref].flags, 0, flags)) != flags);
   4.119  
   4.120    if (!keepref)
   4.121 -    GntTbl_PutRef(Context, ref);
   4.122 +    GntTbl_PutRef(Context, ref, tag);
   4.123    //KdPrint((__DRIVER_NAME " <-- GntTbl_EndAccess\n"));
   4.124    return TRUE;
   4.125  }
   4.126 @@ -152,6 +173,8 @@ GntTbl_Init(PXENPCI_DEVICE_DATA xpdd)
   4.127  {
   4.128    int i;
   4.129    int grant_entries;
   4.130 +
   4.131 +  ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
   4.132    
   4.133    FUNCTION_ENTER();
   4.134    
   4.135 @@ -159,8 +182,10 @@ GntTbl_Init(PXENPCI_DEVICE_DATA xpdd)
   4.136    KdPrint((__DRIVER_NAME "     grant_frames = %d\n", xpdd->grant_frames));
   4.137    grant_entries = min(NR_GRANT_ENTRIES, (xpdd->grant_frames * PAGE_SIZE / sizeof(grant_entry_t)));
   4.138    KdPrint((__DRIVER_NAME "     grant_entries = %d\n", grant_entries));
   4.139 -  
   4.140 -  ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
   4.141 +  #if DBG
   4.142 +  xpdd->gnttab_tag = ExAllocatePoolWithTag(NonPagedPool, grant_entries * sizeof(ULONG), XENPCI_POOL_TAG);
   4.143 +  RtlZeroMemory(xpdd->gnttab_tag, grant_entries * sizeof(ULONG));
   4.144 +  #endif
   4.145    xpdd->gnttab_table_copy = ExAllocatePoolWithTag(NonPagedPool, xpdd->grant_frames * PAGE_SIZE, XENPCI_POOL_TAG);
   4.146    ASSERT(xpdd->gnttab_table_copy); // lazy
   4.147    xpdd->gnttab_table_physical = XenPci_AllocMMIO(xpdd, PAGE_SIZE * xpdd->grant_frames);
     5.1 --- a/xenpci/xenbus.c	Fri Mar 12 09:35:56 2010 +1100
     5.2 +++ b/xenpci/xenbus.c	Fri Mar 12 09:38:42 2010 +1100
     5.3 @@ -235,6 +235,8 @@ XenBus_WatchWorkItemProc(WDFWORKITEM wor
     5.4    PCHAR path;
     5.5    int index;
     5.6    PXENBUS_WATCH_ENTRY entry;
     5.7 +  PXENBUS_WATCH_CALLBACK service_routine;
     5.8 +  PVOID service_context;  
     5.9  
    5.10    //FUNCTION_ENTER();
    5.11    msg = WdfObjectGetTypedContext(workitem, xsd_sockmsg_t);
    5.12 @@ -244,6 +246,7 @@ XenBus_WatchWorkItemProc(WDFWORKITEM wor
    5.13    {
    5.14      KdPrint((__DRIVER_NAME "     Watch index %d out of range\n", index));
    5.15      WdfObjectDelete(workitem);
    5.16 +    //FUNCTION_ENTER();
    5.17      return;
    5.18    }
    5.19    ExAcquireFastMutex(&xpdd->xb_watch_mutex);
    5.20 @@ -253,13 +256,16 @@ XenBus_WatchWorkItemProc(WDFWORKITEM wor
    5.21      KdPrint((__DRIVER_NAME "     No watch for index %d\n", index));
    5.22      ExReleaseFastMutex(&xpdd->xb_watch_mutex);
    5.23      WdfObjectDelete(workitem);
    5.24 +    //FUNCTION_ENTER();
    5.25      return;
    5.26    }
    5.27    entry->Count++;
    5.28 -  entry->ServiceRoutine(path, entry->ServiceContext);
    5.29 +  service_routine = entry->ServiceRoutine;
    5.30 +  service_context = entry->ServiceContext;
    5.31 +  service_routine(path, service_context);
    5.32    ExReleaseFastMutex(&xpdd->xb_watch_mutex);
    5.33    WdfObjectDelete(workitem);
    5.34 -  //FUNCTION_ENTER();
    5.35 +  //FUNCTION_EXIT();
    5.36  }    
    5.37  
    5.38  /* Called at DISPATCH_LEVEL */
    5.39 @@ -284,7 +290,7 @@ XenBus_Dpc(PVOID ServiceContext)
    5.40      {
    5.41        if (xpdd->xen_store_interface->rsp_prod - xpdd->xen_store_interface->rsp_cons < sizeof(xsd_sockmsg_t))
    5.42        {
    5.43 -        KdPrint((__DRIVER_NAME " +++ Message incomplete (not even a full header)\n"));
    5.44 +        //KdPrint((__DRIVER_NAME " +++ Message incomplete (not even a full header)\n"));
    5.45          break;
    5.46        }
    5.47        KeMemoryBarrier();
    5.48 @@ -308,7 +314,7 @@ XenBus_Dpc(PVOID ServiceContext)
    5.49  
    5.50      if (xpdd->xb_msg_offset < sizeof(xsd_sockmsg_t) + xpdd->xb_msg->len)
    5.51      {
    5.52 -      KdPrint((__DRIVER_NAME " +++ Message incomplete (header but not full body)\n"));
    5.53 +      //KdPrint((__DRIVER_NAME " +++ Message incomplete (header but not full body)\n"));
    5.54        EvtChn_Notify(xpdd, xpdd->xen_store_evtchn); /* there is room on the ring now */
    5.55        break;
    5.56      }
     6.1 --- a/xenpci/xenpci.h	Fri Mar 12 09:35:56 2010 +1100
     6.2 +++ b/xenpci/xenpci.h	Fri Mar 12 09:38:42 2010 +1100
     6.3 @@ -154,6 +154,9 @@ typedef struct {
     6.4    struct stack_state *gnttab_ss;
     6.5    grant_entry_t *gnttab_table;
     6.6    grant_entry_t *gnttab_table_copy;
     6.7 +  #if DBG
     6.8 +  PULONG gnttab_tag;
     6.9 +  #endif
    6.10    PHYSICAL_ADDRESS gnttab_table_physical;
    6.11    //grant_ref_t *gnttab_list;
    6.12    //int gnttab_list_free;
    6.13 @@ -186,7 +189,7 @@ typedef struct {
    6.14    ULONG xb_msg_offset;
    6.15    
    6.16    WDFCHILDLIST child_list;
    6.17 -
    6.18 +  
    6.19    KSPIN_LOCK suspend_lock;  
    6.20    evtchn_port_t suspend_evtchn;
    6.21    int suspend_state;
    6.22 @@ -469,12 +472,12 @@ GntTbl_Suspend(PXENPCI_DEVICE_DATA xpdd)
    6.23  VOID
    6.24  GntTbl_Resume(PXENPCI_DEVICE_DATA xpdd);
    6.25  grant_ref_t
    6.26 -GntTbl_GrantAccess(PVOID Context, domid_t domid, uint32_t, int readonly, grant_ref_t ref);
    6.27 +GntTbl_GrantAccess(PVOID Context, domid_t domid, uint32_t, int readonly, grant_ref_t ref, ULONG tag);
    6.28  BOOLEAN
    6.29 -GntTbl_EndAccess(PVOID Context, grant_ref_t ref, BOOLEAN keepref);
    6.30 +GntTbl_EndAccess(PVOID Context, grant_ref_t ref, BOOLEAN keepref, ULONG tag);
    6.31  VOID
    6.32 -GntTbl_PutRef(PVOID Context, grant_ref_t ref);
    6.33 +GntTbl_PutRef(PVOID Context, grant_ref_t ref, ULONG tag);
    6.34  grant_ref_t
    6.35 -GntTbl_GetRef(PVOID Context);
    6.36 +GntTbl_GetRef(PVOID Context, ULONG tag);
    6.37  
    6.38  #endif
     7.1 --- a/xenpci/xenpci_fdo.c	Fri Mar 12 09:35:56 2010 +1100
     7.2 +++ b/xenpci/xenpci_fdo.c	Fri Mar 12 09:38:42 2010 +1100
     7.3 @@ -29,7 +29,6 @@ Foundation, Inc., 51 Franklin Street, Fi
     7.4  static EVT_WDF_WORKITEM XenPci_SuspendResume;
     7.5  static KSTART_ROUTINE XenPci_BalloonThreadProc;
     7.6  
     7.7 -
     7.8  static VOID
     7.9  XenPci_MapHalThenPatchKernel(PXENPCI_DEVICE_DATA xpdd)
    7.10  {
    7.11 @@ -908,6 +907,7 @@ XenPci_EvtDeviceReleaseHardware(WDFDEVIC
    7.12  }
    7.13  
    7.14  /* Called at PASSIVE_LEVEL but with pagefile unavailable */
    7.15 +/* Can be called concurrently, but KMDF takes care of concurrent calls to WdfChildListXxx */
    7.16  VOID
    7.17  XenPci_EvtChildListScanForChildren(WDFCHILDLIST child_list)
    7.18  {
     8.1 --- a/xenpci/xenpci_pdo.c	Fri Mar 12 09:35:56 2010 +1100
     8.2 +++ b/xenpci/xenpci_pdo.c	Fri Mar 12 09:38:42 2010 +1100
     8.3 @@ -340,43 +340,43 @@ XenPci_EvtChn_Sync(PVOID context, PXEN_E
     8.4  }
     8.5  
     8.6  static grant_ref_t
     8.7 -XenPci_GntTbl_GrantAccess(PVOID context, domid_t domid, uint32_t frame, int readonly, grant_ref_t ref)
     8.8 -{
     8.9 -  WDFDEVICE device = context;
    8.10 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
    8.11 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
    8.12 -  
    8.13 -  return GntTbl_GrantAccess(xpdd, domid, frame, readonly, ref);
    8.14 -}
    8.15 -
    8.16 -static BOOLEAN
    8.17 -XenPci_GntTbl_EndAccess(PVOID context, grant_ref_t ref, BOOLEAN keepref)
    8.18 +XenPci_GntTbl_GrantAccess(PVOID context, domid_t domid, uint32_t frame, int readonly, grant_ref_t ref, ULONG tag)
    8.19  {
    8.20    WDFDEVICE device = context;
    8.21    PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
    8.22    PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
    8.23    
    8.24 -  return GntTbl_EndAccess(xpdd, ref, keepref);
    8.25 +  return GntTbl_GrantAccess(xpdd, domid, frame, readonly, ref, tag);
    8.26  }
    8.27  
    8.28 -static VOID
    8.29 -XenPci_GntTbl_PutRef(PVOID context, grant_ref_t ref)
    8.30 +static BOOLEAN
    8.31 +XenPci_GntTbl_EndAccess(PVOID context, grant_ref_t ref, BOOLEAN keepref, ULONG tag)
    8.32  {
    8.33    WDFDEVICE device = context;
    8.34    PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
    8.35    PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
    8.36    
    8.37 -  GntTbl_PutRef(xpdd, ref);
    8.38 +  return GntTbl_EndAccess(xpdd, ref, keepref, tag);
    8.39  }
    8.40  
    8.41 -static grant_ref_t
    8.42 -XenPci_GntTbl_GetRef(PVOID context)
    8.43 +static VOID
    8.44 +XenPci_GntTbl_PutRef(PVOID context, grant_ref_t ref, ULONG tag)
    8.45  {
    8.46    WDFDEVICE device = context;
    8.47    PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
    8.48    PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
    8.49    
    8.50 -  return GntTbl_GetRef(xpdd);
    8.51 +  GntTbl_PutRef(xpdd, ref, tag);
    8.52 +}
    8.53 +
    8.54 +static grant_ref_t
    8.55 +XenPci_GntTbl_GetRef(PVOID context, ULONG tag)
    8.56 +{
    8.57 +  WDFDEVICE device = context;
    8.58 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
    8.59 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
    8.60 +  
    8.61 +  return GntTbl_GetRef(xpdd, tag);
    8.62  }
    8.63  
    8.64  PCHAR
    8.65 @@ -564,7 +564,7 @@ XenPci_XenShutdownDevice(PVOID context)
    8.66          break;
    8.67        case XEN_INIT_TYPE_GRANT_ENTRIES:
    8.68          for (i = 0; i < PtrToUlong(setting); i++)
    8.69 -          GntTbl_EndAccess(xpdd, ((grant_ref_t *)value)[i], FALSE);
    8.70 +          GntTbl_EndAccess(xpdd, ((grant_ref_t *)value)[i], FALSE, (ULONG)'XPDO');
    8.71          break;
    8.72        }
    8.73      }
    8.74 @@ -679,7 +679,7 @@ XenPci_XenConfigDeviceSpecifyBuffers(WDF
    8.75          //KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_RING - %s = %p\n", setting, address));
    8.76          SHARED_RING_INIT((struct dummy_sring *)address);
    8.77          if ((gref = GntTbl_GrantAccess(
    8.78 -          xpdd, 0, (ULONG)*MmGetMdlPfnArray(ring), FALSE, INVALID_GRANT_REF)) != INVALID_GRANT_REF)
    8.79 +          xpdd, 0, (ULONG)*MmGetMdlPfnArray(ring), FALSE, INVALID_GRANT_REF, (ULONG)'XPDO')) != INVALID_GRANT_REF)
    8.80          {
    8.81            RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
    8.82            XenBus_Printf(xpdd, XBT_NIL, path, "%d", gref);
    8.83 @@ -787,7 +787,7 @@ XenPci_XenConfigDeviceSpecifyBuffers(WDF
    8.84        __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, PtrToUlong(value));
    8.85        for (i = 0; i < PtrToUlong(value); i++)
    8.86        {
    8.87 -        gref = GntTbl_GetRef(xpdd);
    8.88 +        gref = GntTbl_GetRef(xpdd, 'XPDO');
    8.89          __ADD_XEN_INIT_ULONG(&out_ptr, gref);
    8.90          __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, gref);
    8.91        }
     9.1 --- a/xenvbd/xenvbd.c	Fri Mar 12 09:35:56 2010 +1100
     9.2 +++ b/xenvbd/xenvbd.c	Fri Mar 12 09:38:42 2010 +1100
     9.3 @@ -63,7 +63,7 @@ get_shadow_from_freelist(PXENVBD_DEVICE_
     9.4  {
     9.5    if (xvdd->shadow_free == 0)
     9.6    {
     9.7 -    KdPrint((__DRIVER_NAME "     No more shadow entries\n"));    
     9.8 +    KdPrint((__DRIVER_NAME "     No more shadow entries\n"));
     9.9      return NULL;
    9.10    }
    9.11    xvdd->shadow_free--;
    9.12 @@ -228,7 +228,7 @@ XenVbd_InitFromConfig(PXENVBD_DEVICE_DAT
    9.13        break;
    9.14      case XEN_INIT_TYPE_GRANT_ENTRIES:
    9.15        KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_GRANT_ENTRIES - entries = %d\n", PtrToUlong(setting)));
    9.16 -      //memcpy(xvdd->dump_grant_refs, value, PtrToUlong(setting) * sizeof(grant_ref_t));
    9.17 +      memcpy(xvdd->dump_grant_refs, value, PtrToUlong(setting) * sizeof(grant_ref_t));
    9.18        break;
    9.19      case XEN_INIT_TYPE_QEMU_HIDE_FLAGS:
    9.20        qemu_hide_flags_value = PtrToUlong(value);
    9.21 @@ -362,7 +362,6 @@ XenVbd_PutQueuedSrbsOnRing(PXENVBD_DEVIC
    9.22    grant_ref_t gref;
    9.23    PUCHAR ptr;
    9.24    int notify;
    9.25 -  
    9.26  
    9.27    //FUNCTION_ENTER();
    9.28  
    9.29 @@ -419,15 +418,24 @@ XenVbd_PutQueuedSrbsOnRing(PXENVBD_DEVIC
    9.30      {
    9.31        PHYSICAL_ADDRESS physical_address = MmGetPhysicalAddress(ptr);
    9.32        
    9.33 -      gref = xvdd->vectors.GntTbl_GrantAccess(xvdd->vectors.context, 0,
    9.34 -                (ULONG)(physical_address.QuadPart >> PAGE_SHIFT), FALSE, INVALID_GRANT_REF);
    9.35 +      if (dump_mode)
    9.36 +      {
    9.37 +        gref = xvdd->vectors.GntTbl_GrantAccess(xvdd->vectors.context, 0,
    9.38 +                 (ULONG)(physical_address.QuadPart >> PAGE_SHIFT), FALSE,
    9.39 +                 xvdd->dump_grant_refs[shadow->req.nr_segments], (ULONG)'XPDO');
    9.40 +      }
    9.41 +      else
    9.42 +      {
    9.43 +        gref = xvdd->vectors.GntTbl_GrantAccess(xvdd->vectors.context, 0,
    9.44 +                 (ULONG)(physical_address.QuadPart >> PAGE_SHIFT), FALSE, INVALID_GRANT_REF, (ULONG)'XVBD');
    9.45 +      }
    9.46        if (gref == INVALID_GRANT_REF)
    9.47        {
    9.48          ULONG i;
    9.49          for (i = 0; i < shadow->req.nr_segments; i++)
    9.50          {
    9.51            xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
    9.52 -            shadow->req.seg[i].gref, FALSE);
    9.53 +            shadow->req.seg[i].gref, FALSE, (ULONG)'XVBD');
    9.54          }
    9.55          if (shadow->aligned_buffer_in_use)
    9.56          {
    9.57 @@ -911,14 +919,17 @@ XenVbd_HwScsiInterrupt(PVOID DeviceExten
    9.58          KdPrint((__DRIVER_NAME "     premature IRQ\n"));
    9.59          break;
    9.60        case RING_DETECT_STATE_DETECT1:
    9.61 -        KdPrint((__DRIVER_NAME "     ring_detect_state = %d, operation = %x, id = %lx, status = %d\n", xvdd->ring_detect_state, rep->operation, rep->id, rep->status));
    9.62 +        KdPrint((__DRIVER_NAME "     ring_detect_state = %d, index = %d, operation = %x, id = %lx, status = %d\n", xvdd->ring_detect_state, i, rep->operation, rep->id, rep->status));
    9.63 +        KdPrint((__DRIVER_NAME "     req_prod = %d, rsp_prod = %d, rsp_cons = %d\n", xvdd->sring->req_prod, xvdd->sring->rsp_prod, xvdd->ring.rsp_cons));
    9.64          xvdd->ring_detect_state = RING_DETECT_STATE_DETECT2;
    9.65          break;
    9.66        case RING_DETECT_STATE_DETECT2:
    9.67 -        KdPrint((__DRIVER_NAME "     ring_detect_state = %d, operation = %x, id = %lx, status = %d\n", xvdd->ring_detect_state, rep->operation, rep->id, rep->status));
    9.68 +        KdPrint((__DRIVER_NAME "     ring_detect_state = %d, index = %d, operation = %x, id = %lx, status = %d\n", xvdd->ring_detect_state, i, rep->operation, rep->id, rep->status));
    9.69 +        KdPrint((__DRIVER_NAME "     req_prod = %d, rsp_prod = %d, rsp_cons = %d\n", xvdd->sring->req_prod, xvdd->sring->rsp_prod, xvdd->ring.rsp_cons));
    9.70          *xvdd->event_channel_ptr |= 0x80000000;
    9.71          if (rep->operation != 0xff)
    9.72          {
    9.73 +          KdPrint((__DRIVER_NAME "     switching to 'other' ring size\n"));
    9.74            xvdd->ring.nr_ents = BLK_OTHER_RING_SIZE;
    9.75            xvdd->use_other = TRUE;
    9.76            *xvdd->event_channel_ptr |= 0x40000000;
    9.77 @@ -979,8 +990,16 @@ KdPrint((__DRIVER_NAME "     Completed r
    9.78  #endif
    9.79          for (j = 0; j < shadow->req.nr_segments; j++)
    9.80          {
    9.81 -          xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
    9.82 -            shadow->req.seg[j].gref, FALSE);
    9.83 +          if (dump_mode)
    9.84 +          {
    9.85 +            xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
    9.86 +              shadow->req.seg[j].gref, TRUE, (ULONG)'XPDO');
    9.87 +          }
    9.88 +          else
    9.89 +          {
    9.90 +            xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
    9.91 +              shadow->req.seg[j].gref, FALSE, (ULONG)'XVBD');
    9.92 +          }
    9.93          }
    9.94          shadow->aligned_buffer_in_use = FALSE;
    9.95          shadow->srb = NULL;
    9.96 @@ -1031,12 +1050,6 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
    9.97    PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
    9.98    ULONG data_transfer_length = srb->DataTransferLength;
    9.99  
   9.100 -
   9.101 -if (xvdd->aligned_buffer_in_use)
   9.102 -{
   9.103 -  KdPrint((__DRIVER_NAME "     New request while aligned buffer in use - Function = %x, next_request = %d\n", srb->Function, xvdd->next_request));
   9.104 -}
   9.105 -
   9.106    if (xvdd->inactive)
   9.107    {
   9.108      KdPrint((__DRIVER_NAME "     Inactive srb->Function = %08X\n", srb->Function));
   9.109 @@ -1078,11 +1091,6 @@ if (xvdd->aligned_buffer_in_use)
   9.110    case SRB_FUNCTION_EXECUTE_SCSI:
   9.111      cdb = (PCDB)srb->Cdb;
   9.112  
   9.113 -if (xvdd->aligned_buffer_in_use)
   9.114 -{
   9.115 -  KdPrint((__DRIVER_NAME "     New request while aligned buffer in use - OP = %x, next_request = %d\n", cdb->CDB6GENERIC.OperationCode, xvdd->next_request));
   9.116 -}
   9.117 -
   9.118      switch(cdb->CDB6GENERIC.OperationCode)
   9.119      {
   9.120      case SCSIOP_TEST_UNIT_READY:
   9.121 @@ -1506,7 +1514,6 @@ XenVbd_HwScsiAdapterControl(PVOID Device
   9.122      break;
   9.123    case ScsiStopAdapter:
   9.124      KdPrint((__DRIVER_NAME "     ScsiStopAdapter\n"));
   9.125 -    //KdBreakPoint();
   9.126      /* I don't think we actually have to do anything here... xenpci cleans up all the xenbus stuff for us */
   9.127      break;
   9.128    case ScsiRestartAdapter:
   9.129 @@ -1571,7 +1578,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
   9.130      ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "mode", NULL, NULL);
   9.131      ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "sectors", NULL, NULL);
   9.132      ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "sector-size", NULL, NULL);
   9.133 -    //ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_GRANT_ENTRIES, NULL, ULongToPtr(BLKIF_MAX_SEGMENTS_PER_REQUEST), NULL); /* for use in crash dump */
   9.134 +    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_GRANT_ENTRIES, NULL, ULongToPtr(BLKIF_MAX_SEGMENTS_PER_REQUEST), NULL); /* for use in crash dump */
   9.135      ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_END, NULL, NULL, NULL);
   9.136  
   9.137      InitializeObjectAttributes(&oa, RegistryPath, OBJ_CASE_INSENSITIVE, NULL, NULL);
    10.1 --- a/xenvbd/xenvbd.h	Fri Mar 12 09:35:56 2010 +1100
    10.2 +++ b/xenvbd/xenvbd.h	Fri Mar 12 09:38:42 2010 +1100
    10.3 @@ -137,8 +137,7 @@ struct
    10.4    XENPCI_VECTORS vectors;
    10.5    PXENPCI_DEVICE_STATE device_state;
    10.6    LIST_ENTRY srb_list;
    10.7 -  ULONG next_request; // debug - true if nextrequest has been sent
    10.8 -  //grant_ref_t dump_grant_refs[BLKIF_MAX_SEGMENTS_PER_REQUEST - 1];
    10.9 +  grant_ref_t dump_grant_refs[BLKIF_MAX_SEGMENTS_PER_REQUEST];
   10.10    BOOLEAN aligned_buffer_in_use;
   10.11    PVOID aligned_buffer;
   10.12    UCHAR aligned_buffer_data[(BLKIF_MAX_SEGMENTS_PER_REQUEST + 1) * PAGE_SIZE - 1];