win-pvdrivers

changeset 252:7e3bcd88515c

packets are being very occasionally sent without headers... and other strange things are happening. added some debugging.
author James Harper <james.harper@bendigoit.com.au>
date Tue Apr 15 23:36:10 2008 +1000 (2008-04-15)
parents 3db181609094
children 58ce01887603
files common.inc xennet/xennet.h xennet/xennet_common.c xennet/xennet_rx.c xennet/xennet_tx.c
line diff
     1.1 --- a/common.inc	Thu Apr 10 20:43:45 2008 +1000
     1.2 +++ b/common.inc	Tue Apr 15 23:36:10 2008 +1000
     1.3 @@ -1,4 +1,4 @@
     1.4 -VERSION=0.8.8.40
     1.5 +VERSION=0.8.8.54
     1.6  TARGETPATH=..\Target\$(DDK_TARGET_OS)
     1.7  KMDF_VERSION=1
     1.8  !IF $(_NT_TOOLS_VERSION) > 0x700
     2.1 --- a/xennet/xennet.h	Thu Apr 10 20:43:45 2008 +1000
     2.2 +++ b/xennet/xennet.h	Tue Apr 15 23:36:10 2008 +1000
     2.3 @@ -110,7 +110,7 @@ Foundation, Inc., 51 Franklin Street, Fi
     2.4  #define RX_DFL_MIN_TARGET 128
     2.5  #define RX_MAX_TARGET min(NET_RX_RING_SIZE, 256)
     2.6  
     2.7 -#define MAX_BUFFERS_PER_PACKET 64
     2.8 +#define MAX_BUFFERS_PER_PACKET 128
     2.9  
    2.10  
    2.11  typedef struct {
     3.1 --- a/xennet/xennet_common.c	Thu Apr 10 20:43:45 2008 +1000
     3.2 +++ b/xennet/xennet_common.c	Tue Apr 15 23:36:10 2008 +1000
     3.3 @@ -33,6 +33,11 @@ XenNet_ParsePacketHeader(
     3.4    
     3.5    NdisQueryBufferSafe(pi->mdls[0], &pi->header, &header_length, NormalPagePriority);
     3.6  
     3.7 +// what about if the buffer isn't completely on one page???
     3.8 +  if (ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(pi->mdls[0]), header_length) != 1)
     3.9 +    KdPrint((__DRIVER_NAME "     header crosses a page!\n"));
    3.10 +
    3.11 +
    3.12    if (header_length < XN_HDR_SIZE + 20 + 20) // minimum size of first buffer is ETH + IP + TCP header
    3.13    {
    3.14      return PARSE_TOO_SMALL;
    3.15 @@ -50,7 +55,7 @@ XenNet_ParsePacketHeader(
    3.16      pi->ip4_header_length = (pi->header[XN_HDR_SIZE + 0] & 0x0F) << 2;
    3.17      if (header_length < (ULONG)(pi->ip4_header_length + 20))
    3.18      {
    3.19 -      KdPrint((__DRIVER_NAME "     first packet is only %d long, must be >= %d\n", XN_HDR_SIZE + header_length, (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + 20)));
    3.20 +      KdPrint((__DRIVER_NAME "     first buffer is only %d bytes long, must be >= %d\n", XN_HDR_SIZE + header_length, (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + 20)));
    3.21        // we need to do something conclusive here...
    3.22        return PARSE_TOO_SMALL;
    3.23      }
     4.1 --- a/xennet/xennet_rx.c	Thu Apr 10 20:43:45 2008 +1000
     4.2 +++ b/xennet/xennet_rx.c	Tue Apr 15 23:36:10 2008 +1000
     4.3 @@ -171,7 +171,6 @@ XenNet_SumPacketData(
     4.4    PUSHORT csum_ptr;
     4.5    USHORT remaining;
     4.6    USHORT ip4_length;
     4.7 -ULONG seq;
     4.8  
     4.9  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    4.10  
    4.11 @@ -209,7 +208,6 @@ ULONG seq;
    4.12    csum += GET_NET_USHORT(buffer[XN_HDR_SIZE + 16]) + GET_NET_USHORT(buffer[XN_HDR_SIZE + 18]); // dst
    4.13    csum += ((USHORT)buffer[XN_HDR_SIZE + 9]);
    4.14  
    4.15 -seq = GET_NET_ULONG(buffer[XN_HDR_SIZE + pi->ip4_header_length + 4]);
    4.16    remaining = ip4_length - pi->ip4_header_length;
    4.17  
    4.18    csum += remaining;
    4.19 @@ -226,7 +224,6 @@ seq = GET_NET_ULONG(buffer[XN_HDR_SIZE +
    4.20          return;
    4.21        }
    4.22        NdisQueryBufferSafe(mdl, &buffer, &buffer_length, NormalPagePriority);
    4.23 -//KdPrint((__DRIVER_NAME "     New buffer - unaligned... seq = %x\n", seq));
    4.24        csum += ((USHORT)buffer[0]);
    4.25        buffer_offset = (USHORT)-1;
    4.26      }
    4.27 @@ -249,7 +246,6 @@ seq = GET_NET_ULONG(buffer[XN_HDR_SIZE +
    4.28    }
    4.29    if (i != total_length) // last odd byte
    4.30    {
    4.31 -//    KdPrint((__DRIVER_NAME "     odd final byte... seq = %x\n", seq));
    4.32      csum += ((USHORT)buffer[buffer_offset] << 8);
    4.33    }
    4.34    while (csum & 0xFFFF0000)
    4.35 @@ -261,6 +257,8 @@ seq = GET_NET_ULONG(buffer[XN_HDR_SIZE +
    4.36  //  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    4.37  }
    4.38  
    4.39 +static ULONG debug_length;
    4.40 +
    4.41  static PNDIS_PACKET
    4.42  XenNet_MakePacket(
    4.43    struct xennet_info *xi
    4.44 @@ -328,7 +326,6 @@ XenNet_MakePackets(
    4.45  )
    4.46  {
    4.47    USHORT i;
    4.48 -  int pc;
    4.49  
    4.50  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "(packets = %p, packet_count = %d)\n", packets, *packet_count_p));
    4.51  
    4.52 @@ -344,12 +341,10 @@ XenNet_MakePackets(
    4.53      if (xi->rxpi.csum_calc_required)
    4.54        XenNet_SumPacketData(&xi->rxpi, packets[*packet_count_p]);
    4.55      (*packet_count_p)++;
    4.56 -//    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ " (TCP/UDP)\n"));
    4.57      return;
    4.58    default:
    4.59      packets[*packet_count_p] = XenNet_MakePacket(xi);
    4.60      (*packet_count_p)++;
    4.61 -//    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ " (Other)\n"));
    4.62      return;
    4.63    }
    4.64  //  KdPrint((__DRIVER_NAME "     splitting packet\n"));
    4.65 @@ -359,18 +354,13 @@ XenNet_MakePackets(
    4.66    else
    4.67      xi->rxpi.curr_mdl = 1;
    4.68  
    4.69 -pc = 0;
    4.70    while (xi->rxpi.tcp_remaining)
    4.71    {
    4.72 -//    KdPrint((__DRIVER_NAME "     tcp_remaining = %d\n", xi->rxpi.tcp_remaining));
    4.73      packets[*packet_count_p] = XenNet_MakePacket(xi);
    4.74      XenNet_SumPacketData(&xi->rxpi, packets[*packet_count_p]);
    4.75      (*packet_count_p)++;
    4.76 -pc++;
    4.77    }
    4.78    ASSERT(xi->rxpi.curr_mdl == xi->rxpi.mdl_count);
    4.79 -//KdPrint((__DRIVER_NAME "     split %d bytes into %d packets\n", xi->rxpi.tcp_length, pc));
    4.80 -//  KdPrint((__DRIVER_NAME "     tcp_remaining = %d\n", xi->rxpi.tcp_remaining));
    4.81    // TODO: restore psh status to last packet
    4.82    for (i = 0; i < xi->rxpi.mdl_count; i++)
    4.83    {
    4.84 @@ -574,7 +564,7 @@ XenNet_RxTimer(
    4.85  
    4.86    KeAcquireSpinLockAtDpcLevel(&xi->rx_lock);
    4.87  
    4.88 -  KdPrint((__DRIVER_NAME " --- rx_timer - lowest = %d\n", xi->rx_page_free_lowest));
    4.89 +//  KdPrint((__DRIVER_NAME " --- rx_timer - lowest = %d\n", xi->rx_page_free_lowest));
    4.90  
    4.91    if (xi->rx_page_free_lowest > max(RX_DFL_MIN_TARGET / 4, 16)) // lots of potential for tuning here
    4.92    {
    4.93 @@ -585,6 +575,7 @@ XenNet_RxTimer(
    4.94          *(grant_ref_t *)(((UCHAR *)mdl) + MmSizeOfMdl(0, PAGE_SIZE)), 0);
    4.95        FreePages(mdl);
    4.96      }
    4.97 +    KdPrint((__DRIVER_NAME " --- rx_timer - freed %d pages\n", i));
    4.98    }
    4.99  
   4.100    xi->rx_page_free_lowest = xi->rx_page_free;
   4.101 @@ -652,8 +643,15 @@ XenNet_RxInit(xennet_info_t *xi)
   4.102  BOOLEAN
   4.103  XenNet_RxShutdown(xennet_info_t *xi)
   4.104  {
   4.105 +  KIRQL OldIrql;
   4.106 +  BOOLEAN TimerCancelled;
   4.107 +
   4.108    KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   4.109  
   4.110 +  KeAcquireSpinLock(&xi->rx_lock, &OldIrql);
   4.111 +  NdisMCancelTimer(&xi->rx_timer, &TimerCancelled);
   4.112 +  KeReleaseSpinLock(&xi->rx_lock, OldIrql);
   4.113 +
   4.114    XenNet_RxBufferFree(xi);
   4.115  
   4.116    free_page_freelist(xi);
     5.1 --- a/xennet/xennet_tx.c	Thu Apr 10 20:43:45 2008 +1000
     5.2 +++ b/xennet/xennet_tx.c	Tue Apr 15 23:36:10 2008 +1000
     5.3 @@ -250,12 +250,13 @@ XenNet_HWSendPacket(struct xennet_info *
     5.4  
     5.5    pi.mdls[0] = buffer;
     5.6    pi.mdl_count = 1;
     5.7 -  // only if csum offload
     5.8 +  // only if some offload function is in use
     5.9    if ((csum_info->Transmit.NdisPacketTcpChecksum
    5.10      || csum_info->Transmit.NdisPacketUdpChecksum
    5.11      || mss > 0)
    5.12      && XenNet_ParsePacketHeader(&pi) == PARSE_TOO_SMALL)
    5.13    {
    5.14 +KdPrint((__DRIVER_NAME "     Split header - merging\n"));
    5.15      pi.mdls[0] = merged_buffer = get_page_from_freelist(xi);
    5.16      address = MmGetMdlVirtualAddress(pi.mdls[0]);
    5.17      memcpy(address, MmGetSystemAddressForMdlSafe(buffer, NormalPagePriority), MmGetMdlByteCount(buffer));
    5.18 @@ -268,8 +269,11 @@ XenNet_HWSendPacket(struct xennet_info *
    5.19        memcpy(&address[length], MmGetSystemAddressForMdlSafe(buffer, NormalPagePriority), MmGetMdlByteCount(buffer));
    5.20        length += MmGetMdlByteCount(buffer);
    5.21        NdisAdjustBufferLength(pi.mdls[0], length); /* do this here so that ParsePacketHeader works */
    5.22 +KdPrint((__DRIVER_NAME "     length = %d\n", length));
    5.23      }
    5.24    }
    5.25 +  if (mss > 0 && mss < pi.tcp_length)
    5.26 +    mss = 0;
    5.27    ASSERT(buffer != NULL);
    5.28    NdisGetNextBuffer(buffer, &buffer);
    5.29    while (buffer != NULL)
    5.30 @@ -283,7 +287,12 @@ XenNet_HWSendPacket(struct xennet_info *
    5.31    XenNet_BuildPageList(&pi, elements, &num_elements);
    5.32  
    5.33    if (num_elements + !!mss > (int)free_requests(xi))
    5.34 +  {
    5.35 +    KdPrint((__DRIVER_NAME "     Full on send - required = %d, available = %d\n", num_elements + !!mss, (int)free_requests(xi)));
    5.36 +    if (merged_buffer)
    5.37 +      FreePages(merged_buffer);
    5.38      return FALSE;
    5.39 +  }
    5.40  
    5.41    if (csum_info->Transmit.NdisPacketTcpChecksum
    5.42      || csum_info->Transmit.NdisPacketUdpChecksum)
    5.43 @@ -294,7 +303,9 @@ XenNet_HWSendPacket(struct xennet_info *
    5.44  
    5.45    if (mss > 0)
    5.46    {
    5.47 -    flags |= NETTXF_extra_info;
    5.48 +    if (!csum_info->Transmit.NdisPacketTcpChecksum)
    5.49 +      KdPrint((__DRIVER_NAME "     strange... mss set but checksum offload not set\n"));
    5.50 +    flags |= NETTXF_extra_info | NETTXF_csum_blank | NETTXF_data_validated;
    5.51      XenNet_SumIpHeader(MmGetSystemAddressForMdlSafe(pi.mdls[0], NormalPagePriority), pi.ip4_header_length);
    5.52      PC_INC(ProfCount_TxPacketsLargeOffload);
    5.53    }
    5.54 @@ -325,21 +336,36 @@ XenNet_HWSendPacket(struct xennet_info *
    5.55    /* (C) */
    5.56    for (element_num = 1; element_num < num_elements; element_num++)
    5.57    {
    5.58 -//if (csum_info->Transmit.NdisPacketTcpChecksum || csum_info->Transmit.NdisPacketUdpChecksum)
    5.59 -//KdPrint((__DRIVER_NAME "                   - size = %d, pfn = %08x, offset = %04x\n", elements[element_num].length, elements[element_num].pfn, elements[element_num].offset));
    5.60 -    //KdPrint((__DRIVER_NAME "     i = %d\n", i));
    5.61      tx = XenNet_PutOnTxRing(xi, elements[element_num].pfn,
    5.62        elements[element_num].offset, elements[element_num].length,
    5.63        NETTXF_more_data);
    5.64      xi->tx.req_prod_pvt++;
    5.65    }
    5.66  
    5.67 +for (element_num = 0, length = 0; element_num < num_elements; element_num++)
    5.68 +{
    5.69 +  if (elements[element_num].length == 0 || elements[element_num].pfn == 0)
    5.70 +    KdPrint((__DRIVER_NAME "     strange page length = %d, pfn = %08x, offset = %04x\n", elements[element_num].length, elements[element_num].pfn, elements[element_num].offset));
    5.71 +  length += elements[element_num].length;
    5.72 +}
    5.73 +if (length != total_packet_length) {
    5.74 +  KdPrint((__DRIVER_NAME "     length (%d) != total_packet_length (%d)\n", length, total_packet_length));
    5.75 +}
    5.76 +
    5.77 +
    5.78    /* only set the packet on the last buffer, clear more_data */
    5.79    ASSERT(tx);
    5.80    xi->tx_pkts[tx->id] = packet;
    5.81    xi->tx_mdls[tx->id] = merged_buffer;
    5.82    tx->flags &= ~NETTXF_more_data;
    5.83  
    5.84 +  if (mss)
    5.85 +  {
    5.86 +    NDIS_PER_PACKET_INFO_FROM_PACKET(packet, TcpLargeSendPacketInfo) = UlongToPtr(pi.tcp_length);
    5.87 +  }
    5.88 +
    5.89 +  xi->tx_outstanding++;
    5.90 +
    5.91    return TRUE;
    5.92  }
    5.93  
    5.94 @@ -371,7 +397,10 @@ XenNet_SendQueuedPackets(struct xennet_i
    5.95      packet = CONTAINING_RECORD(entry, NDIS_PACKET, MiniportReservedEx[sizeof(PVOID)]);
    5.96      success = XenNet_HWSendPacket(xi, packet);
    5.97      if (!success)
    5.98 +    {
    5.99 +      InsertHeadList(&xi->tx_waiting_pkt_list, entry);
   5.100        break;
   5.101 +    }
   5.102      entry = RemoveHeadList(&xi->tx_waiting_pkt_list);
   5.103    }
   5.104  
   5.105 @@ -398,7 +427,6 @@ XenNet_TxBufferGC(struct xennet_info *xi
   5.106    ULONG packet_count = 0;
   5.107    int moretodo;
   5.108    ULONG i;
   5.109 -  UINT total_packet_length;
   5.110    int cycles = 0;
   5.111  #if defined(XEN_PROFILE)
   5.112    LARGE_INTEGER tsc, dummy;
   5.113 @@ -438,12 +466,6 @@ XenNet_TxBufferGC(struct xennet_info *xi
   5.114        packets[packet_count] = xi->tx_pkts[id];
   5.115        if (packets[packet_count])
   5.116        {
   5.117 -        NdisQueryPacket(packets[packet_count], NULL, NULL, NULL, &total_packet_length);
   5.118 -        if (NDIS_PER_PACKET_INFO_FROM_PACKET(packets[packet_count], TcpLargeSendPacketInfo) != 0)
   5.119 -        {
   5.120 -          NDIS_PER_PACKET_INFO_FROM_PACKET(packets[packet_count], TcpLargeSendPacketInfo) = UlongToPtr(total_packet_length);
   5.121 -//KdPrint((__DRIVER_NAME "     Large Send Response = %d\n", NDIS_PER_PACKET_INFO_FROM_PACKET(packets[packet_count], TcpLargeSendPacketInfo)));
   5.122 -        }
   5.123          xi->tx_pkts[id] = NULL;
   5.124          packet_count++;
   5.125          xi->stat_tx_ok++;
   5.126 @@ -518,7 +540,6 @@ XenNet_SendPackets(
   5.127      *(ULONG *)&packet->MiniportReservedEx = 0;
   5.128      entry = (PLIST_ENTRY)&packet->MiniportReservedEx[sizeof(PVOID)];
   5.129      InsertTailList(&xi->tx_waiting_pkt_list, entry);
   5.130 -    xi->tx_outstanding++;
   5.131  #if defined(XEN_PROFILE)
   5.132      ProfCount_PacketsPerSendPackets++;
   5.133  #endif
   5.134 @@ -573,7 +594,9 @@ XenNet_TxTimer(
   5.135  
   5.136    KeAcquireSpinLockAtDpcLevel(&xi->tx_lock);
   5.137  
   5.138 -  KdPrint((__DRIVER_NAME " --- tx_timer - lowest = %d\n", xi->tx_page_free_lowest));
   5.139 +//  KdPrint((__DRIVER_NAME " --- tx_timer - lowest = %d\n", xi->tx_page_free_lowest));
   5.140 +
   5.141 +  KdPrint((__DRIVER_NAME " --- tx_outstanding = %d\n", xi->tx_outstanding));
   5.142  
   5.143  #if 0
   5.144    if (xi->tx_page_free_lowest > max(RX_DFL_MIN_TARGET / 4, 16)) // lots of potential for tuning here
   5.145 @@ -666,12 +689,24 @@ XenNet_TxShutdown(xennet_info_t *xi)
   5.146    KIRQL OldIrql;
   5.147    ULONG i;
   5.148    LARGE_INTEGER Interval;
   5.149 +  BOOLEAN TimerCancelled;
   5.150  
   5.151    KeAcquireSpinLock(&xi->tx_lock, &OldIrql);
   5.152 -  NdisMSetPeriodicTimer(&xi->tx_timer, 1000);
   5.153 +
   5.154 +  NdisMCancelTimer(&xi->tx_timer, &TimerCancelled);
   5.155 +
   5.156 +  XenNet_TxBufferFree(xi);
   5.157 +
   5.158    KeReleaseSpinLock(&xi->tx_lock, OldIrql);
   5.159  
   5.160 -  XenNet_TxBufferFree(xi);
   5.161 +  KdPrint((__DRIVER_NAME "     Waiting for tx_outstanding\n"));
   5.162 +  while (xi->tx_outstanding)
   5.163 +  {
   5.164 +    KdPrint((__DRIVER_NAME "     tx_outstanding = %d\n", xi->tx_outstanding));
   5.165 +    Interval.QuadPart = -10000000;
   5.166 +    KeDelayExecutionThread(KernelMode, FALSE, &Interval);
   5.167 +  }
   5.168 +  KdPrint((__DRIVER_NAME "     Done\n"));
   5.169  
   5.170    /* free TX resources */
   5.171    if (xi->XenInterface.GntTbl_EndAccess(
   5.172 @@ -686,18 +721,6 @@ XenNet_TxShutdown(xennet_info_t *xi)
   5.173  
   5.174    free_page_freelist(xi);
   5.175  
   5.176 -  /* I think that NDIS takes care of this for us... */
   5.177 -  /* no it doesn't - this needs handling properly */
   5.178 -  
   5.179 -  KdPrint((__DRIVER_NAME "     Waiting for tx_outstanding\n"));
   5.180 -  while (xi->tx_outstanding)
   5.181 -  {
   5.182 -    KdPrint((__DRIVER_NAME "     tx_outstanding = %d\n", xi->tx_outstanding));
   5.183 -    Interval.QuadPart = -1000000;
   5.184 -    KeDelayExecutionThread(KernelMode, FALSE, &Interval);
   5.185 -  }
   5.186 -  KdPrint((__DRIVER_NAME "     Done\n"));
   5.187 -
   5.188    ASSERT(xi->tx_outstanding == 0);
   5.189  
   5.190    for (i = 0; i < NET_TX_RING_SIZE; i++)