win-pvdrivers

changeset 112:57b0d44f10f5

xennet: Minor tidying after James's multiple-buffers-in-a-packet changes

Move spinlock acqure inside RxBufferAlloc()
Clean up some warnings
Instead of handling some errors, ASSERT() them
Omit more_frags variable in RxBufferCheck, I think it's clearer without it
Change ReturnPacket to free multiple buffers
author Andy Grover <andy.grover@oracle.com>
date Fri Jan 11 11:40:45 2008 -0800 (2008-01-11)
parents f565bdc4f522
children e96b7ebe0147
files xennet/xennet.c
line diff
     1.1 --- a/xennet/xennet.c	Fri Jan 11 23:47:45 2008 +1100
     1.2 +++ b/xennet/xennet.c	Fri Jan 11 11:40:45 2008 -0800
     1.3 @@ -94,7 +94,7 @@ struct xennet_info
     1.4     * is an index into a chain of free entries. */
     1.5    int tx_pkt_ids_used;
     1.6    PNDIS_PACKET tx_pkts[NET_TX_RING_SIZE+1];
     1.7 -  PNDIS_PACKET rx_buffers[NET_RX_RING_SIZE];
     1.8 +  PNDIS_BUFFER rx_buffers[NET_RX_RING_SIZE];
     1.9  
    1.10    grant_ref_t gref_tx_head;
    1.11    grant_ref_t grant_tx_ref[NET_TX_RING_SIZE+1];
    1.12 @@ -265,7 +265,7 @@ static void XenNet_TxBufferFree(struct x
    1.13    }
    1.14  }
    1.15  
    1.16 -// Called at DISPATCH_LEVEL with RxLock held
    1.17 +// Called at DISPATCH_LEVEL with no locks held
    1.18  static NDIS_STATUS
    1.19  XenNet_RxBufferAlloc(struct xennet_info *xi)
    1.20  {
    1.21 @@ -277,14 +277,17 @@ XenNet_RxBufferAlloc(struct xennet_info 
    1.22    netif_rx_request_t *req;
    1.23    NDIS_STATUS status;
    1.24    PVOID start;
    1.25 +  KIRQL OldIrql;
    1.26  
    1.27  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    1.28  
    1.29 +  KeAcquireSpinLock(&xi->rx_lock, &OldIrql);
    1.30 +
    1.31    batch_target = xi->rx_target - (req_prod - xi->rx.rsp_cons);
    1.32    for (i = 0; i < batch_target; i++)
    1.33    {
    1.34      /*
    1.35 -     * Allocate a packet, page, and buffer. Hook them up.
    1.36 +     * Allocate memory and an NDIS_BUFFER.
    1.37       */
    1.38      status = NdisAllocateMemoryWithTag(&start, PAGE_SIZE, XENNET_POOL_TAG);
    1.39      if (status != NDIS_STATUS_SUCCESS)
    1.40 @@ -299,9 +302,10 @@ XenNet_RxBufferAlloc(struct xennet_info 
    1.41        NdisFreeMemory(start, 0, 0);
    1.42        break;
    1.43      }
    1.44 +
    1.45      /* Give to netback */
    1.46      id = (unsigned short)(req_prod + i) & (NET_RX_RING_SIZE - 1);
    1.47 -//    ASSERT(!xi->rx_pkts[id]);
    1.48 +    ASSERT(!xi->rx_buffers[id]);
    1.49      xi->rx_buffers[id] = buffer;
    1.50      req = RING_GET_REQUEST(&xi->rx, req_prod + i);
    1.51      /* an NDIS_BUFFER is just a MDL, so we can get its pfn array */
    1.52 @@ -323,20 +327,20 @@ XenNet_RxBufferAlloc(struct xennet_info 
    1.53        xi->event_channel);
    1.54    }
    1.55  
    1.56 +  KeReleaseSpinLock(&xi->rx_lock, OldIrql);
    1.57 +
    1.58  //  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    1.59  
    1.60    return NDIS_STATUS_SUCCESS;
    1.61  }
    1.62  
    1.63 +/* Free all Rx buffers (on halt, for example) */
    1.64  static void
    1.65  XenNet_RxBufferFree(struct xennet_info *xi)
    1.66  {
    1.67    int i;
    1.68    grant_ref_t ref;
    1.69    PNDIS_BUFFER buffer;
    1.70 -  PVOID buff_va;
    1.71 -  UINT buff_len;
    1.72 -  UINT tot_buff_len;
    1.73    KIRQL OldIrql;
    1.74  
    1.75    ASSERT(!xi->connected);
    1.76 @@ -459,16 +463,12 @@ XenNet_RxBufferCheck(struct xennet_info 
    1.77  
    1.78    PNDIS_PACKET packet = NULL;
    1.79    PNDIS_BUFFER buffer;
    1.80 -  PVOID buff_va;
    1.81 -  UINT buff_len;
    1.82 -  UINT tot_buff_len;
    1.83    int moretodo;
    1.84    KIRQL OldIrql;
    1.85    PNDIS_TCP_IP_CHECKSUM_PACKET_INFO csum_info;
    1.86    struct netif_rx_response *rxrsp = NULL;
    1.87 -  int more_frags = 0;
    1.88  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    1.89 -  PNDIS_STATUS status;
    1.90 +  NDIS_STATUS status;
    1.91  
    1.92    ASSERT(xi->connected);
    1.93  
    1.94 @@ -480,25 +480,13 @@ XenNet_RxBufferCheck(struct xennet_info 
    1.95  
    1.96      for (cons = xi->rx.rsp_cons; cons != prod; cons++) {
    1.97        rxrsp = RING_GET_RESPONSE(&xi->rx, cons);
    1.98 -      if (rxrsp->status == NETIF_RSP_NULL)
    1.99 -        continue;
   1.100 +      ASSERT(rxrsp->status > 0);
   1.101  
   1.102 -    //  KdPrint((__DRIVER_NAME "     Got a packet\n"));
   1.103 -
   1.104 -      if (!more_frags) // !more_frags means this buffer is the first for the packet
   1.105 +      if (!(rxrsp->flags & NETRXF_more_data)) // handling the packet's 1st buffer
   1.106        {
   1.107 -        // we might be able to set up an IP and an Other pool and select as appropriate here...
   1.108 +        //  KdPrint((__DRIVER_NAME "     Got a packet\n"));
   1.109          NdisAllocatePacket(&status, &packet, xi->packet_pool);
   1.110 -        if (status != NDIS_STATUS_SUCCESS)
   1.111 -        {
   1.112 -          KdPrint(("NdisAllocatePacket Failed! status = 0x%x\n", status));
   1.113 -/* we are going to fail horribly here right now!!! */
   1.114 -/*
   1.115 -          NdisFreeMemory(start, 0, 0);
   1.116 -          NdisFreeBuffer(buffer);
   1.117 -          break;
   1.118 -*/
   1.119 -        }
   1.120 +        ASSERT(status == NDIS_STATUS_SUCCESS);
   1.121          NDIS_SET_PACKET_HEADER_SIZE(packet, XN_HDR_SIZE);
   1.122  /*
   1.123          if (NDIS_GET_PACKET_PROTOCOL_TYPE(packet) == NDIS_PROTOCOL_ID_TCP_IP
   1.124 @@ -522,13 +510,6 @@ XenNet_RxBufferCheck(struct xennet_info 
   1.125          xi->grant_rx_ref[rxrsp->id]);
   1.126        xi->grant_rx_ref[rxrsp->id] = GRANT_INVALID_REF;
   1.127  
   1.128 -/*
   1.129 -      NdisGetFirstBufferFromPacketSafe(packet, &buffer, &buff_va, &buff_len,
   1.130 -        &tot_buff_len, NormalPagePriority);
   1.131 -      ASSERT(rxrsp->offset == 0);
   1.132 -      ASSERT(rxrsp->status > 0);
   1.133 -*/
   1.134 -
   1.135  #if 1
   1.136        KdPrint((__DRIVER_NAME "     Flags = %sNETRXF_data_validated|%sNETRXF_csum_blank|%sNETRXF_more_data|%sNETRXF_extra_info\n",
   1.137          (rxrsp->flags&NETRXF_data_validated)?"":"!",
   1.138 @@ -536,42 +517,31 @@ XenNet_RxBufferCheck(struct xennet_info 
   1.139          (rxrsp->flags&NETRXF_more_data)?"":"!",
   1.140          (rxrsp->flags&NETRXF_extra_info)?"":"!"));
   1.141  #endif
   1.142 +      ASSERT(!(rxrsp->flags & NETRXF_extra_info)); // not used on RX
   1.143 +
   1.144        //XenNet_ProcessReceivedEthernetPacket(packet, buff_va, rxrsp->status);
   1.145  
   1.146 -      more_frags = rxrsp->flags & NETRXF_more_data;
   1.147 -
   1.148 -      if (!more_frags)
   1.149 +      /* Packet done, pass it up */
   1.150 +      if (!(rxrsp->flags & NETRXF_more_data))
   1.151        {
   1.152 -        ASSERT(packet != NULL);
   1.153          xi->stat_rx_ok++;
   1.154          NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_SUCCESS);
   1.155 -
   1.156 -        /* just indicate 1 packet for now */
   1.157          NdisMIndicateReceivePacket(xi->adapter_handle, &packet, 1);
   1.158        }
   1.159      }
   1.160  
   1.161 +    ASSERT(!(rxrsp->flags & NETRXF_more_data));
   1.162 +
   1.163      xi->rx.rsp_cons = prod;
   1.164  
   1.165      RING_FINAL_CHECK_FOR_RESPONSES(&xi->rx, moretodo);
   1.166    } while (moretodo);
   1.167  
   1.168 -  if (more_frags)
   1.169 -  {
   1.170 -    KdPrint((__DRIVER_NAME "     Missing fragments\n"));
   1.171 -    // free our packet and buffer(s) (may be more than one buffer...) here, as nobody else will!
   1.172 -/*
   1.173 -    NdisFreeMemory(buff_va, 0, 0);
   1.174 -    NdisFreeBuffer(buffer);
   1.175 -    NdisFreePacket(packet);
   1.176 -*/
   1.177 -  }
   1.178 +  KeReleaseSpinLock(&xi->rx_lock, OldIrql);
   1.179  
   1.180    /* Give netback more buffers */
   1.181    XenNet_RxBufferAlloc(xi);
   1.182  
   1.183 -  KeReleaseSpinLock(&xi->rx_lock, OldIrql);
   1.184 -
   1.185    //xi->rx.sring->rsp_event = xi->rx.rsp_cons + 1;
   1.186  
   1.187  //  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   1.188 @@ -1494,10 +1464,16 @@ XenNet_ReturnPacket(
   1.189  
   1.190    NdisGetFirstBufferFromPacketSafe(Packet, &buffer, &buff_va, &buff_len,
   1.191      &tot_buff_len, NormalPagePriority);
   1.192 -  //ASSERT(buff_len == tot_buff_len);
   1.193 +  ASSERT(tot_buff_len <= XN_MAX_PKT_SIZE);
   1.194  
   1.195 -  NdisFreeMemory(buff_va, 0, 0);
   1.196 -  NdisFreeBuffer(buffer);
   1.197 +  while (buffer)
   1.198 +  {
   1.199 +    NdisQueryBufferSafe(buffer, &buff_va, &buff_len, NormalPagePriority);
   1.200 +    NdisFreeMemory(buff_va, 0, 0);
   1.201 +    NdisFreeBuffer(buffer);
   1.202 +    NdisGetNextBuffer(buffer, &buffer);
   1.203 +  }
   1.204 +
   1.205    NdisFreePacket(Packet);
   1.206  
   1.207    //KdPrint((__FUNCTION__ " called\n"));