win-pvdrivers

changeset 903:2e4f05dd4dfe 0.11.0.288

Try and balance TX and RX a bit better by doing it all from the same DPC. It's always on CPU 0 anyway now.
author James Harper <james.harper@bendigoit.com.au>
date Sat Apr 02 12:01:36 2011 +1100 (2011-04-02)
parents 44029b09876a
children 27b09cfec468
files xennet/xennet.c xennet/xennet.h xennet/xennet_oid.c xennet/xennet_rx.c xennet/xennet_tx.c
line diff
     1.1 --- a/xennet/xennet.c	Fri Apr 01 16:02:17 2011 +1100
     1.2 +++ b/xennet/xennet.c	Sat Apr 02 12:01:36 2011 +1100
     1.3 @@ -320,7 +320,22 @@ XenNet_SuspendResume(PKDPC dpc, PVOID co
     1.4    FUNCTION_EXIT();
     1.5  }
     1.6  
     1.7 -static DDKAPI BOOLEAN
     1.8 +static VOID
     1.9 +XenNet_RxTxDpc(PKDPC dpc, PVOID context, PVOID arg1, PVOID arg2)
    1.10 +{
    1.11 +  struct xennet_info *xi = context;
    1.12 +  BOOLEAN dont_set_event;
    1.13 +
    1.14 +  UNREFERENCED_PARAMETER(dpc);
    1.15 +  UNREFERENCED_PARAMETER(arg1);
    1.16 +  UNREFERENCED_PARAMETER(arg2);
    1.17 +
    1.18 +  /* if Rx goes over its per-dpc quota then make sure TxBufferGC doesn't set an event as we are already guaranteed to be called again */
    1.19 +  dont_set_event = XenNet_RxBufferCheck(xi);
    1.20 +  XenNet_TxBufferGC(xi, dont_set_event);
    1.21 +} 
    1.22 +
    1.23 +static BOOLEAN
    1.24  XenNet_HandleEvent(PVOID context)
    1.25  {
    1.26    struct xennet_info *xi = context;
    1.27 @@ -337,8 +352,7 @@ XenNet_HandleEvent(PVOID context)
    1.28    }
    1.29    if (xi->connected && !xi->inactive && suspend_resume_state_pdo != SR_STATE_RESUMING)
    1.30    {
    1.31 -    KeInsertQueueDpc(&xi->tx_dpc, NULL, NULL);
    1.32 -    KeInsertQueueDpc(&xi->rx_dpc, NULL, NULL);
    1.33 +    KeInsertQueueDpc(&xi->rxtx_dpc, NULL, NULL);
    1.34    }
    1.35    //FUNCTION_EXIT();
    1.36    return TRUE;
    1.37 @@ -617,6 +631,10 @@ XenNet_Init(
    1.38    KeInitializeDpc(&xi->suspend_dpc, XenNet_SuspendResume, xi);
    1.39    KeInitializeSpinLock(&xi->resume_lock);
    1.40  
    1.41 +  KeInitializeDpc(&xi->rxtx_dpc, XenNet_RxTxDpc, xi);
    1.42 +  KeSetTargetProcessorDpc(&xi->rxtx_dpc, 0);
    1.43 +  KeSetImportanceDpc(&xi->rxtx_dpc, HighImportance);
    1.44 +
    1.45    NdisMGetDeviceProperty(MiniportAdapterHandle, &xi->pdo, &xi->fdo,
    1.46      &xi->lower_do, NULL, NULL);
    1.47    xi->packet_filter = 0;
    1.48 @@ -827,7 +845,7 @@ XenNet_PnPEventNotify(
    1.49  }
    1.50  
    1.51  /* Called when machine is shutting down, so just quiesce the HW and be done fast. */
    1.52 -VOID DDKAPI
    1.53 +VOID
    1.54  XenNet_Shutdown(
    1.55    IN NDIS_HANDLE MiniportAdapterContext
    1.56    )
    1.57 @@ -840,7 +858,7 @@ XenNet_Shutdown(
    1.58  }
    1.59  
    1.60  /* Opposite of XenNet_Init */
    1.61 -VOID DDKAPI
    1.62 +VOID
    1.63  XenNet_Halt(
    1.64    IN NDIS_HANDLE MiniportAdapterContext
    1.65    )
     2.1 --- a/xennet/xennet.h	Fri Apr 01 16:02:17 2011 +1100
     2.2 +++ b/xennet/xennet.h	Sat Apr 02 12:01:36 2011 +1100
     2.3 @@ -21,7 +21,6 @@ Foundation, Inc., 51 Franklin Street, Fi
     2.4  #pragma warning(disable: 4201)
     2.5  #pragma warning(disable: 4214)
     2.6  
     2.7 -#define DDKAPI
     2.8  #include <ntddk.h>
     2.9  #include <wdm.h>
    2.10  #define NDIS_MINIPORT_DRIVER
    2.11 @@ -272,6 +271,7 @@ struct xennet_info
    2.12    KDPC suspend_dpc;
    2.13    PIO_WORKITEM resume_work_item;
    2.14    KSPIN_LOCK resume_lock;
    2.15 +  KDPC rxtx_dpc;
    2.16  
    2.17    /* tx related - protected by tx_lock */
    2.18    KSPIN_LOCK tx_lock;
    2.19 @@ -287,7 +287,6 @@ struct xennet_info
    2.20    ULONG tx_outstanding;
    2.21    ULONG tx_id_free;
    2.22    USHORT tx_id_list[NET_TX_RING_SIZE];
    2.23 -  KDPC tx_dpc;
    2.24    NPAGED_LOOKASIDE_LIST tx_lookaside_list;
    2.25  
    2.26    /* rx_related - protected by rx_lock */
    2.27 @@ -297,7 +296,6 @@ struct xennet_info
    2.28    packet_info_t *rxpi;
    2.29    KEVENT packet_returned_event;
    2.30    //NDIS_MINIPORT_TIMER rx_timer;
    2.31 -  KDPC rx_dpc;
    2.32    KTIMER rx_timer;
    2.33    KDPC rx_timer_dpc;
    2.34    NDIS_HANDLE rx_packet_pool;
    2.35 @@ -340,7 +338,7 @@ struct xennet_info
    2.36    
    2.37  } typedef xennet_info_t;
    2.38  
    2.39 -VOID DDKAPI
    2.40 +VOID
    2.41  XenNet_ReturnPacket(
    2.42    IN NDIS_HANDLE MiniportAdapterContext,
    2.43    IN PNDIS_PACKET Packet
    2.44 @@ -358,13 +356,16 @@ XenNet_RxResumeStart(xennet_info_t *xi);
    2.45  VOID
    2.46  XenNet_RxResumeEnd(xennet_info_t *xi);
    2.47  
    2.48 +BOOLEAN
    2.49 +XenNet_RxBufferCheck(struct xennet_info *xi);
    2.50 +
    2.51  VOID
    2.52  XenNet_TxResumeStart(xennet_info_t *xi);
    2.53  
    2.54  VOID
    2.55  XenNet_TxResumeEnd(xennet_info_t *xi);
    2.56  
    2.57 -VOID DDKAPI
    2.58 +VOID
    2.59  XenNet_SendPackets(
    2.60    IN NDIS_HANDLE MiniportAdapterContext,
    2.61    IN PPNDIS_PACKET PacketArray,
    2.62 @@ -382,7 +383,10 @@ XenNet_TxInit(xennet_info_t *xi);
    2.63  BOOLEAN
    2.64  XenNet_TxShutdown(xennet_info_t *xi);
    2.65  
    2.66 -NDIS_STATUS DDKAPI
    2.67 +VOID
    2.68 +XenNet_TxBufferGC(struct xennet_info *xi, BOOLEAN dont_set_event);
    2.69 +
    2.70 +NDIS_STATUS
    2.71  XenNet_QueryInformation(
    2.72    IN NDIS_HANDLE MiniportAdapterContext,
    2.73    IN NDIS_OID Oid,
    2.74 @@ -391,7 +395,7 @@ XenNet_QueryInformation(
    2.75    OUT PULONG BytesWritten,
    2.76    OUT PULONG BytesNeeded);
    2.77  
    2.78 -NDIS_STATUS DDKAPI
    2.79 +NDIS_STATUS
    2.80  XenNet_SetInformation(
    2.81    IN NDIS_HANDLE MiniportAdapterContext,
    2.82    IN NDIS_OID Oid,
     3.1 --- a/xennet/xennet_oid.c	Fri Apr 01 16:02:17 2011 +1100
     3.2 +++ b/xennet/xennet_oid.c	Sat Apr 02 12:01:36 2011 +1100
     3.3 @@ -76,7 +76,7 @@ NDIS_OID supported_oids[] =
     3.4      len = 8; \
     3.5      } }
     3.6  
     3.7 -NDIS_STATUS DDKAPI
     3.8 +NDIS_STATUS
     3.9  XenNet_QueryInformation(
    3.10    IN NDIS_HANDLE MiniportAdapterContext,
    3.11    IN NDIS_OID Oid,
    3.12 @@ -406,7 +406,7 @@ XenNet_QueryInformation(
    3.13    return status;
    3.14  }
    3.15  
    3.16 -NDIS_STATUS DDKAPI
    3.17 +NDIS_STATUS
    3.18  XenNet_SetInformation(
    3.19    IN NDIS_HANDLE MiniportAdapterContext,
    3.20    IN NDIS_OID Oid,
     4.1 --- a/xennet/xennet_rx.c	Fri Apr 01 16:02:17 2011 +1100
     4.2 +++ b/xennet/xennet_rx.c	Sat Apr 02 12:01:36 2011 +1100
     4.3 @@ -20,12 +20,8 @@ Foundation, Inc., 51 Franklin Street, Fi
     4.4  
     4.5  #include "xennet.h"
     4.6  
     4.7 -/* Not really necessary but keeps PREfast happy */
     4.8 -#if (NTDDI_VERSION >= NTDDI_WINXP)
     4.9 -static KDEFERRED_ROUTINE XenNet_RxBufferCheck;
    4.10 -#endif
    4.11 -
    4.12  LONG rx_pb_outstanding = 0;
    4.13 +LONG rx_pb_outstanding_refs = 0;
    4.14  
    4.15  static __inline shared_buffer_t *
    4.16  get_pb_from_freelist(struct xennet_info *xi)
    4.17 @@ -40,6 +36,7 @@ get_pb_from_freelist(struct xennet_info 
    4.18      pb->ref_count = 1;
    4.19      InterlockedDecrement(&xi->rx_pb_free);
    4.20      InterlockedIncrement(&rx_pb_outstanding);
    4.21 +    InterlockedIncrement(&rx_pb_outstanding_refs);
    4.22      return pb;
    4.23    }
    4.24  
    4.25 @@ -78,6 +75,7 @@ get_pb_from_freelist(struct xennet_info 
    4.26    }
    4.27    InterlockedIncrement(&rx_pb_outstanding);
    4.28    pb->ref_count = 1;
    4.29 +  InterlockedIncrement(&rx_pb_outstanding_refs);
    4.30    return pb;
    4.31  }
    4.32  
    4.33 @@ -86,11 +84,13 @@ ref_pb(struct xennet_info *xi, shared_bu
    4.34  {
    4.35    UNREFERENCED_PARAMETER(xi);
    4.36    InterlockedIncrement(&pb->ref_count);
    4.37 +  InterlockedIncrement(&rx_pb_outstanding_refs);
    4.38  }
    4.39  
    4.40  static __inline VOID
    4.41  put_pb_on_freelist(struct xennet_info *xi, shared_buffer_t *pb)
    4.42  {
    4.43 +  InterlockedDecrement(&rx_pb_outstanding_refs);
    4.44    if (InterlockedDecrement(&pb->ref_count) == 0)
    4.45    {
    4.46      NdisAdjustBufferLength(pb->buffer, PAGE_SIZE);
    4.47 @@ -189,10 +189,10 @@ put_packet_on_freelist(struct xennet_inf
    4.48    InterlockedDecrement(&total_allocated_packets);
    4.49    NdisFreePacket(packet);
    4.50    KeQuerySystemTime(&current_time);
    4.51 -  if ((int)total_allocated_packets < 0 || (current_time.QuadPart - last_print_time.QuadPart) / 10000 > 1000)
    4.52 +  if ((int)total_allocated_packets < 0 || (current_time.QuadPart - last_print_time.QuadPart) / 10000 > 5000)
    4.53    {
    4.54      last_print_time.QuadPart = current_time.QuadPart;
    4.55 -    KdPrint(("total_allocated_packets = %d, rx_outstanding = %d, dpc_limit_hit = %d, rx_pb_outstanding = %d, rx_pb_free = %d\n", total_allocated_packets, xi->rx_outstanding, dpc_limit_hit, rx_pb_outstanding, xi->rx_pb_free));
    4.56 +    KdPrint(("total_allocated_packets = %d, rx_outstanding = %d, dpc_limit_hit = %d, rx_pb_outstanding = %d, rx_pb_outstanding_refs = %d, rx_pb_free = %d\n", total_allocated_packets, xi->rx_outstanding, dpc_limit_hit, rx_pb_outstanding, rx_pb_outstanding_refs, xi->rx_pb_free));
    4.57    }
    4.58  }
    4.59  
    4.60 @@ -614,16 +614,6 @@ done:
    4.61    return packet_count;
    4.62  }
    4.63  
    4.64 -static BOOLEAN
    4.65 -XenNet_RxQueueDpcSynchronized(PVOID context)
    4.66 -{
    4.67 -  struct xennet_info *xi = context;
    4.68 -
    4.69 -  KeInsertQueueDpc(&xi->rx_dpc, NULL, NULL);
    4.70 -  
    4.71 -  return TRUE;
    4.72 -}
    4.73 -
    4.74  #define MAXIMUM_PACKETS_PER_INDICATE 32
    4.75  
    4.76  /* We limit the number of packets per interrupt so that acks get a chance
    4.77 @@ -632,10 +622,9 @@ under high rx load. The DPC is immediate
    4.78  #define MAXIMUM_DATA_PER_INTERRUPT (MAXIMUM_PACKETS_PER_INTERRUPT * 1500) /* help account for large packets */
    4.79  
    4.80  // Called at DISPATCH_LEVEL
    4.81 -static VOID
    4.82 -XenNet_RxBufferCheck(PKDPC dpc, PVOID context, PVOID arg1, PVOID arg2)
    4.83 +BOOLEAN
    4.84 +XenNet_RxBufferCheck(struct xennet_info *xi)
    4.85  {
    4.86 -  struct xennet_info *xi = context;
    4.87    RING_IDX cons, prod;
    4.88    LIST_ENTRY rx_packet_list;
    4.89    PLIST_ENTRY entry;
    4.90 @@ -656,15 +645,12 @@ XenNet_RxBufferCheck(PKDPC dpc, PVOID co
    4.91    BOOLEAN extra_info_flag = FALSE;
    4.92    BOOLEAN more_data_flag = FALSE;
    4.93    PNDIS_BUFFER buffer;
    4.94 -
    4.95 -  UNREFERENCED_PARAMETER(dpc);
    4.96 -  UNREFERENCED_PARAMETER(arg1);
    4.97 -  UNREFERENCED_PARAMETER(arg2);
    4.98 +  BOOLEAN dont_set_event;
    4.99  
   4.100    //FUNCTION_ENTER();
   4.101  
   4.102    if (!xi->connected)
   4.103 -    return; /* a delayed DPC could let this come through... just do nothing */
   4.104 +    return FALSE; /* a delayed DPC could let this come through... just do nothing */
   4.105  
   4.106    InitializeListHead(&rx_packet_list);
   4.107  
   4.108 @@ -676,7 +662,7 @@ XenNet_RxBufferCheck(PKDPC dpc, PVOID co
   4.109    {
   4.110      /* there is a chance that our Dpc had been queued just before the shutdown... */
   4.111      KeReleaseSpinLockFromDpcLevel(&xi->rx_lock);
   4.112 -    return;
   4.113 +    return FALSE;
   4.114    }
   4.115  
   4.116    if (xi->rx_partial_buf)
   4.117 @@ -783,14 +769,17 @@ XenNet_RxBufferCheck(PKDPC dpc, PVOID co
   4.118      //KdPrint((__DRIVER_NAME "     Dpc Duration Exceeded\n"));
   4.119      dpc_limit_hit++;
   4.120      /* we want the Dpc on the end of the queue. By definition we are already on the right CPU so we know the Dpc queue will be run immediately */
   4.121 -    KeSetImportanceDpc(&xi->rx_dpc, MediumImportance);
   4.122 -    KeInsertQueueDpc(&xi->rx_dpc, NULL, NULL);
   4.123 -    //xi->vectors.EvtChn_Sync(xi->vectors.context, XenNet_RxQueueDpcSynchronized, xi);
   4.124 +    KeSetImportanceDpc(&xi->rxtx_dpc, MediumImportance);
   4.125 +    KeInsertQueueDpc(&xi->rxtx_dpc, NULL, NULL);
   4.126 +    /* dont set an event in TX path */
   4.127 +    dont_set_event = TRUE;
   4.128    }
   4.129    else
   4.130    {
   4.131      /* make sure the Dpc queue is run immediately next interrupt */
   4.132 -    KeSetImportanceDpc(&xi->rx_dpc, HighImportance);
   4.133 +    KeSetImportanceDpc(&xi->rxtx_dpc, HighImportance);
   4.134 +    /* set an event in TX path */
   4.135 +    dont_set_event = FALSE;
   4.136    }
   4.137  
   4.138    /* make packets out of the buffers */
   4.139 @@ -895,6 +884,7 @@ XenNet_RxBufferCheck(PKDPC dpc, PVOID co
   4.140        packet_count = 0;
   4.141      }
   4.142    }
   4.143 +  return dont_set_event;
   4.144    //FUNCTION_EXIT();
   4.145  }
   4.146  
   4.147 @@ -1047,10 +1037,6 @@ XenNet_RxInit(xennet_info_t *xi)
   4.148    KeInitializeSpinLock(&xi->rx_lock);
   4.149    KeInitializeEvent(&xi->packet_returned_event, SynchronizationEvent, FALSE);
   4.150    KeInitializeTimer(&xi->rx_timer);
   4.151 -  KeInitializeDpc(&xi->rx_dpc, XenNet_RxBufferCheck, xi);
   4.152 -  KeSetTargetProcessorDpc(&xi->rx_dpc, 0);
   4.153 -  KeSetImportanceDpc(&xi->rx_dpc, HighImportance);
   4.154 -  //KeInitializeDpc(&xi->rx_timer_dpc, XenNet_RxTimerDpc, xi);
   4.155    status = NdisAllocateMemoryWithTag((PVOID)&xi->rxpi, sizeof(packet_info_t) * NdisSystemProcessorCount(), XENNET_POOL_TAG);
   4.156    if (status != NDIS_STATUS_SUCCESS)
   4.157    {
   4.158 @@ -1097,7 +1083,6 @@ XenNet_RxShutdown(xennet_info_t *xi)
   4.159      KeCancelTimer(&xi->rx_timer);
   4.160    }
   4.161  
   4.162 -  KeRemoveQueueDpc(&xi->rx_dpc);
   4.163  #if (NTDDI_VERSION >= NTDDI_WINXP)
   4.164    KeFlushQueuedDpcs();
   4.165  #endif
     5.1 --- a/xennet/xennet_tx.c	Fri Apr 01 16:02:17 2011 +1100
     5.2 +++ b/xennet/xennet_tx.c	Sat Apr 02 12:01:36 2011 +1100
     5.3 @@ -20,11 +20,6 @@ Foundation, Inc., 51 Franklin Street, Fi
     5.4  
     5.5  #include "xennet.h"
     5.6  
     5.7 -/* Not really necessary but keeps PREfast happy */
     5.8 -#if (NTDDI_VERSION >= NTDDI_WINXP)
     5.9 -static KDEFERRED_ROUTINE XenNet_TxBufferGC;
    5.10 -#endif
    5.11 -
    5.12  static USHORT
    5.13  get_id_from_freelist(struct xennet_info *xi)
    5.14  {
    5.15 @@ -419,19 +414,14 @@ XenNet_SendQueuedPackets(struct xennet_i
    5.16  
    5.17  //ULONG packets_outstanding = 0;
    5.18  // Called at DISPATCH_LEVEL
    5.19 -static VOID
    5.20 -XenNet_TxBufferGC(PKDPC dpc, PVOID context, PVOID arg1, PVOID arg2)
    5.21 +VOID
    5.22 +XenNet_TxBufferGC(struct xennet_info *xi, BOOLEAN dont_set_event)
    5.23  {
    5.24 -  struct xennet_info *xi = context;
    5.25    RING_IDX cons, prod;
    5.26    PNDIS_PACKET head = NULL, tail = NULL;
    5.27    PNDIS_PACKET packet;
    5.28    ULONG tx_packets = 0;
    5.29  
    5.30 -  UNREFERENCED_PARAMETER(dpc);
    5.31 -  UNREFERENCED_PARAMETER(arg1);
    5.32 -  UNREFERENCED_PARAMETER(arg2);
    5.33 -
    5.34    //FUNCTION_ENTER();
    5.35  
    5.36    if (!xi->connected)
    5.37 @@ -496,7 +486,8 @@ XenNet_TxBufferGC(PKDPC dpc, PVOID conte
    5.38  
    5.39      xi->tx.rsp_cons = prod;
    5.40      /* resist the temptation to set the event more than +1... it breaks things */
    5.41 -    xi->tx.sring->rsp_event = prod + 1;
    5.42 +    if (!dont_set_event)
    5.43 +      xi->tx.sring->rsp_event = prod + 1;
    5.44      KeMemoryBarrier();
    5.45    } while (prod != xi->tx.sring->rsp_prod);
    5.46  
    5.47 @@ -536,7 +527,7 @@ XenNet_TxBufferGC(PKDPC dpc, PVOID conte
    5.48  }
    5.49  
    5.50  // called at <= DISPATCH_LEVEL
    5.51 -VOID DDKAPI
    5.52 +VOID
    5.53  XenNet_SendPackets(
    5.54    IN NDIS_HANDLE MiniportAdapterContext,
    5.55    IN PPNDIS_PACKET PacketArray,
    5.56 @@ -656,10 +647,6 @@ XenNet_TxInit(xennet_info_t *xi)
    5.57    USHORT i;
    5.58  
    5.59    KeInitializeSpinLock(&xi->tx_lock);
    5.60 -  KeInitializeDpc(&xi->tx_dpc, XenNet_TxBufferGC, xi);
    5.61 -  /* dpcs are only serialised to a single processor */
    5.62 -  KeSetTargetProcessorDpc(&xi->tx_dpc, 0);
    5.63 -  KeSetImportanceDpc(&xi->tx_dpc, HighImportance);
    5.64    InitializeListHead(&xi->tx_waiting_pkt_list);
    5.65  
    5.66    KeInitializeEvent(&xi->tx_idle_event, SynchronizationEvent, FALSE);
    5.67 @@ -707,7 +694,6 @@ XenNet_TxShutdown(xennet_info_t *xi)
    5.68      KeWaitForSingleObject(&xi->tx_idle_event, Executive, KernelMode, FALSE, NULL);
    5.69    }
    5.70  
    5.71 -  KeRemoveQueueDpc(&xi->tx_dpc);
    5.72  #if (NTDDI_VERSION >= NTDDI_WINXP)
    5.73    KeFlushQueuedDpcs();
    5.74  #endif