win-pvdrivers

changeset 207:2b9e77dc2071

Fixed some locking issues in rx. No more lockups with iperf and large windows.
author James Harper <james.harper@bendigoit.com.au>
date Wed Mar 05 23:41:32 2008 +1100 (2008-03-05)
parents d841932ba7ae
children e2939422de10
files common.inc xennet/xennet.c xennet/xennet.h xennet/xennet_rx.c xennet/xennet_tx.c
line diff
     1.1 --- a/common.inc	Wed Mar 05 20:44:14 2008 +1100
     1.2 +++ b/common.inc	Wed Mar 05 23:41:32 2008 +1100
     1.3 @@ -1,4 +1,4 @@
     1.4 -VERSION=0.8.4.75
     1.5 +VERSION=0.8.4.80
     1.6  TARGETPATH=..\Target\$(DDK_TARGET_OS)
     1.7  KMDF_VERSION=1
     1.8  !IF $(_NT_TOOLS_VERSION) > 0x700
     2.1 --- a/xennet/xennet.c	Wed Mar 05 20:44:14 2008 +1100
     2.2 +++ b/xennet/xennet.c	Wed Mar 05 23:41:32 2008 +1100
     2.3 @@ -43,6 +43,7 @@ int ProfCount_TxPacketsTotal;
     2.4  int ProfCount_TxPacketsOffload;
     2.5  int ProfCount_RxPacketsTotal;
     2.6  int ProfCount_RxPacketsOffload;
     2.7 +int ProfCount_CallsToIndicateReceive;
     2.8  
     2.9  /* This function copied from linux's lib/vsprintf.c, see it for attribution */
    2.10  static unsigned long
    2.11 @@ -595,6 +596,7 @@ DriverEntry(
    2.12    ProfCount_TxPacketsOffload = 0;
    2.13    ProfCount_RxPacketsTotal = 0;
    2.14    ProfCount_RxPacketsOffload = 0;
    2.15 +  ProfCount_CallsToIndicateReceive = 0;
    2.16  
    2.17    RtlZeroMemory(&mini_chars, sizeof(mini_chars));
    2.18  
     3.1 --- a/xennet/xennet.h	Wed Mar 05 20:44:14 2008 +1100
     3.2 +++ b/xennet/xennet.h	Wed Mar 05 23:41:32 2008 +1100
     3.3 @@ -72,7 +72,7 @@ Foundation, Inc., 51 Franklin Street, Fi
     3.4  
     3.5  #pragma warning(disable: 4127) // conditional expression is constant
     3.6  
     3.7 -//#define XEN_PROFILE
     3.8 +#define XEN_PROFILE
     3.9  
    3.10  /* TODO: crank this up if we support higher mtus? */
    3.11  #define XN_DATA_SIZE 1500
    3.12 @@ -189,6 +189,7 @@ extern int ProfCount_TxPacketsTotal;
    3.13  extern int ProfCount_TxPacketsOffload;
    3.14  extern int ProfCount_RxPacketsTotal;
    3.15  extern int ProfCount_RxPacketsOffload;
    3.16 +extern int ProfCount_CallsToIndicateReceive;
    3.17  
    3.18  NDIS_STATUS
    3.19  XenNet_RxBufferCheck(struct xennet_info *xi);
     4.1 --- a/xennet/xennet_rx.c	Wed Mar 05 20:44:14 2008 +1100
     4.2 +++ b/xennet/xennet_rx.c	Wed Mar 05 23:41:32 2008 +1100
     4.3 @@ -173,6 +173,7 @@ XenNet_RxBufferCheck(struct xennet_info 
     4.4    NDIS_STATUS status;
     4.5    USHORT id;
     4.6    PNDIS_TCP_IP_CHECKSUM_PACKET_INFO csum_info;
     4.7 +  int cycles = 0;
     4.8  #if defined(XEN_PROFILE)
     4.9    LARGE_INTEGER tsc, dummy;
    4.10  #endif
    4.11 @@ -189,6 +190,7 @@ XenNet_RxBufferCheck(struct xennet_info 
    4.12  
    4.13    packet_count = 0;
    4.14    do {
    4.15 +    ASSERT(cycles++ < 256);
    4.16      prod = xi->rx.sring->rsp_prod;
    4.17      KeMemoryBarrier(); /* Ensure we see responses up to 'rp'. */
    4.18  
    4.19 @@ -239,12 +241,6 @@ XenNet_RxBufferCheck(struct xennet_info 
    4.20          xi->stat_rx_ok++;
    4.21          NDIS_SET_PACKET_STATUS(packets[packet_count], NDIS_STATUS_SUCCESS);
    4.22          packet_count++;
    4.23 -        if (packet_count == NET_RX_RING_SIZE)
    4.24 -        {
    4.25 -          /* A miniport driver must release any spin lock that it is holding before calling NdisMIndicateReceivePacket */
    4.26 -          NdisMIndicateReceivePacket(xi->adapter_handle, packets, packet_count);
    4.27 -          packet_count = 0;
    4.28 -        }
    4.29        }
    4.30      }
    4.31      xi->rx.rsp_cons = prod;
    4.32 @@ -252,22 +248,27 @@ XenNet_RxBufferCheck(struct xennet_info 
    4.33      RING_FINAL_CHECK_FOR_RESPONSES(&xi->rx, moretodo);
    4.34    } while (moretodo);
    4.35  
    4.36 +  /* Give netback more buffers */
    4.37 +  XenNet_RxBufferAlloc(xi);
    4.38 +
    4.39 +  KeReleaseSpinLockFromDpcLevel(&xi->rx_lock);
    4.40 +
    4.41 +  ASSERT(!more_frags);
    4.42 +/*
    4.43    if (more_frags)
    4.44    {
    4.45      KdPrint((__DRIVER_NAME "     Missing fragments\n"));
    4.46      XenNet_ReturnPacket(xi, packets[packet_count]);
    4.47    }
    4.48 -
    4.49 +*/
    4.50    if (packet_count != 0)
    4.51    {
    4.52      NdisMIndicateReceivePacket(xi->adapter_handle, packets, packet_count);
    4.53 +#if defined(XEN_PROFILE)
    4.54 +    ProfCount_CallsToIndicateReceive++;
    4.55 +#endif
    4.56    }
    4.57  
    4.58 -  /* Give netback more buffers */
    4.59 -  XenNet_RxBufferAlloc(xi);
    4.60 -
    4.61 -  KeReleaseSpinLockFromDpcLevel(&xi->rx_lock);
    4.62 -
    4.63  //  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    4.64  
    4.65  #if defined(XEN_PROFILE)
    4.66 @@ -278,7 +279,7 @@ XenNet_RxBufferCheck(struct xennet_info 
    4.67    return NDIS_STATUS_SUCCESS;
    4.68  }
    4.69  
    4.70 -/* called at DISPATCH_LEVEL with rx_lock held (as it gets called from IndicateReceived) */
    4.71 +/* called at DISPATCH_LEVEL */
    4.72  
    4.73  VOID
    4.74  XenNet_ReturnPacket(
    4.75 @@ -288,6 +289,7 @@ XenNet_ReturnPacket(
    4.76  {
    4.77    struct xennet_info *xi = MiniportAdapterContext;
    4.78    PMDL mdl;
    4.79 +  int cycles = 0;
    4.80  #if defined(XEN_PROFILE)
    4.81    LARGE_INTEGER tsc, dummy;
    4.82  #endif
    4.83 @@ -298,15 +300,20 @@ XenNet_ReturnPacket(
    4.84    tsc = KeQueryPerformanceCounter(&dummy);
    4.85  #endif
    4.86  
    4.87 +  KeAcquireSpinLockAtDpcLevel(&xi->rx_lock);
    4.88 +
    4.89    NdisUnchainBufferAtBack(Packet, &mdl);
    4.90    while (mdl)
    4.91    {
    4.92 +    ASSERT(cycles++ < 256);
    4.93      NdisAdjustBufferLength(mdl, PAGE_SIZE);
    4.94      put_page_on_freelist(xi, mdl);
    4.95      NdisUnchainBufferAtBack(Packet, &mdl);
    4.96    }
    4.97  
    4.98    NdisFreePacket(Packet);
    4.99 +
   4.100 +  KeReleaseSpinLockFromDpcLevel(&xi->rx_lock);
   4.101    
   4.102  //  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   4.103  
     5.1 --- a/xennet/xennet_tx.c	Wed Mar 05 20:44:14 2008 +1100
     5.2 +++ b/xennet/xennet_tx.c	Wed Mar 05 23:41:32 2008 +1100
     5.3 @@ -75,6 +75,7 @@ XenNet_SendQueuedPackets(struct xennet_i
     5.4    ULONGLONG curr_addr;
     5.5    ULONG sg_num;
     5.6    ULONG pfn;
     5.7 +  int cycles = 0;
     5.8  
     5.9  #if defined(XEN_PROFILE)
    5.10    tsc = KeQueryPerformanceCounter(&dummy);
    5.11 @@ -84,6 +85,8 @@ XenNet_SendQueuedPackets(struct xennet_i
    5.12    /* if empty, the above returns head*, not NULL */
    5.13    while (entry != &xi->tx_waiting_pkt_list)
    5.14    {
    5.15 +    cycles++;
    5.16 +    ASSERT(cycles < 256);
    5.17  //KdPrint((__DRIVER_NAME "     Packet ready to send\n"));
    5.18      packet = CONTAINING_RECORD(entry, NDIS_PACKET, MiniportReservedEx[sizeof(PVOID)]);
    5.19      sg_list = NDIS_PER_PACKET_INFO_FROM_PACKET(packet, ScatterGatherListPacketInfo);
    5.20 @@ -95,6 +98,8 @@ XenNet_SendQueuedPackets(struct xennet_i
    5.21      id = 0;
    5.22      while (sg_num < sg_list->NumberOfElements || remaining > 0)
    5.23      {
    5.24 +      cycles++;
    5.25 +      ASSERT(cycles < 256);
    5.26        if (remaining == 0)
    5.27        {
    5.28  //KdPrint((__DRIVER_NAME "     First Frag in sg...\n"));
    5.29 @@ -196,6 +201,7 @@ XenNet_TxBufferGC(struct xennet_info *xi
    5.30    unsigned short id;
    5.31    PNDIS_PACKET packet;
    5.32    int moretodo;
    5.33 +  int cycles = 0;
    5.34  #if defined(XEN_PROFILE)
    5.35    LARGE_INTEGER tsc, dummy;
    5.36  #endif
    5.37 @@ -212,6 +218,7 @@ XenNet_TxBufferGC(struct xennet_info *xi
    5.38    KeAcquireSpinLockAtDpcLevel(&xi->tx_lock);
    5.39  
    5.40    do {
    5.41 +    ASSERT(cycles++ < 256);
    5.42      prod = xi->tx.sring->rsp_prod;
    5.43      KeMemoryBarrier(); /* Ensure we see responses up to 'rp'. */
    5.44  
    5.45 @@ -318,7 +325,7 @@ XenNet_SendPackets(
    5.46      KdPrint((__DRIVER_NAME "     Packets per SendPackets = %10d\n", (ProfCount_SendPackets == 0)?0:(ProfCount_PacketsPerSendPackets / ProfCount_SendPackets)));
    5.47      KdPrint((__DRIVER_NAME "     SendQueuedPackets Count = %10d, Avg Time = %10ld\n", ProfCount_SendQueuedPackets, (ProfCount_SendQueuedPackets == 0)?0:(ProfTime_SendQueuedPackets.QuadPart / ProfCount_SendQueuedPackets)));
    5.48      KdPrint((__DRIVER_NAME "     TxBufferGC        Count = %10d, Avg Time = %10ld\n", ProfCount_TxBufferGC, (ProfCount_TxBufferGC == 0)?0:(ProfTime_TxBufferGC.QuadPart / ProfCount_TxBufferGC)));
    5.49 -    KdPrint((__DRIVER_NAME "     RxPackets         Total = %10d, Offload  = %10d\n", ProfCount_RxPacketsTotal, ProfCount_RxPacketsOffload));
    5.50 +    KdPrint((__DRIVER_NAME "     RxPackets         Total = %10d, Offload  = %10d, CallsToReceive = %10d\n", ProfCount_RxPacketsTotal, ProfCount_RxPacketsOffload, ProfCount_CallsToIndicateReceive));
    5.51      KdPrint((__DRIVER_NAME "     TxPackets         Total = %10d, Offload  = %10d\n", ProfCount_TxPacketsTotal, ProfCount_TxPacketsOffload));
    5.52    }
    5.53  #endif