win-pvdrivers

changeset 257:253ec5052cb4

Xennet tuning... still getting occasional inconsistent results and very occasional crashes under extreme load.
author James Harper <james.harper@bendigoit.com.au>
date Mon Apr 28 23:07:28 2008 +1000 (2008-04-28)
parents 6c1ab34c1bda
children 9b16ad37af17 2fc877b00cfd
files common.inc xenhide/xenhide.c xennet/xennet.h xennet/xennet_oid.c xennet/xennet_rx.c
line diff
     1.1 --- a/common.inc	Sun Apr 27 00:01:43 2008 +1000
     1.2 +++ b/common.inc	Mon Apr 28 23:07:28 2008 +1000
     1.3 @@ -1,4 +1,4 @@
     1.4 -VERSION=0.8.9.3
     1.5 +VERSION=0.8.9.8
     1.6  TARGETPATH=..\Target\$(DDK_TARGET_OS)
     1.7  KMDF_VERSION=1
     1.8  !IF $(_NT_TOOLS_VERSION) > 0x700
     2.1 --- a/xenhide/xenhide.c	Sun Apr 27 00:01:43 2008 +1000
     2.2 +++ b/xenhide/xenhide.c	Mon Apr 28 23:07:28 2008 +1000
     2.3 @@ -265,7 +265,6 @@ XenHide_IoCompletion(PDEVICE_OBJECT Devi
     2.4    UNREFERENCED_PARAMETER(Context);
     2.5  
     2.6  //  KdPrint((__DRIVER_NAME " --> IoCompletion\n"));
     2.7 -//  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
     2.8  
     2.9    Relations = (PDEVICE_RELATIONS)Irp->IoStatus.Information;
    2.10  
    2.11 @@ -273,6 +272,10 @@ XenHide_IoCompletion(PDEVICE_OBJECT Devi
    2.12    {
    2.13    case 0:
    2.14      DeviceExtension->InternalState = 1;
    2.15 +    for (i = 0; i < Relations->Count; i++)
    2.16 +    {
    2.17 +      KdPrint((__DRIVER_NAME "     i = %d, DeviceType = 0x%08x\n", i, Relations->Objects[i]->DeviceType));
    2.18 +    }
    2.19      break;
    2.20    case 1:
    2.21      DeviceExtension->InternalState = 2; 
    2.22 @@ -310,6 +313,7 @@ XenHide_IoCompletion(PDEVICE_OBJECT Devi
    2.23          }
    2.24          if (Match)
    2.25          {
    2.26 +          KdPrint((__DRIVER_NAME "     Match at i = %d\n", i));
    2.27            Offset++;
    2.28          }
    2.29        }
     3.1 --- a/xennet/xennet.h	Sun Apr 27 00:01:43 2008 +1000
     3.2 +++ b/xennet/xennet.h	Mon Apr 28 23:07:28 2008 +1000
     3.3 @@ -83,7 +83,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  #define MIN_LARGE_SEND_SEGMENTS 4
    3.11  
    3.12 @@ -107,7 +107,7 @@ Foundation, Inc., 51 Franklin Street, Fi
    3.13  #define MAX_XENBUS_STR_LEN 128
    3.14  
    3.15  #define RX_MIN_TARGET 8
    3.16 -#define RX_DFL_MIN_TARGET 128
    3.17 +#define RX_DFL_MIN_TARGET 256
    3.18  #define RX_MAX_TARGET min(NET_RX_RING_SIZE, 256)
    3.19  
    3.20  #define MAX_BUFFERS_PER_PACKET 128
    3.21 @@ -200,6 +200,8 @@ struct xennet_info
    3.22    PNDIS_BUFFER rx_buffers[NET_RX_RING_SIZE];
    3.23    freelist_t rx_freelist;
    3.24    packet_info_t rxpi;
    3.25 +  PNDIS_PACKET rx_packet_list[NET_RX_RING_SIZE * 2];
    3.26 +  ULONG rx_packet_free;
    3.27  
    3.28    /* Receive-ring batched refills. */
    3.29    ULONG rx_target;
     4.1 --- a/xennet/xennet_oid.c	Sun Apr 27 00:01:43 2008 +1000
     4.2 +++ b/xennet/xennet_oid.c	Mon Apr 28 23:07:28 2008 +1000
     4.3 @@ -125,8 +125,9 @@ XenNet_QueryInformation(
     4.4        break;
     4.5      case OID_GEN_TRANSMIT_BUFFER_SPACE:
     4.6        /* pkts times sizeof ring, maybe? */
     4.7 +      /* multiply this by some small number as we can queue additional packets */
     4.8  //      temp_data = XN_MAX_PKT_SIZE * NET_TX_RING_SIZE;
     4.9 -      temp_data = PAGE_SIZE * NET_TX_RING_SIZE;
    4.10 +      temp_data = PAGE_SIZE * NET_TX_RING_SIZE * 4;
    4.11        break;
    4.12      case OID_GEN_RECEIVE_BUFFER_SPACE:
    4.13        /* pkts times sizeof ring, maybe? */
    4.14 @@ -172,7 +173,8 @@ XenNet_QueryInformation(
    4.15          temp_data = NdisMediaStateDisconnected;
    4.16        break;
    4.17      case OID_GEN_MAXIMUM_SEND_PACKETS:
    4.18 -      temp_data = XN_MAX_SEND_PKTS;
    4.19 +      /* this is actually ignored for deserialised drivers like us */
    4.20 +      temp_data = 0; //XN_MAX_SEND_PKTS;
    4.21        break;
    4.22      case OID_GEN_XMIT_OK:
    4.23        temp_data = xi->stat_tx_ok;
     5.1 --- a/xennet/xennet_rx.c	Sun Apr 27 00:01:43 2008 +1000
     5.2 +++ b/xennet/xennet_rx.c	Mon Apr 28 23:07:28 2008 +1000
     5.3 @@ -194,7 +194,43 @@ XenNet_SumPacketData(
     5.4  //  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
     5.5  }
     5.6  
     5.7 -static ULONG debug_length;
     5.8 +static PNDIS_PACKET
     5.9 +get_packet_from_freelist(struct xennet_info *xi)
    5.10 +{
    5.11 +  NDIS_STATUS status;
    5.12 +  PNDIS_PACKET packet;
    5.13 +
    5.14 +  if (!xi->rx_packet_free)
    5.15 +  {
    5.16 +    NdisAllocatePacket(&status, &packet, xi->packet_pool);
    5.17 +    ASSERT(status == NDIS_STATUS_SUCCESS);
    5.18 +    NDIS_SET_PACKET_HEADER_SIZE(packet, XN_HDR_SIZE);
    5.19 +  }
    5.20 +  else
    5.21 +  {
    5.22 +    xi->rx_packet_free--;
    5.23 +    packet = xi->rx_packet_list[xi->rx_packet_free];
    5.24 +  }
    5.25 +  return packet;
    5.26 +}
    5.27 +
    5.28 +static VOID
    5.29 +put_packet_on_freelist(struct xennet_info *xi, PNDIS_PACKET packet)
    5.30 +{
    5.31 +  NdisReinitializePacket(packet);
    5.32 +  xi->rx_packet_list[xi->rx_packet_free] = packet;
    5.33 +  xi->rx_packet_free++;
    5.34 +}
    5.35 +
    5.36 +static VOID
    5.37 +packet_freelist_dispose(struct xennet_info *xi)
    5.38 +{
    5.39 +  while(xi->rx_packet_free != 0)
    5.40 +  {
    5.41 +    xi->rx_packet_free--;
    5.42 +    NdisFreePacket(xi->rx_packet_list[xi->rx_packet_free]);
    5.43 +  }
    5.44 +}
    5.45  
    5.46  static PNDIS_PACKET
    5.47  XenNet_MakePacket(
    5.48 @@ -209,15 +245,13 @@ XenNet_MakePacket(
    5.49    USHORT out_remaining;
    5.50    USHORT length;
    5.51    USHORT new_ip4_length;
    5.52 -  NDIS_STATUS status;
    5.53 +  //NDIS_STATUS status;
    5.54    USHORT i;
    5.55  
    5.56  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    5.57  
    5.58 -  NdisAllocatePacket(&status, &packet, xi->packet_pool);
    5.59 -  ASSERT(status == NDIS_STATUS_SUCCESS);
    5.60 +  packet = get_packet_from_freelist(xi);
    5.61    xi->rx_outstanding++;
    5.62 -  NDIS_SET_PACKET_HEADER_SIZE(packet, XN_HDR_SIZE);
    5.63  
    5.64    if (!xi->rxpi.split_required)
    5.65    {
    5.66 @@ -274,12 +308,14 @@ XenNet_MakePackets(
    5.67        break;
    5.68      // fallthrough
    5.69    case 17:  // UDP
    5.70 +    ASSERT(*packet_count_p < NET_RX_RING_SIZE);
    5.71      packets[*packet_count_p] = XenNet_MakePacket(xi);
    5.72      if (xi->rxpi.csum_calc_required)
    5.73        XenNet_SumPacketData(&xi->rxpi, packets[*packet_count_p]);
    5.74      (*packet_count_p)++;
    5.75      return;
    5.76    default:
    5.77 +    ASSERT(*packet_count_p < NET_RX_RING_SIZE);
    5.78      packets[*packet_count_p] = XenNet_MakePacket(xi);
    5.79      (*packet_count_p)++;
    5.80      return;
    5.81 @@ -293,6 +329,7 @@ XenNet_MakePackets(
    5.82  
    5.83    while (xi->rxpi.tcp_remaining)
    5.84    {
    5.85 +    ASSERT(*packet_count_p < NET_RX_RING_SIZE);
    5.86      packets[*packet_count_p] = XenNet_MakePacket(xi);
    5.87      XenNet_SumPacketData(&xi->rxpi, packets[*packet_count_p]);
    5.88      (*packet_count_p)++;
    5.89 @@ -308,14 +345,17 @@ XenNet_MakePackets(
    5.90  //  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ " (split)\n"));
    5.91  }
    5.92  
    5.93 -#define MAXIMUM_PACKETS_PER_INTERRUPT 64
    5.94 -#define MAXIMUM_PACKETS_PER_INDICATE 8
    5.95 +#define MAXIMUM_PACKETS_PER_INTERRUPT 128
    5.96 +#define MAXIMUM_PACKETS_PER_INDICATE 32
    5.97  
    5.98  // Called at DISPATCH_LEVEL
    5.99  NDIS_STATUS
   5.100  XenNet_RxBufferCheck(struct xennet_info *xi)
   5.101  {
   5.102    RING_IDX cons, prod;
   5.103 +  /* the highest number of packets we receive could be (65535 - header) / mss
   5.104 +     for a low mss this could be even higher than NET_RX_RING_SIZE...
   5.105 +     what can we do? */
   5.106    PNDIS_PACKET packets[NET_RX_RING_SIZE];
   5.107    ULONG packet_count = 0;
   5.108    ULONG total_packets = 0;
   5.109 @@ -404,15 +444,17 @@ XenNet_RxBufferCheck(struct xennet_info 
   5.110        /* Packet done, add it to the list */
   5.111        if (!xi->rxpi.more_frags && !xi->rxpi.extra_info)
   5.112        {
   5.113 +        /* we should probably check here and make sure that we have enough
   5.114 +           space for these packets, and if we don't, defer MakePackets until
   5.115 +           we have Indicated the current packets... */
   5.116          XenNet_MakePackets(xi, packets, &packet_count);
   5.117          RtlZeroMemory(&xi->rxpi, sizeof(xi->rxpi));
   5.118 -//        if (packet_count >= MAXIMUM_PACKETS_PER_INDICATE)
   5.119 -//          break;
   5.120        }
   5.121      }
   5.122 -    ASSERT(packet_count < NET_RX_RING_SIZE);
   5.123      xi->rx.rsp_cons = cons;
   5.124  
   5.125 +    XenNet_RxBufferAlloc(xi);
   5.126 +
   5.127      if (packet_count > 0)
   5.128      {
   5.129        KeReleaseSpinLockFromDpcLevel(&xi->rx_lock);
   5.130 @@ -476,7 +518,7 @@ XenNet_ReturnPacket(
   5.131      NdisUnchainBufferAtBack(Packet, &mdl);
   5.132    }
   5.133  
   5.134 -  NdisFreePacket(Packet);
   5.135 +  put_packet_on_freelist(xi, Packet);
   5.136    xi->rx_outstanding--;
   5.137  
   5.138    KeReleaseSpinLockFromDpcLevel(&xi->rx_lock);
   5.139 @@ -558,6 +600,8 @@ XenNet_RxShutdown(xennet_info_t *xi)
   5.140  
   5.141    XenFreelist_Dispose(&xi->rx_freelist);
   5.142  
   5.143 +  packet_freelist_dispose(xi);
   5.144 +
   5.145    /* free RX resources */
   5.146    ASSERT(xi->XenInterface.GntTbl_EndAccess(
   5.147      xi->XenInterface.InterfaceHeader.Context, xi->rx_ring_ref, 0));