win-pvdrivers

changeset 91:24963c2b7846

xennet: break up tx and rx locks to prevent recursive acquire
author Andy Grover <andy.grover@oracle.com>
date Wed Jan 02 16:52:52 2008 -0800 (2008-01-02)
parents 93879f914f05
children 7bcdf94713dc
files xennet/xennet.c
line diff
     1.1 --- a/xennet/xennet.c	Wed Jan 02 15:47:16 2008 -0800
     1.2 +++ b/xennet/xennet.c	Wed Jan 02 16:52:52 2008 -0800
     1.3 @@ -114,7 +114,8 @@ struct xennet_info
     1.4    ULONG state;
     1.5    ULONG backend_state;
     1.6  
     1.7 -  KSPIN_LOCK Lock;
     1.8 +  KSPIN_LOCK RxLock;
     1.9 +  KSPIN_LOCK TxLock;
    1.10  };
    1.11  
    1.12  /* This function copied from linux's lib/vsprintf.c, see it for attribution */
    1.13 @@ -170,11 +171,14 @@ XenNet_TxBufferGC(struct xennet_info *xi
    1.14    unsigned short id;
    1.15    PNDIS_PACKET pkt;
    1.16    PMDL pmdl;
    1.17 +  KIRQL OldIrql;
    1.18  
    1.19    ASSERT(xi->connected);
    1.20  
    1.21  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    1.22  
    1.23 +  KeAcquireSpinLock(&xi->TxLock, &OldIrql);
    1.24 +
    1.25    do {
    1.26      prod = xi->tx.sring->rsp_prod;
    1.27      KeMemoryBarrier(); /* Ensure we see responses up to 'rp'. */
    1.28 @@ -220,6 +224,8 @@ XenNet_TxBufferGC(struct xennet_info *xi
    1.29    /* if queued packets, send them now?
    1.30    network_maybe_wake_tx(dev); */
    1.31  
    1.32 +  KeReleaseSpinLock(&xi->TxLock, OldIrql);
    1.33 +
    1.34  //  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    1.35  
    1.36    return NDIS_STATUS_SUCCESS;
    1.37 @@ -311,11 +317,14 @@ XenNet_RxBufferCheck(struct xennet_info 
    1.38    UINT buff_len;
    1.39    UINT tot_buff_len;
    1.40    int moretodo;
    1.41 +  KIRQL OldIrql;
    1.42  
    1.43  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    1.44  
    1.45    ASSERT(xi->connected);
    1.46  
    1.47 +  KeAcquireSpinLock(&xi->RxLock, &OldIrql);
    1.48 +
    1.49    do {
    1.50      prod = xi->rx.sring->rsp_prod;
    1.51      KeMemoryBarrier(); /* Ensure we see responses up to 'rp'. */
    1.52 @@ -353,25 +362,13 @@ XenNet_RxBufferCheck(struct xennet_info 
    1.53      xi->rx.rsp_cons = prod;
    1.54  
    1.55      RING_FINAL_CHECK_FOR_RESPONSES(&xi->rx, moretodo);
    1.56 -#if 0
    1.57 -    /*
    1.58 -     * Set a new event, then check for race with update of rx_cons.
    1.59 -     * Note that it is essential to schedule a callback, no matter
    1.60 -     * how few buffers are pending. Even if there is space in the
    1.61 -     * transmit ring, higher layers may be blocked because too much
    1.62 -     * data is outstanding: in such cases notification from Xen is
    1.63 -     * likely to be the only kick that we'll get.
    1.64 -     */
    1.65 -    xi->rx.sring->rsp_event =
    1.66 -      prod + ((xi->rx.sring->req_prod - prod) >> 1) + 1;
    1.67 -    KeMemoryBarrier();
    1.68 -  } while ((cons == prod) && (prod != xi->rx.sring->rsp_prod));
    1.69 -#endif
    1.70    } while (moretodo);
    1.71  
    1.72    /* Give netback more buffers */
    1.73    XenNet_AllocRXBuffers(xi);
    1.74  
    1.75 +  KeReleaseSpinLock(&xi->RxLock, OldIrql);
    1.76 +
    1.77    //xi->rx.sring->rsp_event = xi->rx.rsp_cons + 1;
    1.78  
    1.79  //  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    1.80 @@ -387,24 +384,17 @@ XenNet_Interrupt(
    1.81    )
    1.82  {
    1.83    struct xennet_info *xi = ServiceContext;
    1.84 -  KIRQL OldIrql;
    1.85  
    1.86    UNREFERENCED_PARAMETER(Interrupt);
    1.87  
    1.88  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    1.89  
    1.90 -  KeAcquireSpinLock(&xi->Lock, &OldIrql);
    1.91 -
    1.92 -  //KdPrint((__DRIVER_NAME "     ***XenNet Interrupt***\n"));  
    1.93 -
    1.94    if (xi->connected)
    1.95    {
    1.96      XenNet_TxBufferGC(xi);
    1.97      XenNet_RxBufferCheck(xi);
    1.98    }
    1.99  
   1.100 -  KeReleaseSpinLock(&xi->Lock, OldIrql);
   1.101 -
   1.102  //  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   1.103  
   1.104    return TRUE;
   1.105 @@ -648,7 +638,8 @@ XenNet_Init(
   1.106    xi->state = XenbusStateUnknown;
   1.107    xi->backend_state = XenbusStateUnknown;
   1.108  
   1.109 -  KeInitializeSpinLock(&xi->Lock);
   1.110 +  KeInitializeSpinLock(&xi->TxLock);
   1.111 +  KeInitializeSpinLock(&xi->RxLock);
   1.112  
   1.113    NdisAllocatePacketPool(&status, &xi->packet_pool, NET_RX_RING_SIZE,
   1.114      PROTOCOL_RESERVED_SIZE_IN_PACKET);
   1.115 @@ -1224,7 +1215,7 @@ XenNet_SendPackets(
   1.116  
   1.117  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   1.118  
   1.119 -  KeAcquireSpinLock(&xi->Lock, &OldIrql);
   1.120 +  KeAcquireSpinLock(&xi->TxLock, &OldIrql);
   1.121  
   1.122    for (i = 0; i < NumberOfPackets; i++)
   1.123    {
   1.124 @@ -1273,7 +1264,7 @@ XenNet_SendPackets(
   1.125        xi->event_channel);
   1.126    }
   1.127  
   1.128 -  KeReleaseSpinLock(&xi->Lock, OldIrql);
   1.129 +  KeReleaseSpinLock(&xi->TxLock, OldIrql);
   1.130  
   1.131  //  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   1.132  }