win-pvdrivers

changeset 451:1275f2e97b60

Fixed a crash if the backend connect failed.
Added interrupt moderation, configurable.
author James Harper <james.harper@bendigoit.com.au>
date Thu Nov 13 17:28:55 2008 +1100 (2008-11-13)
parents 605747e0db9c
children 1ac3b9d80a06
files xennet/xennet.c xennet/xennet.h xennet/xennet.inx xennet/xennet_oid.c xennet/xennet_rx.c
line diff
     1.1 --- a/xennet/xennet.c	Thu Nov 13 17:27:05 2008 +1100
     1.2 +++ b/xennet/xennet.c	Thu Nov 13 17:28:55 2008 +1100
     1.3 @@ -371,6 +371,7 @@ XenNet_Init(
     1.4    xi->config_sg = 1;
     1.5    xi->config_gso = 61440;
     1.6    xi->config_page = NULL;
     1.7 +  xi->config_rx_interrupt_moderation = 0;
     1.8    
     1.9    for (i = 0; i < nrl->Count; i++)
    1.10    {
    1.11 @@ -553,6 +554,20 @@ XenNet_Init(
    1.12      xi->config_mtu = config_param->ParameterData.IntegerData;
    1.13    }
    1.14  
    1.15 +  NdisInitUnicodeString(&config_param_name, L"RxInterruptModeration");
    1.16 +  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);  
    1.17 +  if (!NT_SUCCESS(status))
    1.18 +  {
    1.19 +    KdPrint(("Could not read RxInterruptModeration value (%08x)\n", status));
    1.20 +    xi->config_rx_interrupt_moderation = 1500;
    1.21 +  }
    1.22 +  else
    1.23 +  {
    1.24 +    KdPrint(("RxInterruptModeration = %d\n", config_param->ParameterData.IntegerData));
    1.25 +    xi->config_rx_interrupt_moderation = config_param->ParameterData.IntegerData;
    1.26 +  }
    1.27 +  
    1.28 +
    1.29    NdisReadNetworkAddress(&status, &network_address, &network_address_length, config_handle);
    1.30    if (!NT_SUCCESS(status) || network_address_length != ETH_ALEN || !(((PUCHAR)network_address)[0] & 0x02))
    1.31    {
    1.32 @@ -572,6 +587,8 @@ XenNet_Init(
    1.33    NdisCloseConfiguration(config_handle);
    1.34  
    1.35    ptr = xi->config_page;
    1.36 +  // two XEN_INIT_TYPE_RUNs means go straight to XenbusStateConnected - skip XenbusStateInitialised
    1.37 +  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RUN, NULL, NULL);
    1.38    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RUN, NULL, NULL);
    1.39    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RING, "tx-ring-ref", NULL);
    1.40    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RING, "rx-ring-ref", NULL);
    1.41 @@ -588,10 +605,20 @@ XenNet_Init(
    1.42    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_END, NULL, NULL);
    1.43    
    1.44    status = xi->vectors.XenPci_XenConfigDevice(xi->vectors.context);
    1.45 -  // check return value
    1.46 +  if (!NT_SUCCESS(status))
    1.47 +  {
    1.48 +    KdPrint(("Failed to complete device configuration\n", status));
    1.49 +    goto err;
    1.50 +  }
    1.51  
    1.52    status = XenNet_ConnectBackend(xi);
    1.53    
    1.54 +  if (!NT_SUCCESS(status))
    1.55 +  {
    1.56 +    KdPrint(("Failed to complete device configuration\n", status));
    1.57 +    goto err;
    1.58 +  }
    1.59 +
    1.60    XenNet_TxInit(xi);
    1.61    XenNet_RxInit(xi);
    1.62  
     2.1 --- a/xennet/xennet.h	Thu Nov 13 17:27:05 2008 +1100
     2.2 +++ b/xennet/xennet.h	Thu Nov 13 17:28:55 2008 +1100
     2.3 @@ -268,6 +268,7 @@ struct xennet_info
     2.4    ULONG rx_packet_free;
     2.5    BOOLEAN rx_shutting_down;
     2.6    KEVENT packet_returned_event;
     2.7 +  NDIS_MINIPORT_TIMER rx_timer;
     2.8  
     2.9    /* Receive-ring batched refills. */
    2.10    ULONG rx_target;
    2.11 @@ -283,6 +284,7 @@ struct xennet_info
    2.12    ULONG config_csum_rx_check;
    2.13    ULONG config_gso;
    2.14    ULONG config_mtu;
    2.15 +  ULONG config_rx_interrupt_moderation;
    2.16  
    2.17    NDIS_TASK_TCP_IP_CHECKSUM setting_csum;
    2.18    ULONG setting_max_offload;
    2.19 @@ -290,8 +292,6 @@ struct xennet_info
    2.20    /* config stuff calculated from the above */
    2.21    ULONG config_max_pkt_size;
    2.22  
    2.23 -  //NDIS_MINIPORT_TIMER resume_timer;
    2.24 -
    2.25    /* stats */
    2.26    ULONG64 stat_tx_ok;
    2.27    ULONG64 stat_rx_ok;
     3.1 --- a/xennet/xennet.inx	Thu Nov 13 17:27:05 2008 +1100
     3.2 +++ b/xennet/xennet.inx	Thu Nov 13 17:28:55 2008 +1100
     3.3 @@ -67,6 +67,12 @@ HKR, Ndi\Params\ScatterGather, type, , "
     3.4  HKR, Ndi\Params\ScatterGather\enum, 0, , "Disabled"
     3.5  HKR, Ndi\Params\ScatterGather\enum, 1, , "Enabled"
     3.6  
     3.7 +HKR, Ndi\Params\RxInterruptModeration, ParamDesc, , "Rx Interrupt Moderation (beta)"
     3.8 +HKR, Ndi\Params\RxInterruptModeration, default, , "0"
     3.9 +HKR, Ndi\Params\RxInterruptModeration, type, , "enum"
    3.10 +HKR, Ndi\Params\RxInterruptModeration\enum, 0, , "Disabled"
    3.11 +HKR, Ndi\Params\RxInterruptModeration\enum, 1, , "Enabled"
    3.12 +
    3.13  HKR, Ndi\Params\NetworkAddress, ParamDesc, , "Locally Administered Address"
    3.14  HKR, Ndi\Params\NetworkAddress, Type, , "edit"
    3.15  HKR, Ndi\Params\NetworkAddress, LimitText, , "12"
     4.1 --- a/xennet/xennet_oid.c	Thu Nov 13 17:27:05 2008 +1100
     4.2 +++ b/xennet/xennet_oid.c	Thu Nov 13 17:28:55 2008 +1100
     4.3 @@ -108,12 +108,12 @@ XenNet_QueryInformation(
     4.4        if (!xi->connected)
     4.5        {
     4.6          temp_data = NdisHardwareStatusInitializing;
     4.7 -        FUNCTION_MSG(("NdisHardwareStatusInitializing\n"));
     4.8 +        FUNCTION_MSG("NdisHardwareStatusInitializing\n");
     4.9        }
    4.10        else
    4.11        {
    4.12          temp_data = NdisHardwareStatusReady;
    4.13 -        FUNCTION_MSG(("NdisHardwareStatusReady\n"));
    4.14 +        FUNCTION_MSG("NdisHardwareStatusReady\n");
    4.15        }
    4.16        break;
    4.17      case OID_GEN_MEDIA_SUPPORTED:
    4.18 @@ -371,7 +371,7 @@ XenNet_QueryInformation(
    4.19    if (len > InformationBufferLength)
    4.20    {
    4.21      *BytesNeeded = len;
    4.22 -    FUNCTION_MSG(("(BUFFER_TOO_SHORT %d > %d)\n", len, InformationBufferLength));
    4.23 +    FUNCTION_MSG("(BUFFER_TOO_SHORT %d > %d)\n", len, InformationBufferLength);
    4.24      return NDIS_STATUS_BUFFER_TOO_SHORT;
    4.25    }
    4.26  
     5.1 --- a/xennet/xennet_rx.c	Thu Nov 13 17:27:05 2008 +1100
     5.2 +++ b/xennet/xennet_rx.c	Thu Nov 13 17:28:55 2008 +1100
     5.3 @@ -483,7 +483,8 @@ XenNet_RxBufferCheck(struct xennet_info 
     5.4    struct netif_rx_response *rxrsp = NULL;
     5.5    struct netif_extra_info *ei;
     5.6    USHORT id;
     5.7 -  int more_to_do;
     5.8 +  int more_to_do = FALSE;
     5.9 +  int page_count = 0;
    5.10    
    5.11  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    5.12  
    5.13 @@ -593,9 +594,23 @@ XenNet_RxBufferCheck(struct xennet_info 
    5.14        {
    5.15          packet_count += XenNet_MakePackets(xi, &rx_packet_list);
    5.16        }
    5.17 +      if (!more_to_do) {
    5.18 +        page_count++; /* only interested in the number of pages available after the first time around */
    5.19 +      }
    5.20      }
    5.21      xi->rx.rsp_cons = cons;
    5.22 -    RING_FINAL_CHECK_FOR_RESPONSES(&xi->rx, more_to_do);
    5.23 +    
    5.24 +    more_to_do = RING_HAS_UNCONSUMED_RESPONSES(&xi->rx);
    5.25 +    if (!more_to_do)
    5.26 +    {
    5.27 +      if (xi->config_rx_interrupt_moderation)
    5.28 +        xi->rx.sring->rsp_event = xi->rx.rsp_cons + min(max(1, page_count >> 1), 64);
    5.29 +      else
    5.30 +        xi->rx.sring->rsp_event = xi->rx.rsp_cons + 1;
    5.31 +      mb();
    5.32 +      more_to_do = RING_HAS_UNCONSUMED_RESPONSES(&xi->rx);
    5.33 +    }
    5.34 +    //RING_FINAL_CHECK_FOR_RESPONSES(&xi->rx, more_to_do);
    5.35    } while (more_to_do);
    5.36  
    5.37    if (xi->rxpi.more_frags || xi->rxpi.extra_info)
    5.38 @@ -606,6 +621,18 @@ XenNet_RxBufferCheck(struct xennet_info 
    5.39  
    5.40    KeReleaseSpinLockFromDpcLevel(&xi->rx_lock);
    5.41  
    5.42 +  if (xi->config_rx_interrupt_moderation)
    5.43 +  {
    5.44 +    if (page_count >> 1)
    5.45 +    {
    5.46 +      NdisMSetTimer(&xi->rx_timer, 1);
    5.47 +    }
    5.48 +    else
    5.49 +    {
    5.50 +      BOOLEAN cancelled;
    5.51 +      NdisMCancelTimer(&xi->rx_timer, &cancelled);
    5.52 +    }
    5.53 +  }
    5.54    entry = RemoveHeadList(&rx_packet_list);
    5.55    packet_count = 0;
    5.56    while (entry != &rx_packet_list)
    5.57 @@ -716,6 +743,27 @@ XenNet_RxResumeEnd(xennet_info_t *xi)
    5.58    KeReleaseSpinLock(&xi->rx_lock, old_irql);
    5.59  }
    5.60  
    5.61 +/* Called at DISPATCH LEVEL */
    5.62 +static VOID DDKAPI
    5.63 +XenNet_RxTimer(
    5.64 +  PVOID SystemSpecific1,
    5.65 +  PVOID FunctionContext,
    5.66 +  PVOID SystemSpecific2,
    5.67 +  PVOID SystemSpecific3
    5.68 +)
    5.69 +{
    5.70 +  struct xennet_info *xi = FunctionContext;
    5.71 +
    5.72 +  UNREFERENCED_PARAMETER(SystemSpecific1);
    5.73 +  UNREFERENCED_PARAMETER(SystemSpecific2);
    5.74 +  UNREFERENCED_PARAMETER(SystemSpecific3);
    5.75 +
    5.76 +  if (xi->connected && !xi->inactive && xi->device_state->resume_state == RESUME_STATE_RUNNING)
    5.77 +  {
    5.78 +    XenNet_RxBufferCheck(xi);
    5.79 +  }  
    5.80 +}
    5.81 +
    5.82  BOOLEAN
    5.83  XenNet_RxInit(xennet_info_t *xi)
    5.84  {
    5.85 @@ -724,6 +772,7 @@ XenNet_RxInit(xennet_info_t *xi)
    5.86    FUNCTION_ENTER();
    5.87  
    5.88    KeInitializeEvent(&xi->packet_returned_event, SynchronizationEvent, FALSE);
    5.89 +  NdisMInitializeTimer(&xi->rx_timer, xi->adapter_handle, XenNet_RxTimer, xi);
    5.90  
    5.91    xi->rx_shutting_down = FALSE;
    5.92    
    5.93 @@ -754,7 +803,13 @@ XenNet_RxShutdown(xennet_info_t *xi)
    5.94    KeAcquireSpinLock(&xi->rx_lock, &OldIrql);
    5.95    xi->rx_shutting_down = TRUE;
    5.96    KeReleaseSpinLock(&xi->rx_lock, OldIrql);
    5.97 -  
    5.98 +
    5.99 +  if (xi->config_rx_interrupt_moderation)
   5.100 +  {
   5.101 +    BOOLEAN cancelled;
   5.102 +    NdisMCancelTimer(&xi->rx_timer, &cancelled);
   5.103 +  }
   5.104 +
   5.105    while (xi->rx_outstanding)
   5.106    {
   5.107      KdPrint((__DRIVER_NAME "     Waiting for all packets to be returned\n"));