win-pvdrivers

changeset 603:ee9c59a5a06c

Fix the xennet shutdown race properly this time
author James Harper <james.harper@bendigoit.com.au>
date Sun Jul 05 12:06:47 2009 +1000 (2009-07-05)
parents 093ba74b1e6e
children 43c29c68398f
files xennet/xennet.c xennet/xennet.h xennet/xennet_rx.c xennet/xennet_tx.c
line diff
     1.1 --- a/xennet/xennet.c	Sun Jul 05 11:05:23 2009 +1000
     1.2 +++ b/xennet/xennet.c	Sun Jul 05 12:06:47 2009 +1000
     1.3 @@ -307,17 +307,14 @@ XenNet_HandleEvent(PVOID context)
     1.4    KeMemoryBarrier();
     1.5  //  KdPrint((__DRIVER_NAME "     connected = %d, inactive = %d, suspend_resume_state_pdo = %d\n",
     1.6  //    xi->connected, xi->inactive, suspend_resume_state_pdo));
     1.7 -  if (!xi->shutting_down)
     1.8 +  if (!xi->shutting_down && suspend_resume_state_pdo != xi->device_state->suspend_resume_state_fdo)
     1.9    {
    1.10 -    if (suspend_resume_state_pdo != xi->device_state->suspend_resume_state_fdo)
    1.11 -    {
    1.12 -      KeInsertQueueDpc(&xi->suspend_dpc, NULL, NULL);
    1.13 -    }
    1.14 -    else if (xi->connected && !xi->inactive && suspend_resume_state_pdo != SR_STATE_RESUMING)
    1.15 -    {
    1.16 -      KeInsertQueueDpc(&xi->tx_dpc, NULL, NULL);
    1.17 -      KeInsertQueueDpc(&xi->rx_dpc, NULL, NULL);
    1.18 -    }
    1.19 +    KeInsertQueueDpc(&xi->suspend_dpc, NULL, NULL);
    1.20 +  }
    1.21 +  if (xi->connected && !xi->inactive && suspend_resume_state_pdo != SR_STATE_RESUMING)
    1.22 +  {
    1.23 +    KeInsertQueueDpc(&xi->tx_dpc, NULL, NULL);
    1.24 +    KeInsertQueueDpc(&xi->rx_dpc, NULL, NULL);
    1.25    }
    1.26    //FUNCTION_EXIT();
    1.27    return TRUE;
     2.1 --- a/xennet/xennet.h	Sun Jul 05 11:05:23 2009 +1000
     2.2 +++ b/xennet/xennet.h	Sun Jul 05 12:06:47 2009 +1000
     2.3 @@ -247,6 +247,8 @@ struct xennet_info
     2.4    ULONG packet_filter;
     2.5    BOOLEAN connected;
     2.6    BOOLEAN shutting_down;
     2.7 +  BOOLEAN tx_shutting_down;
     2.8 +  BOOLEAN rx_shutting_down;
     2.9    uint8_t perm_mac_addr[ETH_ALEN];
    2.10    uint8_t curr_mac_addr[ETH_ALEN];
    2.11  
     3.1 --- a/xennet/xennet_rx.c	Sun Jul 05 11:05:23 2009 +1000
     3.2 +++ b/xennet/xennet_rx.c	Sun Jul 05 12:06:47 2009 +1000
     3.3 @@ -660,7 +660,7 @@ XenNet_RxBufferCheck(PKDPC dpc, PVOID co
     3.4  
     3.5    KeAcquireSpinLockAtDpcLevel(&xi->rx_lock);
     3.6    
     3.7 -  if (xi->shutting_down)
     3.8 +  if (xi->rx_shutting_down)
     3.9    {
    3.10      /* there is a chance that our Dpc had been queued just before the shutdown... */
    3.11      KeReleaseSpinLockFromDpcLevel(&xi->rx_lock);
    3.12 @@ -854,7 +854,7 @@ XenNet_ReturnPacket(
    3.13    put_packet_on_freelist(xi, Packet);
    3.14    xi->rx_outstanding--;
    3.15    
    3.16 -  if (!xi->rx_outstanding && xi->shutting_down)
    3.17 +  if (!xi->rx_outstanding && xi->rx_shutting_down)
    3.18      KeSetEvent(&xi->packet_returned_event, IO_NO_INCREMENT, FALSE);
    3.19  
    3.20    XenNet_FillRing(xi);
    3.21 @@ -962,6 +962,7 @@ XenNet_RxInit(xennet_info_t *xi)
    3.22  
    3.23    FUNCTION_ENTER();
    3.24  
    3.25 +  xi->rx_shutting_down = FALSE;
    3.26    KeInitializeSpinLock(&xi->rx_lock);
    3.27    KeInitializeEvent(&xi->packet_returned_event, SynchronizationEvent, FALSE);
    3.28    KeInitializeTimer(&xi->rx_timer);
    3.29 @@ -992,10 +993,14 @@ XenNet_RxInit(xennet_info_t *xi)
    3.30  BOOLEAN
    3.31  XenNet_RxShutdown(xennet_info_t *xi)
    3.32  {
    3.33 -  KIRQL OldIrql;
    3.34 +  KIRQL old_irql;
    3.35  
    3.36    FUNCTION_ENTER();
    3.37  
    3.38 +  KeAcquireSpinLock(&xi->rx_lock, &old_irql);
    3.39 +  xi->rx_shutting_down = TRUE;
    3.40 +  KeReleaseSpinLock(&xi->rx_lock, old_irql);
    3.41 +
    3.42    if (xi->config_rx_interrupt_moderation)
    3.43    {
    3.44      KeCancelTimer(&xi->rx_timer);
    3.45 @@ -1010,7 +1015,7 @@ XenNet_RxShutdown(xennet_info_t *xi)
    3.46      KeWaitForSingleObject(&xi->packet_returned_event, Executive, KernelMode, FALSE, NULL);
    3.47    }
    3.48  
    3.49 -  KeAcquireSpinLock(&xi->rx_lock, &OldIrql);
    3.50 +  //KeAcquireSpinLock(&xi->rx_lock, &old_irql);
    3.51  
    3.52    XenNet_BufferFree(xi);
    3.53  
    3.54 @@ -1020,7 +1025,7 @@ XenNet_RxShutdown(xennet_info_t *xi)
    3.55  
    3.56    NdisDeleteNPagedLookasideList(&xi->rx_lookaside_list);
    3.57  
    3.58 -  KeReleaseSpinLock(&xi->rx_lock, OldIrql);
    3.59 +  //KeReleaseSpinLock(&xi->rx_lock, old_irql);
    3.60  
    3.61    FUNCTION_EXIT();
    3.62  
     4.1 --- a/xennet/xennet_tx.c	Sun Jul 05 11:05:23 2009 +1000
     4.2 +++ b/xennet/xennet_tx.c	Sun Jul 05 12:06:47 2009 +1000
     4.3 @@ -424,7 +424,7 @@ XenNet_TxBufferGC(PKDPC dpc, PVOID conte
     4.4  
     4.5    KeAcquireSpinLockAtDpcLevel(&xi->tx_lock);
     4.6  
     4.7 -  if (xi->shutting_down && !xi->tx_outstanding)
     4.8 +  if (xi->tx_shutting_down && !xi->tx_outstanding)
     4.9    {
    4.10      /* there is a chance that our Dpc had been queued just before the shutdown... */
    4.11      KeReleaseSpinLockFromDpcLevel(&xi->tx_lock);
    4.12 @@ -472,7 +472,7 @@ XenNet_TxBufferGC(PKDPC dpc, PVOID conte
    4.13    } while (prod != xi->tx.sring->rsp_prod);
    4.14  
    4.15    /* if queued packets, send them now */
    4.16 -  if (!xi->shutting_down)
    4.17 +  if (!xi->tx_shutting_down)
    4.18      XenNet_SendQueuedPackets(xi);
    4.19  
    4.20    KeReleaseSpinLockFromDpcLevel(&xi->tx_lock);
    4.21 @@ -483,7 +483,7 @@ XenNet_TxBufferGC(PKDPC dpc, PVOID conte
    4.22      head = *(PNDIS_PACKET *)&packet->MiniportReservedEx[0];
    4.23      NdisMSendComplete(xi->adapter_handle, packet, NDIS_STATUS_SUCCESS);
    4.24      xi->tx_outstanding--;
    4.25 -    if (!xi->tx_outstanding && xi->shutting_down)
    4.26 +    if (!xi->tx_outstanding && xi->tx_shutting_down)
    4.27        KeSetEvent(&xi->tx_idle_event, IO_NO_INCREMENT, FALSE);
    4.28    }
    4.29  
    4.30 @@ -628,6 +628,7 @@ XenNet_TxInit(xennet_info_t *xi)
    4.31    InitializeListHead(&xi->tx_waiting_pkt_list);
    4.32  
    4.33    KeInitializeEvent(&xi->tx_idle_event, SynchronizationEvent, FALSE);
    4.34 +  xi->tx_shutting_down = TRUE;
    4.35    xi->tx_outstanding = 0;
    4.36    xi->tx_ring_free = NET_TX_RING_SIZE;
    4.37    
    4.38 @@ -685,11 +686,19 @@ XenNet_TxShutdown(xennet_info_t *xi)
    4.39  
    4.40    FUNCTION_ENTER();
    4.41  
    4.42 +  KeAcquireSpinLock(&xi->tx_lock, &OldIrql);
    4.43 +  xi->tx_shutting_down = TRUE;
    4.44 +  KeReleaseSpinLock(&xi->tx_lock, OldIrql);
    4.45 +
    4.46 +  while (xi->tx_outstanding)
    4.47 +  {
    4.48 +    KdPrint((__DRIVER_NAME "     Waiting for %d remaining packets to be sent\n", xi->tx_outstanding));
    4.49 +    KeWaitForSingleObject(&xi->tx_idle_event, Executive, KernelMode, FALSE, NULL);
    4.50 +  }
    4.51 +
    4.52    KeRemoveQueueDpc(&xi->tx_dpc);
    4.53    KeFlushQueuedDpcs();
    4.54  
    4.55 -  KeAcquireSpinLock(&xi->tx_lock, &OldIrql);
    4.56 -
    4.57    /* Free packets in tx queue */
    4.58    entry = RemoveHeadList(&xi->tx_waiting_pkt_list);
    4.59    while (entry != &xi->tx_waiting_pkt_list)
    4.60 @@ -699,15 +708,7 @@ XenNet_TxShutdown(xennet_info_t *xi)
    4.61      entry = RemoveHeadList(&xi->tx_waiting_pkt_list);
    4.62    }
    4.63    
    4.64 -  KeReleaseSpinLock(&xi->tx_lock, OldIrql);
    4.65 -
    4.66 -  while (xi->tx_outstanding)
    4.67 -  {
    4.68 -    KdPrint((__DRIVER_NAME "     Waiting for all packets to be sent\n"));
    4.69 -    KeWaitForSingleObject(&xi->tx_idle_event, Executive, KernelMode, FALSE, NULL);
    4.70 -  }
    4.71 -
    4.72 -  KeAcquireSpinLock(&xi->tx_lock, &OldIrql);
    4.73 +  //KeAcquireSpinLock(&xi->tx_lock, &OldIrql);
    4.74  
    4.75    while((cb = get_cb_from_freelist(xi)) != NULL)
    4.76    {
    4.77 @@ -716,7 +717,7 @@ XenNet_TxShutdown(xennet_info_t *xi)
    4.78        NdisMFreeSharedMemory(xi->adapter_handle, PAGE_SIZE, TRUE, cb->virtual, cb->logical);
    4.79    }
    4.80  
    4.81 -  KeReleaseSpinLock(&xi->tx_lock, OldIrql);
    4.82 +  //KeReleaseSpinLock(&xi->tx_lock, OldIrql);
    4.83  
    4.84    FUNCTION_EXIT();
    4.85