win-pvdrivers

changeset 141:28ac4e5c2231

Fixed crash by correcting GntTbl code and shutdown ordering. Now going to remove the copious debugging stuff I put in earlier.
author James Harper <james.harper@bendigoit.com.au>
date Tue Jan 22 16:15:57 2008 +1100 (2008-01-22)
parents 76a661426861
children 8d3f39a47293
files xennet/sources xennet/xennet.c xenpci/gnttbl.c xenpci/sources
line diff
     1.1 --- a/xennet/sources	Mon Jan 21 23:45:15 2008 +1100
     1.2 +++ b/xennet/sources	Tue Jan 22 16:15:57 2008 +1100
     1.3 @@ -1,7 +1,7 @@
     1.4  TARGETNAME=XENNET
     1.5  TARGETTYPE=DRIVER
     1.6  TARGETPATH=..\Target\$(DDK_TARGET_OS)
     1.7 -VERSION=0.5.0.175
     1.8 +VERSION=0.5.0.190
     1.9  KMDF_VERSION=1
    1.10  MSC_WARNING_LEVEL=/W4
    1.11  INF_NAME=xennet
     2.1 --- a/xennet/xennet.c	Mon Jan 21 23:45:15 2008 +1100
     2.2 +++ b/xennet/xennet.c	Tue Jan 22 16:15:57 2008 +1100
     2.3 @@ -338,19 +338,17 @@ XenNet_RxBufferAlloc(struct xennet_info 
     2.4    KeAcquireSpinLock(&xi->rx_lock, &OldIrql);
     2.5  
     2.6    batch_target = xi->rx_target - (req_prod - xi->rx.rsp_cons);
     2.7 +
     2.8    for (i = 0; i < batch_target; i++)
     2.9    {
    2.10      entry = RemoveHeadList(&xi->rx_free_buf_list);
    2.11 -KdPrint((__DRIVER_NAME "     A - %08x\n", entry));
    2.12      if (entry == &xi->rx_free_buf_list)
    2.13        break;
    2.14      buffer = CONTAINING_RECORD(entry, buffer_entry_t, entry)->buffer;
    2.15 -KdPrint((__DRIVER_NAME "     B - %08x\n", buffer));
    2.16      
    2.17      /* Give to netback */
    2.18      id = (unsigned short)(req_prod + i) & (NET_RX_RING_SIZE - 1);
    2.19      ASSERT(!xi->rx_buffers[id]);
    2.20 -KdPrint(("Putting id = %d on ring\n", id));
    2.21      xi->rx_buffers[id] = buffer;
    2.22      req = RING_GET_REQUEST(&xi->rx, req_prod + i);
    2.23      /* an NDIS_BUFFER is just a MDL, so we can get its pfn array */
    2.24 @@ -390,6 +388,7 @@ XenNet_RxBufferFree(struct xennet_info *
    2.25    KIRQL OldIrql;
    2.26    PVOID buff_va;
    2.27    PLIST_ENTRY entry;
    2.28 +  int ungranted;
    2.29  
    2.30    ASSERT(!xi->connected);
    2.31  
    2.32 @@ -406,14 +405,17 @@ XenNet_RxBufferFree(struct xennet_info *
    2.33      ref = xi->grant_rx_ref[i];
    2.34  
    2.35      /* don't check return, what can we do about it on failure? */
    2.36 -    xi->XenInterface.GntTbl_EndAccess(xi->XenInterface.InterfaceHeader.Context, ref);
    2.37 +    ungranted = xi->XenInterface.GntTbl_EndAccess(xi->XenInterface.InterfaceHeader.Context, ref);
    2.38  
    2.39      NdisAdjustBufferLength(buffer, sizeof(buffer_entry_t));
    2.40      buff_va = NdisBufferVirtualAddressSafe(buffer, NormalPagePriority);
    2.41      NdisFreeBuffer(buffer);
    2.42      BufferAlloc--;
    2.43 -    NdisFreeMemory(buff_va, 0, 0); // <= DISPATCH_LEVEL
    2.44 -    NdisAlloc--;
    2.45 +    if (ungranted)
    2.46 +    {
    2.47 +      NdisFreeMemory(buff_va, 0, 0); // <= DISPATCH_LEVEL
    2.48 +      NdisAlloc--;
    2.49 +    }
    2.50    }
    2.51  
    2.52    KdPrint((__DRIVER_NAME "     B\n"));
    2.53 @@ -443,6 +445,8 @@ XenNet_RxBufferFree(struct xennet_info *
    2.54    KeReleaseSpinLock(&xi->rx_lock, OldIrql);
    2.55  }
    2.56  
    2.57 +int in_dpc = 0;
    2.58 +
    2.59  VOID
    2.60  XenNet_ReturnPacket(
    2.61    IN NDIS_HANDLE MiniportAdapterContext,
    2.62 @@ -458,7 +462,7 @@ XenNet_ReturnPacket(
    2.63    buffer_entry_t *buffer_entry;
    2.64  //  KIRQL OldIrql;
    2.65  
    2.66 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    2.67 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ " (in_dpc = %d)\n", in_dpc));
    2.68  
    2.69    NdisQueryPacketLength(Packet, &tot_buff_len);
    2.70  //  NdisGetFirstBufferFromPacketSafe(Packet, &buffer, &buff_va, &buff_len,
    2.71 @@ -510,6 +514,7 @@ XenNet_RxBufferCheck(struct xennet_info 
    2.72  
    2.73    ASSERT(xi->connected);
    2.74  
    2.75 +  in_dpc = 1;
    2.76    KeAcquireSpinLock(&xi->rx_lock, &OldIrql);
    2.77  
    2.78    do {
    2.79 @@ -520,6 +525,8 @@ XenNet_RxBufferCheck(struct xennet_info 
    2.80        rxrsp = RING_GET_RESPONSE(&xi->rx, cons);
    2.81        ASSERT(rxrsp->status > 0);
    2.82  
    2.83 +      KdPrint((__DRIVER_NAME " rx id = %d\n", rxrsp->id));
    2.84 +
    2.85        if (!more_frags) // handling the packet's 1st buffer
    2.86        {
    2.87          entry = RemoveHeadList(&xi->rx_free_pkt_list);
    2.88 @@ -568,6 +575,7 @@ XenNet_RxBufferCheck(struct xennet_info 
    2.89      RING_FINAL_CHECK_FOR_RESPONSES(&xi->rx, moretodo);
    2.90    } while (moretodo);
    2.91  
    2.92 +  in_dpc = 0;
    2.93    KeReleaseSpinLock(&xi->rx_lock, OldIrql);
    2.94  
    2.95    if (more_frags)
    2.96 @@ -1726,9 +1734,6 @@ XenNet_Halt(
    2.97  //  KdPrint((__DRIVER_NAME "     tx_outstanding = %d\n", xi->tx_outstanding));
    2.98  //  KdPrint((__DRIVER_NAME "     rx_outstanding = %d\n", xi->rx_outstanding));
    2.99  
   2.100 -  // this disables the interrupt
   2.101 -  XenNet_Shutdown(xi);
   2.102 -
   2.103    // set frontend state to 'closing'
   2.104    xi->state = XenbusStateClosing;
   2.105    RtlStringCbPrintfA(TmpPath, ARRAY_SIZE(TmpPath), "%s/state", xi->pdo_data->Path);
   2.106 @@ -1750,6 +1755,19 @@ XenNet_Halt(
   2.107      KeWaitForSingleObject(&xi->backend_state_change_event, Executive,
   2.108        KernelMode, FALSE, NULL);
   2.109  
   2.110 +  // set frontend state to 'Initialising'
   2.111 +  xi->state = XenbusStateInitialising;
   2.112 +  RtlStringCbPrintfA(TmpPath, ARRAY_SIZE(TmpPath), "%s/state", xi->pdo_data->Path);
   2.113 +  xi->XenInterface.XenBus_Printf(if_cxt, XBT_NIL, TmpPath, "%d", xi->state);
   2.114 +
   2.115 +  // wait for backend to set 'InitWait' state
   2.116 +  while (xi->backend_state != XenbusStateInitWait)
   2.117 +    KeWaitForSingleObject(&xi->backend_state_change_event, Executive,
   2.118 +      KernelMode, FALSE, NULL);
   2.119 +
   2.120 +  // this disables the interrupt
   2.121 +  XenNet_Shutdown(xi);
   2.122 +
   2.123    xi->connected = FALSE;
   2.124    KeMemoryBarrier(); /* make sure everyone sees that we are now shut down */
   2.125  
     3.1 --- a/xenpci/gnttbl.c	Mon Jan 21 23:45:15 2008 +1100
     3.2 +++ b/xenpci/gnttbl.c	Tue Jan 22 16:15:57 2008 +1100
     3.3 @@ -143,7 +143,9 @@ GntTbl_EndAccess(
     3.4        return FALSE;
     3.5      }
     3.6    } while ((nflags = InterlockedCompareExchange16(
     3.7 -    (volatile SHORT *)&xpdd->gnttab_table[ref].flags, flags, 0)) != flags);
     3.8 +    (volatile SHORT *)&xpdd->gnttab_table[ref].flags, 0, flags)) != flags);
     3.9 +//  } while ((nflags = InterlockedCompareExchange16(
    3.10 +//    (volatile SHORT *)&xpdd->gnttab_table[ref].flags, flags, 0)) != flags);
    3.11  
    3.12    put_free_entry(Device, ref);
    3.13    //KdPrint((__DRIVER_NAME " <-- GntTbl_EndAccess\n"));
     4.1 --- a/xenpci/sources	Mon Jan 21 23:45:15 2008 +1100
     4.2 +++ b/xenpci/sources	Tue Jan 22 16:15:57 2008 +1100
     4.3 @@ -1,7 +1,7 @@
     4.4  TARGETNAME=XENPCI
     4.5  TARGETTYPE=DRIVER
     4.6  TARGETPATH=..\Target\$(DDK_TARGET_OS)
     4.7 -VERSION=0.5.0.41
     4.8 +VERSION=0.5.0.42
     4.9  KMDF_VERSION=1
    4.10  MSC_WARNING_LEVEL=/W4
    4.11  INF_NAME=xenpci