win-pvdrivers

changeset 858:fc54b0c09c08

Added better tracking of grant tables for tracking leaks across suspend/resume
author James Harper <james.harper@bendigoit.com.au>
date Sun Feb 27 11:14:02 2011 +1100 (2011-02-27)
parents f6ba3ce0bd81
children 658d20a31016
files xenpci/gnttbl.c xenpci/xenpci.h
line diff
     1.1 --- a/xenpci/gnttbl.c	Tue Feb 22 23:21:15 2011 +1100
     1.2 +++ b/xenpci/gnttbl.c	Sun Feb 27 11:14:02 2011 +1100
     1.3 @@ -27,10 +27,11 @@ GntTbl_PutRef(PVOID Context, grant_ref_t
     1.4    UNREFERENCED_PARAMETER(tag);
     1.5    
     1.6  #if DBG
     1.7 -  if (xpdd->gnttbl_tag[ref] != tag)
     1.8 -    KdPrint((__DRIVER_NAME "     Grant Entry %d for %.4s doesn't match %.4s\n", ref, (PUCHAR)&tag, (PUCHAR)&xpdd->gnttbl_tag[ref]));
     1.9 -  ASSERT(xpdd->gnttbl_tag[ref] == tag);
    1.10 -  xpdd->gnttbl_tag[ref] = 0;
    1.11 +  if (xpdd->gnttbl_tag[ref].tag != tag)
    1.12 +    KdPrint((__DRIVER_NAME "     Grant Entry %d for %.4s doesn't match %.4s\n", ref, (PUCHAR)&tag, (PUCHAR)&xpdd->gnttbl_tag[ref].tag));
    1.13 +  ASSERT(xpdd->gnttbl_tag[ref].tag == tag);
    1.14 +  xpdd->gnttbl_tag[ref].tag = 0;
    1.15 +  xpdd->gnttbl_tag[ref].generation = (ULONG)-1;
    1.16  #endif
    1.17    stack_push(xpdd->gnttbl_ss, (PVOID)ref);
    1.18  }
    1.19 @@ -51,10 +52,11 @@ GntTbl_GetRef(PVOID Context, ULONG tag)
    1.20    }
    1.21    ref = (grant_ref_t)(ULONG_PTR)ptr_ref;
    1.22  #if DBG
    1.23 -  if (xpdd->gnttbl_tag[ref])
    1.24 -    KdPrint((__DRIVER_NAME "     Grant Entry %d for %.4s in use by %.4s\n", ref, (PUCHAR)&tag, (PUCHAR)&xpdd->gnttbl_tag[ref]));
    1.25 -  ASSERT(!xpdd->gnttbl_tag[ref]);
    1.26 -  xpdd->gnttbl_tag[ref] = tag;
    1.27 +  if (xpdd->gnttbl_tag[ref].tag)
    1.28 +    KdPrint((__DRIVER_NAME "     Grant Entry %d for %.4s in use by %.4s\n", ref, (PUCHAR)&tag, (PUCHAR)&xpdd->gnttbl_tag[ref].tag));
    1.29 +  ASSERT(!xpdd->gnttbl_tag[ref].tag);
    1.30 +  xpdd->gnttbl_tag[ref].generation = xpdd->gnttbl_generation;
    1.31 +  xpdd->gnttbl_tag[ref].tag = tag;
    1.32  #endif
    1.33  
    1.34    return ref;
    1.35 @@ -102,7 +104,7 @@ GntTbl_GrantAccess(
    1.36    if (ref == INVALID_GRANT_REF)
    1.37      return ref;
    1.38  
    1.39 -  ASSERT(xpdd->gnttbl_tag[ref] == tag);
    1.40 +  ASSERT(xpdd->gnttbl_tag[ref].tag == tag);
    1.41    
    1.42    xpdd->gnttbl_table[ref].frame = frame;
    1.43    xpdd->gnttbl_table[ref].domid = domid;
    1.44 @@ -110,7 +112,7 @@ GntTbl_GrantAccess(
    1.45    if (xpdd->gnttbl_table[ref].flags)
    1.46    {
    1.47  #if DBG
    1.48 -    KdPrint((__DRIVER_NAME "     Grant Entry %d for %.4s still in use by %.4s\n", ref, (PUCHAR)&tag, (PUCHAR)&xpdd->gnttbl_tag[ref]));
    1.49 +    KdPrint((__DRIVER_NAME "     Grant Entry %d for %.4s still in use by %.4s\n", ref, (PUCHAR)&tag, (PUCHAR)&xpdd->gnttbl_tag[ref].tag));
    1.50  #else
    1.51      KdPrint((__DRIVER_NAME "     Grant Entry %d for %.4s still in use\n", ref, (PUCHAR)&tag));
    1.52  #endif
    1.53 @@ -135,7 +137,7 @@ GntTbl_EndAccess(
    1.54    unsigned short flags, nflags;
    1.55  
    1.56    ASSERT(ref != INVALID_GRANT_REF);
    1.57 -  ASSERT(xpdd->gnttbl_tag[ref] == tag);
    1.58 +  ASSERT(xpdd->gnttbl_tag[ref].tag == tag);
    1.59    
    1.60    nflags = xpdd->gnttbl_table[ref].flags;
    1.61    do {
    1.62 @@ -185,9 +187,10 @@ GntTbl_Init(PXENPCI_DEVICE_DATA xpdd)
    1.63    grant_entries = min(NR_GRANT_ENTRIES, (xpdd->grant_frames * PAGE_SIZE / sizeof(grant_entry_t)));
    1.64    KdPrint((__DRIVER_NAME "     grant_entries = %d\n", grant_entries));
    1.65    #if DBG
    1.66 -  xpdd->gnttbl_tag = ExAllocatePoolWithTag(NonPagedPool, grant_entries * sizeof(ULONG), XENPCI_POOL_TAG);
    1.67 -  RtlZeroMemory(xpdd->gnttbl_tag, grant_entries * sizeof(ULONG));
    1.68 -  xpdd->gnttbl_tag_copy = ExAllocatePoolWithTag(NonPagedPool, grant_entries * sizeof(ULONG), XENPCI_POOL_TAG);
    1.69 +  xpdd->gnttbl_tag = ExAllocatePoolWithTag(NonPagedPool, grant_entries * sizeof(grant_tag_t), XENPCI_POOL_TAG);
    1.70 +  RtlZeroMemory(xpdd->gnttbl_tag, grant_entries * sizeof(grant_tag_t));
    1.71 +  xpdd->gnttbl_tag_copy = ExAllocatePoolWithTag(NonPagedPool, grant_entries * sizeof(grant_tag_t), XENPCI_POOL_TAG);
    1.72 +  xpdd->gnttbl_generation = 0;
    1.73    #endif
    1.74    xpdd->gnttbl_table_copy = ExAllocatePoolWithTag(NonPagedPool, xpdd->grant_frames * PAGE_SIZE, XENPCI_POOL_TAG);
    1.75    ASSERT(xpdd->gnttbl_table_copy); // lazy
    1.76 @@ -241,6 +244,17 @@ GntTbl_Suspend(PXENPCI_DEVICE_DATA xpdd)
    1.77    
    1.78    FUNCTION_ENTER();
    1.79    
    1.80 +  #if DBG
    1.81 +  for (i = 0; i < (int)min(NR_GRANT_ENTRIES, (xpdd->grant_frames * PAGE_SIZE / sizeof(grant_entry_t))); i++)
    1.82 +  {
    1.83 +    if (xpdd->gnttbl_tag[i].tag != 0) // && xpdd->gnttbl_tag[i].generation < xpdd->gnttbl_generation)
    1.84 +    {
    1.85 +      KdPrint((__DRIVER_NAME "     grant entry for %.4s from generation %d\n", (PUCHAR)&xpdd->gnttbl_tag[i].tag, xpdd->gnttbl_tag[i].generation));
    1.86 +    }
    1.87 +  }
    1.88 +  xpdd->gnttbl_generation++;
    1.89 +  #endif
    1.90 +
    1.91    /* copy some grant refs and switch to an alternate freelist, but only on hiber */
    1.92    if (KeGetCurrentIrql() <= DISPATCH_LEVEL)
    1.93    {
    1.94 @@ -267,7 +281,7 @@ GntTbl_Suspend(PXENPCI_DEVICE_DATA xpdd)
    1.95    #if DBG
    1.96    /* even though gnttbl_tag is actually preserved, it is used by the dump driver so must be restored to exactly the same state as it was on suspend */
    1.97    grant_entries = min(NR_GRANT_ENTRIES, (xpdd->grant_frames * PAGE_SIZE / sizeof(grant_entry_t)));
    1.98 -  memcpy(xpdd->gnttbl_tag_copy, xpdd->gnttbl_tag, grant_entries * sizeof(ULONG));
    1.99 +  memcpy(xpdd->gnttbl_tag_copy, xpdd->gnttbl_tag, grant_entries * sizeof(grant_tag_t));
   1.100    #endif
   1.101  
   1.102    /* put the grant entries on the new freelist, after copying the tables above */
   1.103 @@ -324,7 +338,7 @@ GntTbl_Resume(PXENPCI_DEVICE_DATA xpdd)
   1.104    memcpy(xpdd->gnttbl_table, xpdd->gnttbl_table_copy, xpdd->grant_frames * PAGE_SIZE);
   1.105    #if DBG
   1.106    grant_entries = min(NR_GRANT_ENTRIES, (xpdd->grant_frames * PAGE_SIZE / sizeof(grant_entry_t)));
   1.107 -  memcpy(xpdd->gnttbl_tag, xpdd->gnttbl_tag_copy, grant_entries * sizeof(ULONG));
   1.108 +  memcpy(xpdd->gnttbl_tag, xpdd->gnttbl_tag_copy, grant_entries * sizeof(grant_tag_t));
   1.109    #endif
   1.110  
   1.111    /* switch back and put the hiber grants back again */
     2.1 --- a/xenpci/xenpci.h	Tue Feb 22 23:21:15 2011 +1100
     2.2 +++ b/xenpci/xenpci.h	Sun Feb 27 11:14:02 2011 +1100
     2.3 @@ -125,6 +125,11 @@ typedef struct _XENBUS_WATCH_ENTRY {
     2.4  /* we take some grant refs out and put them aside so that we dont get corrupted by hibernate */
     2.5  #define HIBER_GREF_COUNT 128
     2.6  
     2.7 +typedef struct {
     2.8 +  ULONG generation;
     2.9 +  ULONG tag;
    2.10 +} grant_tag_t;
    2.11 +
    2.12  typedef struct {  
    2.13    WDFDEVICE wdf_device;
    2.14    
    2.15 @@ -166,8 +171,9 @@ typedef struct {
    2.16    grant_entry_t *gnttbl_table;
    2.17    grant_entry_t *gnttbl_table_copy;
    2.18    #if DBG
    2.19 -  PULONG gnttbl_tag;
    2.20 -  PULONG gnttbl_tag_copy;
    2.21 +  ULONG gnttbl_generation; /* incremented once per save or hibernate */
    2.22 +  grant_tag_t *gnttbl_tag;
    2.23 +  grant_tag_t *gnttbl_tag_copy;
    2.24    #endif
    2.25    ULONG grant_frames;
    2.26