win-pvdrivers

changeset 139:00e9b5835d28

Very rough 'packet recycling' code to prevent having to allocate memory in dpc. Still crashes on unload, but for a different reason.
author James Harper <james.harper@bendigoit.com.au>
date Mon Jan 21 23:23:23 2008 +1100 (2008-01-21)
parents 7ff0dd6ba883
children 76a661426861
files common/include/xen_public.h xenenum/sources xenenum/xenenum.c xennet/sources xennet/xennet.c xennet/xennet.h xenpci/sources xenvbd/sources
line diff
     1.1 --- a/common/include/xen_public.h	Sun Jan 20 22:57:30 2008 +1100
     1.2 +++ b/common/include/xen_public.h	Mon Jan 21 23:23:23 2008 +1100
     1.3 @@ -109,6 +109,7 @@ typedef struct _XEN_IFACE {
     1.4    PXEN_XENBUS_ADDWATCH XenBus_AddWatch;
     1.5    PXEN_XENBUS_REMWATCH XenBus_RemWatch;
     1.6  
     1.7 +  PVOID tmp;
     1.8  } XEN_IFACE, *PXEN_IFACE;
     1.9  
    1.10  #define XEN_DATA_MAGIC 0x12345678
     2.1 --- a/xenenum/sources	Sun Jan 20 22:57:30 2008 +1100
     2.2 +++ b/xenenum/sources	Mon Jan 21 23:23:23 2008 +1100
     2.3 @@ -1,7 +1,7 @@
     2.4  TARGETNAME=xenenum
     2.5  TARGETTYPE=DRIVER
     2.6  TARGETPATH=..\Target\$(DDK_TARGET_OS)
     2.7 -VERSION=0.5.0.14
     2.8 +VERSION=0.5.0.20
     2.9  KMDF_VERSION=1
    2.10  MSC_WARNING_LEVEL=/W4
    2.11  INF_NAME=xenenum
     3.1 --- a/xenenum/xenenum.c	Sun Jan 20 22:57:30 2008 +1100
     3.2 +++ b/xenenum/xenenum.c	Mon Jan 21 23:23:23 2008 +1100
     3.3 @@ -510,8 +510,6 @@ XenEnum_ChildListCreateDevice(WDFCHILDLI
     3.4    ChildDeviceData->AutoEnumerate = AutoEnumerate;
     3.5    ChildDeviceData->WatchHandler = NULL;
     3.6    strncpy(ChildDeviceData->Path, XenIdentificationDesc->Path, 128);
     3.7 -//  memcpy(&ChildDeviceData->InterruptRaw, &InterruptRaw, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
     3.8 -//  memcpy(&ChildDeviceData->InterruptTranslated, &InterruptTranslated, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
     3.9    
    3.10    ChildDeviceData->XenInterface.InterfaceHeader.Size = sizeof(ChildDeviceData->XenInterface);
    3.11    ChildDeviceData->XenInterface.InterfaceHeader.Version = 1;
    3.12 @@ -542,6 +540,8 @@ XenEnum_ChildListCreateDevice(WDFCHILDLI
    3.13    ChildDeviceData->XenInterface.XenBus_AddWatch = XenInterface.XenBus_AddWatch;
    3.14    ChildDeviceData->XenInterface.XenBus_RemWatch = XenInterface.XenBus_RemWatch;
    3.15  
    3.16 +  ChildDeviceData->XenInterface.tmp = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, 0x66606660);
    3.17 +
    3.18    WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&ChildDeviceData->XenInterface, &GUID_XEN_IFACE, NULL);
    3.19    status = WdfDeviceAddQueryInterface(ChildDevice, &qiConfig);
    3.20    if (!NT_SUCCESS(status)) {
     4.1 --- a/xennet/sources	Sun Jan 20 22:57:30 2008 +1100
     4.2 +++ b/xennet/sources	Mon Jan 21 23:23:23 2008 +1100
     4.3 @@ -1,7 +1,7 @@
     4.4  TARGETNAME=XENNET
     4.5  TARGETTYPE=DRIVER
     4.6  TARGETPATH=..\Target\$(DDK_TARGET_OS)
     4.7 -VERSION=0.5.0.142
     4.8 +VERSION=0.5.0.174
     4.9  KMDF_VERSION=1
    4.10  MSC_WARNING_LEVEL=/W4
    4.11  INF_NAME=xennet
     5.1 --- a/xennet/xennet.c	Sun Jan 20 22:57:30 2008 +1100
     5.2 +++ b/xennet/xennet.c	Mon Jan 21 23:23:23 2008 +1100
     5.3 @@ -43,6 +43,13 @@ Foundation, Inc., 51 Franklin Street, Fi
     5.4  
     5.5  #pragma warning(disable: 4127) // conditional expression is constant
     5.6  
     5.7 +struct _buffer_entry
     5.8 +{
     5.9 +  char data[PAGE_SIZE - sizeof(LIST_ENTRY) - sizeof(PNDIS_BUFFER)];
    5.10 +  LIST_ENTRY entry;
    5.11 +  PNDIS_BUFFER buffer;
    5.12 +} typedef buffer_entry_t;
    5.13 +
    5.14  struct xennet_info
    5.15  {
    5.16    /* Base device vars */
    5.17 @@ -76,6 +83,7 @@ struct xennet_info
    5.18    KSPIN_LOCK tx_lock;
    5.19  
    5.20    LIST_ENTRY tx_waiting_pkt_list;
    5.21 +  LIST_ENTRY rx_free_buf_list;
    5.22    LIST_ENTRY rx_free_pkt_list;
    5.23  
    5.24    struct netif_tx_front_ring tx;
    5.25 @@ -225,7 +233,6 @@ XenNet_TxBufferGC(struct xennet_info *xi
    5.26  MdlAlloc--;
    5.27        NdisFreeMemory(ptr, 0, 0); // <= DISPATCH_LEVEL
    5.28  NdisAlloc--;
    5.29 -
    5.30        InterlockedDecrement(&xi->tx_outstanding);
    5.31        xi->stat_tx_ok++;
    5.32        NdisMSendComplete(xi->adapter_handle, pkt, NDIS_STATUS_SUCCESS);
    5.33 @@ -279,7 +286,7 @@ XenNet_TxBufferFree(struct xennet_info *
    5.34  KdPrint((__DRIVER_NAME " --- TxBufferFree %p\n", ptr));
    5.35      IoFreeMdl(pmdl);
    5.36  MdlAlloc--;
    5.37 -    NdisFreeMemory(ptr, 0, 0); // <= DISPATCH_LEVEL
    5.38 +      NdisFreeMemory(ptr, 0, 0); // <= DISPATCH_LEVEL
    5.39  NdisAlloc--;
    5.40  
    5.41      NdisMSendComplete(xi->adapter_handle, packet, NDIS_STATUS_FAILURE);
    5.42 @@ -304,7 +311,7 @@ NdisAlloc--;
    5.43  KdPrint((__DRIVER_NAME " --- TxBufferFree %p\n", ptr));
    5.44      IoFreeMdl(pmdl);
    5.45  MdlAlloc--;
    5.46 -    NdisFreeMemory(ptr, 0, 0); // <= DISPATCH_LEVEL
    5.47 +      NdisFreeMemory(ptr, 0, 0); // <= DISPATCH_LEVEL
    5.48  NdisAlloc--;
    5.49  
    5.50      NdisMSendComplete(xi->adapter_handle, packet, NDIS_STATUS_FAILURE);
    5.51 @@ -321,34 +328,29 @@ XenNet_RxBufferAlloc(struct xennet_info 
    5.52    RING_IDX req_prod = xi->rx.req_prod_pvt;
    5.53    grant_ref_t ref;
    5.54    netif_rx_request_t *req;
    5.55 -  NDIS_STATUS status;
    5.56 -  PVOID start;
    5.57 +//  NDIS_STATUS status;
    5.58 +//  PVOID start;
    5.59    KIRQL OldIrql;
    5.60 +  PLIST_ENTRY entry;
    5.61  
    5.62 -//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    5.63 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    5.64  
    5.65    KeAcquireSpinLock(&xi->rx_lock, &OldIrql);
    5.66  
    5.67    batch_target = xi->rx_target - (req_prod - xi->rx.rsp_cons);
    5.68    for (i = 0; i < batch_target; i++)
    5.69    {
    5.70 -    /*
    5.71 -     * Allocate memory and an NDIS_BUFFER.
    5.72 -     */
    5.73 -    status = NdisAllocateMemoryWithTag(&start, PAGE_SIZE, XENNET_POOL_TAG);
    5.74 -NdisAlloc++;
    5.75 -    if (status != NDIS_STATUS_SUCCESS)
    5.76 -    {
    5.77 -      KdPrint(("NdisAllocateMemoryWithTag Failed! status = 0x%x\n", status));
    5.78 +    entry = RemoveHeadList(&xi->rx_free_buf_list);
    5.79 +KdPrint((__DRIVER_NAME "     A - %08x\n", entry));
    5.80 +    if (entry == &xi->rx_free_buf_list)
    5.81        break;
    5.82 -    }
    5.83 -    NdisAllocateBuffer(&status, &buffer, xi->buffer_pool, start, PAGE_SIZE);
    5.84 -BufferAlloc++;
    5.85 -    ASSERT(status == NDIS_STATUS_SUCCESS); // should never fail
    5.86 -
    5.87 +    buffer = CONTAINING_RECORD(entry, buffer_entry_t, entry)->buffer;
    5.88 +KdPrint((__DRIVER_NAME "     B - %08x\n", buffer));
    5.89 +    
    5.90      /* Give to netback */
    5.91      id = (unsigned short)(req_prod + i) & (NET_RX_RING_SIZE - 1);
    5.92      ASSERT(!xi->rx_buffers[id]);
    5.93 +KdPrint(("Putting id = %d on ring\n", id));
    5.94      xi->rx_buffers[id] = buffer;
    5.95      req = RING_GET_REQUEST(&xi->rx, req_prod + i);
    5.96      /* an NDIS_BUFFER is just a MDL, so we can get its pfn array */
    5.97 @@ -372,7 +374,7 @@ BufferAlloc++;
    5.98  
    5.99    KeReleaseSpinLock(&xi->rx_lock, OldIrql);
   5.100  
   5.101 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   5.102 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   5.103  
   5.104    return NDIS_STATUS_SUCCESS;
   5.105  }
   5.106 @@ -384,8 +386,10 @@ XenNet_RxBufferFree(struct xennet_info *
   5.107    int i;
   5.108    grant_ref_t ref;
   5.109    PNDIS_BUFFER buffer;
   5.110 +  PNDIS_PACKET packet;
   5.111    KIRQL OldIrql;
   5.112    PVOID buff_va;
   5.113 +  PLIST_ENTRY entry;
   5.114  
   5.115    ASSERT(!xi->connected);
   5.116  
   5.117 @@ -402,13 +406,30 @@ XenNet_RxBufferFree(struct xennet_info *
   5.118      /* don't check return, what can we do about it on failure? */
   5.119      xi->XenInterface.GntTbl_EndAccess(xi->XenInterface.InterfaceHeader.Context, ref);
   5.120  
   5.121 -    NdisAdjustBufferLength(buffer, PAGE_SIZE);
   5.122 +    NdisAdjustBufferLength(buffer, sizeof(buffer_entry_t));
   5.123      buff_va = NdisBufferVirtualAddressSafe(buffer, NormalPagePriority);
   5.124      NdisFreeBuffer(buffer);
   5.125 -BufferAlloc--;
   5.126 -KdPrint((__DRIVER_NAME " --- RxBufferFree %p\n", buff_va));
   5.127 -    NdisFreeMemory(buff_va, 0, 0);
   5.128 -NdisAlloc--;
   5.129 +    BufferAlloc--;
   5.130 +    NdisFreeMemory(buff_va, 0, 0); // <= DISPATCH_LEVEL
   5.131 +    NdisAlloc--;
   5.132 +  }
   5.133 +
   5.134 +  while ((entry = RemoveHeadList(&xi->rx_free_buf_list)) != &xi->rx_free_buf_list)
   5.135 +  {
   5.136 +    buffer = (PNDIS_BUFFER)CONTAINING_RECORD(entry, buffer_entry_t, entry);
   5.137 +    NdisAdjustBufferLength(buffer, sizeof(buffer_entry_t));
   5.138 +    buff_va = NdisBufferVirtualAddressSafe(buffer, NormalPagePriority);
   5.139 +    NdisFreeBuffer(buffer);
   5.140 +    BufferAlloc--;
   5.141 +    NdisFreeMemory(buff_va, 0, 0); // <= DISPATCH_LEVEL
   5.142 +    NdisAlloc--;
   5.143 +  }
   5.144 +
   5.145 +  while ((entry = RemoveHeadList(&xi->rx_free_pkt_list)) != &xi->rx_free_pkt_list)
   5.146 +  {
   5.147 +    packet = CONTAINING_RECORD(entry, NDIS_PACKET, MiniportReservedEx[sizeof(PVOID)]);
   5.148 +    NdisFreePacket(packet);
   5.149 +    PacketAlloc--;
   5.150    }
   5.151  
   5.152    KeReleaseSpinLock(&xi->rx_lock, OldIrql);
   5.153 @@ -422,40 +443,45 @@ XenNet_ReturnPacket(
   5.154  {
   5.155    struct xennet_info *xi = MiniportAdapterContext;
   5.156    PNDIS_BUFFER buffer;
   5.157 -  PNDIS_BUFFER next_buffer;
   5.158 +//  PNDIS_BUFFER next_buffer;
   5.159    PVOID buff_va;
   5.160    UINT buff_len;
   5.161    UINT tot_buff_len;
   5.162 -
   5.163 -//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   5.164 +  buffer_entry_t *buffer_entry;
   5.165 +//  KIRQL OldIrql;
   5.166  
   5.167 -  NdisGetFirstBufferFromPacketSafe(Packet, &buffer, &buff_va, &buff_len,
   5.168 -    &tot_buff_len, NormalPagePriority);
   5.169 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   5.170 +
   5.171 +  NdisQueryPacketLength(Packet, &tot_buff_len);
   5.172 +//  NdisGetFirstBufferFromPacketSafe(Packet, &buffer, &buff_va, &buff_len,
   5.173 +//    &tot_buff_len, NormalPagePriority);
   5.174 +  KdPrint((__DRIVER_NAME " Packet = %08x, tot_buff_len = %d, XN_MAX_PKT_SIZE = %d\n", Packet, tot_buff_len, XN_MAX_PKT_SIZE));
   5.175    ASSERT(tot_buff_len <= XN_MAX_PKT_SIZE);
   5.176 -  ASSERT(buff_va != NULL);
   5.177 +//  ASSERT(buff_va != NULL);
   5.178  
   5.179 +  NdisUnchainBufferAtBack(Packet, &buffer);
   5.180    while (buffer)
   5.181    {
   5.182 -    NdisGetNextBuffer(buffer, &next_buffer);
   5.183 -    NdisAdjustBufferLength(buffer, PAGE_SIZE);
   5.184 -    buff_va = NdisBufferVirtualAddressSafe(buffer, NormalPagePriority);
   5.185 -    NdisFreeBuffer(buffer);
   5.186 -BufferAlloc--;
   5.187 -    NdisFreeMemory(buff_va, 0, 0);
   5.188 -NdisAlloc--;
   5.189 -    buffer = next_buffer;
   5.190 +    NdisAdjustBufferLength(buffer, sizeof(buffer_entry_t));
   5.191 +    buffer_entry = NdisBufferVirtualAddressSafe(buffer, NormalPagePriority);
   5.192 +//    KeAcquireSpinLock(&xi->rx_lock, &OldIrql);
   5.193 +    InsertTailList(&xi->rx_free_buf_list, &buffer_entry->entry);
   5.194 +//    KeReleaseSpinLock(&xi->rx_lock, OldIrql);
   5.195 +    NdisUnchainBufferAtBack(Packet, &buffer);
   5.196    }
   5.197  
   5.198 -  NdisFreePacket(Packet);
   5.199 -PacketAlloc--;
   5.200 -
   5.201 +  NdisReinitializePacket(Packet);
   5.202 +//  KeAcquireSpinLock(&xi->rx_lock, &OldIrql);
   5.203 +  InsertTailList(&xi->rx_free_pkt_list, (PLIST_ENTRY)&Packet->MiniportReservedEx[sizeof(PVOID)]);
   5.204 +//  KeReleaseSpinLock(&xi->rx_lock, OldIrql);
   5.205 +  
   5.206    InterlockedDecrement(&xi->rx_outstanding);
   5.207  
   5.208 -  // if we are no longer connected then _halt probably needs to know when rx_outstanding reaches zero
   5.209 +  // if we are no longer connected then _halt needs to know when rx_outstanding reaches zero
   5.210    if (!xi->connected && !xi->rx_outstanding)
   5.211      KeSetEvent(&xi->shutdown_event, 1, FALSE);  
   5.212  
   5.213 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   5.214 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   5.215  }
   5.216  
   5.217  // Called at DISPATCH_LEVEL
   5.218 @@ -463,16 +489,16 @@ static NDIS_STATUS
   5.219  XenNet_RxBufferCheck(struct xennet_info *xi)
   5.220  {
   5.221    RING_IDX cons, prod;
   5.222 -
   5.223 +  PLIST_ENTRY entry;
   5.224    PNDIS_PACKET packet = NULL;
   5.225    PNDIS_BUFFER buffer;
   5.226    int moretodo;
   5.227    KIRQL OldIrql;
   5.228    struct netif_rx_response *rxrsp = NULL;
   5.229    int more_frags = 0;
   5.230 -  NDIS_STATUS status;
   5.231 +  UINT length;
   5.232  
   5.233 -//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   5.234 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   5.235  
   5.236    ASSERT(xi->connected);
   5.237  
   5.238 @@ -488,17 +514,22 @@ XenNet_RxBufferCheck(struct xennet_info 
   5.239  
   5.240        if (!more_frags) // handling the packet's 1st buffer
   5.241        {
   5.242 -        //  KdPrint((__DRIVER_NAME "     Got a packet\n"));
   5.243 -        NdisAllocatePacket(&status, &packet, xi->packet_pool);
   5.244 -PacketAlloc++;
   5.245 -        ASSERT(status == NDIS_STATUS_SUCCESS);
   5.246 +        entry = RemoveHeadList(&xi->rx_free_pkt_list);
   5.247 +        ASSERT(entry != &xi->rx_free_pkt_list);
   5.248 +        packet = CONTAINING_RECORD(entry, NDIS_PACKET, MiniportReservedEx[sizeof(PVOID)]);
   5.249          NDIS_SET_PACKET_HEADER_SIZE(packet, XN_HDR_SIZE);
   5.250 +        KdPrint((__DRIVER_NAME " New Packet = %08x\n", packet));
   5.251 +        NdisQueryPacketLength(packet, &length);
   5.252 +        KdPrint((__DRIVER_NAME " Length = %d\n", length));
   5.253        }
   5.254  
   5.255        buffer = xi->rx_buffers[rxrsp->id];
   5.256        xi->rx_buffers[rxrsp->id] = NULL;
   5.257        NdisAdjustBufferLength(buffer, rxrsp->status);
   5.258        NdisChainBufferAtBack(packet, buffer);
   5.259 +      KdPrint((__DRIVER_NAME " Appended %d bytes\n", rxrsp->status));
   5.260 +      NdisQueryPacketLength(packet, &length);
   5.261 +      KdPrint((__DRIVER_NAME " Length = %d\n", length));
   5.262  
   5.263        xi->XenInterface.GntTbl_EndAccess(xi->XenInterface.InterfaceHeader.Context,
   5.264          xi->grant_rx_ref[rxrsp->id]);
   5.265 @@ -529,20 +560,18 @@ PacketAlloc++;
   5.266      RING_FINAL_CHECK_FOR_RESPONSES(&xi->rx, moretodo);
   5.267    } while (moretodo);
   5.268  
   5.269 +  KeReleaseSpinLock(&xi->rx_lock, OldIrql);
   5.270 +
   5.271    if (more_frags)
   5.272    {
   5.273      KdPrint((__DRIVER_NAME "     Missing fragments\n"));
   5.274      XenNet_ReturnPacket(xi, packet);
   5.275    }
   5.276  
   5.277 -  KeReleaseSpinLock(&xi->rx_lock, OldIrql);
   5.278 -
   5.279    /* Give netback more buffers */
   5.280    XenNet_RxBufferAlloc(xi);
   5.281  
   5.282 -  //xi->rx.sring->rsp_event = xi->rx.rsp_cons + 1;
   5.283 -
   5.284 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   5.285 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   5.286  
   5.287    return NDIS_STATUS_SUCCESS;
   5.288  }
   5.289 @@ -680,6 +709,10 @@ XenNet_Init(
   5.290    int retry = 0;
   5.291    char *err;
   5.292    xenbus_transaction_t xbt = 0;
   5.293 +  KIRQL OldIrql;
   5.294 +  PNDIS_PACKET packet;
   5.295 +  buffer_entry_t *buffer_entry;
   5.296 +  PLIST_ENTRY entry;
   5.297  
   5.298    UNREFERENCED_PARAMETER(OpenErrorStatus);
   5.299    UNREFERENCED_PARAMETER(WrapperConfigurationContext);
   5.300 @@ -726,10 +759,11 @@ NdisAlloc++;
   5.301    KeInitializeSpinLock(&xi->tx_lock);
   5.302    KeInitializeSpinLock(&xi->rx_lock);
   5.303  
   5.304 +  InitializeListHead(&xi->rx_free_buf_list);
   5.305    InitializeListHead(&xi->rx_free_pkt_list);
   5.306    InitializeListHead(&xi->tx_waiting_pkt_list);
   5.307    
   5.308 -  NdisAllocatePacketPool(&status, &xi->packet_pool, NET_RX_RING_SIZE,
   5.309 +  NdisAllocatePacketPool(&status, &xi->packet_pool, XN_RX_QUEUE_LEN,
   5.310      PROTOCOL_RESERVED_SIZE_IN_PACKET);
   5.311  PacketPoolAlloc++;
   5.312    if (status != NDIS_STATUS_SUCCESS)
   5.313 @@ -740,7 +774,7 @@ PacketPoolAlloc++;
   5.314    }
   5.315    NdisSetPacketPoolProtocolId(xi->packet_pool, NDIS_PROTOCOL_ID_TCP_IP);
   5.316  
   5.317 -  NdisAllocateBufferPool(&status, &xi->buffer_pool, NET_RX_RING_SIZE);
   5.318 +  NdisAllocateBufferPool(&status, &xi->buffer_pool, XN_RX_QUEUE_LEN);
   5.319  BufferPoolAlloc++;
   5.320    if (status != NDIS_STATUS_SUCCESS)
   5.321    {
   5.322 @@ -839,7 +873,7 @@ BufferPoolAlloc++;
   5.323      xi->event_channel, XenNet_Interrupt, xi);
   5.324  
   5.325    xi->tx_mdl = AllocatePage();
   5.326 -PageAlloc++;
   5.327 +  PageAlloc++;
   5.328    xi->tx_pgs = MmGetMdlVirtualAddress(xi->tx_mdl);
   5.329    SHARED_RING_INIT(xi->tx_pgs);
   5.330    FRONT_RING_INIT(&xi->tx, xi->tx_pgs, PAGE_SIZE);
   5.331 @@ -848,7 +882,7 @@ PageAlloc++;
   5.332      *MmGetMdlPfnArray(xi->tx_mdl), FALSE);
   5.333  
   5.334    xi->rx_mdl = AllocatePage();
   5.335 -PageAlloc++;
   5.336 +  PageAlloc++;
   5.337    xi->rx_pgs = MmGetMdlVirtualAddress(xi->rx_mdl);
   5.338    SHARED_RING_INIT(xi->rx_pgs);
   5.339    FRONT_RING_INIT(&xi->rx, xi->rx_pgs, PAGE_SIZE);
   5.340 @@ -883,7 +917,6 @@ PageAlloc++;
   5.341      status = NDIS_STATUS_FAILURE;
   5.342      goto err;
   5.343    } 
   5.344 -  XenNet_RxBufferAlloc(xi);
   5.345  
   5.346    xi->connected = TRUE;
   5.347  
   5.348 @@ -903,6 +936,41 @@ PageAlloc++;
   5.349  
   5.350    KdPrint((__DRIVER_NAME "     Connected\n"));
   5.351  
   5.352 +  KeAcquireSpinLock(&xi->rx_lock, &OldIrql);
   5.353 +
   5.354 +KdPrint((__DRIVER_NAME "     A\n"));
   5.355 +  for (i = 0; i < XN_RX_QUEUE_LEN; i++)
   5.356 +  {
   5.357 +KdPrint((__DRIVER_NAME "     B - %d\n", sizeof(buffer_entry_t)));
   5.358 +    status = NdisAllocateMemoryWithTag(&buffer_entry, sizeof(buffer_entry_t), XENNET_POOL_TAG);
   5.359 +    NdisAlloc++;
   5.360 +    if (status != NDIS_STATUS_SUCCESS)
   5.361 +    {
   5.362 +      KdPrint(("NdisAllocateMemoryWithTag Failed! status = 0x%x\n", status));
   5.363 +      break;
   5.364 +    }
   5.365 +KdPrint((__DRIVER_NAME "     C - %d\n", sizeof(buffer_entry->data)));
   5.366 +    NdisAllocateBuffer(&status, &buffer_entry->buffer, xi->buffer_pool, buffer_entry, sizeof(buffer_entry->data));
   5.367 +    ASSERT(status == NDIS_STATUS_SUCCESS); // should never fail
   5.368 +    BufferAlloc++;
   5.369 +KdPrint((__DRIVER_NAME "     D\n"));
   5.370 +    
   5.371 +    InsertTailList(&xi->rx_free_buf_list, &buffer_entry->entry);
   5.372 +KdPrint((__DRIVER_NAME "     E\n"));
   5.373 +
   5.374 +    NdisAllocatePacket(&status, &packet, xi->packet_pool);
   5.375 +    PacketAlloc++;
   5.376 +KdPrint((__DRIVER_NAME "     F\n"));
   5.377 +    entry = (PLIST_ENTRY)&packet->MiniportReservedEx[sizeof(PVOID)];
   5.378 +KdPrint((__DRIVER_NAME "     G\n"));
   5.379 +    InsertTailList(&xi->rx_free_pkt_list, entry);
   5.380 +KdPrint((__DRIVER_NAME "     H\n"));
   5.381 +  }
   5.382 +
   5.383 +  KeReleaseSpinLock(&xi->rx_lock, OldIrql);
   5.384 +
   5.385 +  XenNet_RxBufferAlloc(xi);
   5.386 +
   5.387    /* get mac address */
   5.388    RtlStringCbPrintfA(TmpPath, ARRAY_SIZE(TmpPath), "%s/mac", xi->backend_path);
   5.389    xi->XenInterface.XenBus_Read(xi->XenInterface.InterfaceHeader.Context,
   5.390 @@ -1457,13 +1525,14 @@ XenNet_Linearize(PNDIS_PACKET Packet)
   5.391      &tot_buff_len, NormalPagePriority);
   5.392    ASSERT(tot_buff_len <= XN_MAX_PKT_SIZE);
   5.393  
   5.394 -  status = NdisAllocateMemoryWithTag(&start, tot_buff_len, XENNET_POOL_TAG);
   5.395 +  status = NdisAllocateMemoryWithTag(&start, PAGE_SIZE, XENNET_POOL_TAG);
   5.396  NdisAlloc++;
   5.397    if (!NT_SUCCESS(status))
   5.398    {
   5.399      KdPrint(("Could not allocate memory for linearization\n"));
   5.400      return NULL;
   5.401    }
   5.402 +
   5.403    pmdl = IoAllocateMdl(start, tot_buff_len, FALSE, FALSE, NULL);
   5.404    if (!pmdl)
   5.405    {
   5.406 @@ -1514,7 +1583,7 @@ XenNet_SendQueuedPackets(struct xennet_i
   5.407      if (!id)
   5.408      {
   5.409        /* whups, out of space on the ring. requeue and get out */
   5.410 -      InsertTailList(&xi->tx_waiting_pkt_list, entry);
   5.411 +      InsertHeadList(&xi->tx_waiting_pkt_list, entry);
   5.412        break;
   5.413      }
   5.414      xi->tx_pkts[id] = packet;
   5.415 @@ -1674,9 +1743,9 @@ XenNet_Halt(
   5.416        KernelMode, FALSE, NULL);
   5.417  
   5.418    xi->connected = FALSE;
   5.419 -  /* wait for all receive buffers to be returned */
   5.420    KeMemoryBarrier(); /* make sure everyone sees that we are now shut down */
   5.421  
   5.422 +  /* wait for all receive buffers to be returned */
   5.423    while (xi->rx_outstanding > 0)
   5.424      KeWaitForSingleObject(&xi->shutdown_event, Executive, KernelMode, FALSE, NULL);
   5.425  
   5.426 @@ -1749,6 +1818,15 @@ KdPrint((__DRIVER_NAME "     PageAlloc =
   5.427  KdPrint((__DRIVER_NAME "     PacketPoolAlloc = %d\n", PacketPoolAlloc));
   5.428  KdPrint((__DRIVER_NAME "     BufferPoolAlloc = %d\n", BufferPoolAlloc));
   5.429  
   5.430 +
   5.431 +#if 0
   5.432 +  if (xi->XenInterface.tmp != NULL)
   5.433 +  {
   5.434 +KdPrint(("     tmp = 0x%p\n", xi->XenInterface.tmp));
   5.435 +    ExFreePoolWithTag(xi->XenInterface.tmp, 0x66606660);
   5.436 +    xi->XenInterface.tmp = NULL;
   5.437 +  }
   5.438 +#endif
   5.439    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   5.440  }
   5.441  
     6.1 --- a/xennet/xennet.h	Sun Jan 20 22:57:30 2008 +1100
     6.2 +++ b/xennet/xennet.h	Mon Jan 21 23:23:23 2008 +1100
     6.3 @@ -59,6 +59,7 @@ Foundation, Inc., 51 Franklin Street, Fi
     6.4  
     6.5  #define XN_MAX_SEND_PKTS 16
     6.6  
     6.7 +#define XN_RX_QUEUE_LEN 256
     6.8  #define XENSOURCE_MAC_HDR 0x00163E
     6.9  #define XN_VENDOR_DESC "Xensource"
    6.10  #define MAX_XENBUS_STR_LEN 128
    6.11 \ No newline at end of file
     7.1 --- a/xenpci/sources	Sun Jan 20 22:57:30 2008 +1100
     7.2 +++ b/xenpci/sources	Mon Jan 21 23:23:23 2008 +1100
     7.3 @@ -1,7 +1,7 @@
     7.4  TARGETNAME=XENPCI
     7.5  TARGETTYPE=DRIVER
     7.6  TARGETPATH=..\Target\$(DDK_TARGET_OS)
     7.7 -VERSION=0.5.0.40
     7.8 +VERSION=0.5.0.41
     7.9  KMDF_VERSION=1
    7.10  MSC_WARNING_LEVEL=/W4
    7.11  INF_NAME=xenpci
     8.1 --- a/xenvbd/sources	Sun Jan 20 22:57:30 2008 +1100
     8.2 +++ b/xenvbd/sources	Mon Jan 21 23:23:23 2008 +1100
     8.3 @@ -1,7 +1,7 @@
     8.4  TARGETNAME=XENVBD
     8.5  TARGETTYPE=DRIVER
     8.6  TARGETPATH=..\Target\$(DDK_TARGET_OS)
     8.7 -VERSION=0.5.0.15
     8.8 +VERSION=0.5.0.16
     8.9  KMDF_VERSION=1
    8.10  MSC_WARNING_LEVEL=/W4
    8.11  INF_NAME=xenvbd