win-pvdrivers

changeset 251:3db181609094

Added extra calls to Indicate in rx path, and limited the total work per interrupt.
Forced tx shutdown to wait for all outstanding packets to be completed.
author James Harper <james.harper@bendigoit.com.au>
date Thu Apr 10 20:43:45 2008 +1000 (2008-04-10)
parents 532d7485ddf2
children 7e3bcd88515c
files common.inc xennet/xennet_rx.c xennet/xennet_tx.c
line diff
     1.1 --- a/common.inc	Wed Apr 09 22:38:13 2008 +1000
     1.2 +++ b/common.inc	Thu Apr 10 20:43:45 2008 +1000
     1.3 @@ -1,4 +1,4 @@
     1.4 -VERSION=0.8.8.38
     1.5 +VERSION=0.8.8.40
     1.6  TARGETPATH=..\Target\$(DDK_TARGET_OS)
     1.7  KMDF_VERSION=1
     1.8  !IF $(_NT_TOOLS_VERSION) > 0x700
     2.1 --- a/xennet/xennet_rx.c	Wed Apr 09 22:38:13 2008 +1000
     2.2 +++ b/xennet/xennet_rx.c	Thu Apr 10 20:43:45 2008 +1000
     2.3 @@ -380,13 +380,17 @@ pc++;
     2.4  //  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ " (split)\n"));
     2.5  }
     2.6  
     2.7 +#define MAXIMUM_PACKETS_PER_INTERRUPT 64
     2.8 +#define MAXIMUM_PACKETS_PER_INDICATE 8
     2.9 +
    2.10  // Called at DISPATCH_LEVEL
    2.11  NDIS_STATUS
    2.12  XenNet_RxBufferCheck(struct xennet_info *xi)
    2.13  {
    2.14    RING_IDX cons, prod;
    2.15    PNDIS_PACKET packets[NET_RX_RING_SIZE];
    2.16 -  ULONG packet_count;
    2.17 +  ULONG packet_count = 0;
    2.18 +  ULONG total_packets = 0;
    2.19    PMDL mdl;
    2.20    int moretodo;
    2.21    struct netif_rx_response *rxrsp = NULL;
    2.22 @@ -394,23 +398,22 @@ XenNet_RxBufferCheck(struct xennet_info 
    2.23    USHORT id;
    2.24    int cycles = 0;
    2.25  #if defined(XEN_PROFILE)
    2.26 -  LARGE_INTEGER tsc, tsc2, dummy;
    2.27 +  LARGE_INTEGER tsc, dummy;
    2.28  #endif
    2.29    
    2.30  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    2.31  
    2.32  #if defined(XEN_PROFILE)
    2.33 -  tsc = tsc2 = KeQueryPerformanceCounter(&dummy);
    2.34 +  tsc = KeQueryPerformanceCounter(&dummy);
    2.35  #endif
    2.36  
    2.37    ASSERT(xi->connected);
    2.38  
    2.39    KeAcquireSpinLockAtDpcLevel(&xi->rx_lock);
    2.40  
    2.41 -  packet_count = 0;
    2.42    do {
    2.43      ASSERT(cycles++ < 256);
    2.44 -    prod = xi->rx.sring->rsp_prod;
    2.45 +    prod = min(xi->rx.sring->rsp_prod, xi->rx.rsp_cons + MAXIMUM_PACKETS_PER_INDICATE);
    2.46      KeMemoryBarrier(); /* Ensure we see responses up to 'rp'. */
    2.47  
    2.48      for (cons = xi->rx.rsp_cons; cons != prod; cons++)
    2.49 @@ -479,8 +482,21 @@ XenNet_RxBufferCheck(struct xennet_info 
    2.50      }
    2.51      ASSERT(packet_count < NET_RX_RING_SIZE);
    2.52      xi->rx.rsp_cons = prod;
    2.53 +
    2.54 +    if (packet_count > 0)
    2.55 +    {
    2.56 +      KeReleaseSpinLockFromDpcLevel(&xi->rx_lock);
    2.57 +      NdisMIndicateReceivePacket(xi->adapter_handle, packets, packet_count);
    2.58 +#if defined(XEN_PROFILE)
    2.59 +      ProfCount_CallsToIndicateReceive++;
    2.60 +#endif
    2.61 +      KeAcquireSpinLockAtDpcLevel(&xi->rx_lock);
    2.62 +      total_packets += packet_count;
    2.63 +      packet_count = 0;
    2.64 +    }
    2.65 +
    2.66      RING_FINAL_CHECK_FOR_RESPONSES(&xi->rx, moretodo);
    2.67 -  } while (moretodo);
    2.68 +  } while (moretodo && total_packets < MAXIMUM_PACKETS_PER_INTERRUPT);
    2.69  
    2.70    /* Give netback more buffers */
    2.71    XenNet_RxBufferAlloc(xi);
    2.72 @@ -488,21 +504,7 @@ XenNet_RxBufferCheck(struct xennet_info 
    2.73    KeReleaseSpinLockFromDpcLevel(&xi->rx_lock);
    2.74  
    2.75  #if defined(XEN_PROFILE)
    2.76 -  ProfTime_RxBufferCheckTopHalf.QuadPart += KeQueryPerformanceCounter(&dummy).QuadPart - tsc2.QuadPart;
    2.77 -  tsc2 = KeQueryPerformanceCounter(&dummy);
    2.78 -#endif
    2.79 -
    2.80 -  if (packet_count > 0)
    2.81 -  {
    2.82 -    NdisMIndicateReceivePacket(xi->adapter_handle, packets, packet_count);
    2.83 -#if defined(XEN_PROFILE)
    2.84 -    ProfCount_CallsToIndicateReceive++;
    2.85 -#endif
    2.86 -  }
    2.87 -
    2.88 -#if defined(XEN_PROFILE)
    2.89    ProfTime_RxBufferCheck.QuadPart += KeQueryPerformanceCounter(&dummy).QuadPart - tsc.QuadPart;
    2.90 -  ProfTime_RxBufferCheckBotHalf.QuadPart += KeQueryPerformanceCounter(&dummy).QuadPart - tsc2.QuadPart;
    2.91    ProfCount_RxBufferCheck++;
    2.92  #endif
    2.93  
     3.1 --- a/xennet/xennet_tx.c	Wed Apr 09 22:38:13 2008 +1000
     3.2 +++ b/xennet/xennet_tx.c	Thu Apr 10 20:43:45 2008 +1000
     3.3 @@ -665,6 +665,7 @@ XenNet_TxShutdown(xennet_info_t *xi)
     3.4  {
     3.5    KIRQL OldIrql;
     3.6    ULONG i;
     3.7 +  LARGE_INTEGER Interval;
     3.8  
     3.9    KeAcquireSpinLock(&xi->tx_lock, &OldIrql);
    3.10    NdisMSetPeriodicTimer(&xi->tx_timer, 1000);
    3.11 @@ -687,6 +688,16 @@ XenNet_TxShutdown(xennet_info_t *xi)
    3.12  
    3.13    /* I think that NDIS takes care of this for us... */
    3.14    /* no it doesn't - this needs handling properly */
    3.15 +  
    3.16 +  KdPrint((__DRIVER_NAME "     Waiting for tx_outstanding\n"));
    3.17 +  while (xi->tx_outstanding)
    3.18 +  {
    3.19 +    KdPrint((__DRIVER_NAME "     tx_outstanding = %d\n", xi->tx_outstanding));
    3.20 +    Interval.QuadPart = -1000000;
    3.21 +    KeDelayExecutionThread(KernelMode, FALSE, &Interval);
    3.22 +  }
    3.23 +  KdPrint((__DRIVER_NAME "     Done\n"));
    3.24 +
    3.25    ASSERT(xi->tx_outstanding == 0);
    3.26  
    3.27    for (i = 0; i < NET_TX_RING_SIZE; i++)