| From: Thomas Gleixner <tglx@linutronix.de> |
| Date: Sat, 20 Jun 2009 11:36:54 +0200 |
| Subject: drivers/net: fix livelock issues |
| |
| Preempt-RT runs into a live lock issue with the NETDEV_TX_LOCKED micro |
| optimization. The reason is that the softirq thread is rescheduling |
| itself on that return value. Depending on priorities it starts to |
| monoplize the CPU and livelock on UP systems. |
| |
| Remove it. |
| |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| |
| --- |
| drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 6 +----- |
| drivers/net/ethernet/atheros/atl1e/atl1e_main.c | 3 +-- |
| drivers/net/ethernet/chelsio/cxgb/sge.c | 3 +-- |
| drivers/net/ethernet/neterion/s2io.c | 7 +------ |
| drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c | 6 ++---- |
| drivers/net/ethernet/tehuti/tehuti.c | 9 ++------- |
| drivers/net/rionet.c | 6 +----- |
| 7 files changed, 9 insertions(+), 31 deletions(-) |
| |
| --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c |
| +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c |
| @@ -2206,11 +2206,7 @@ static netdev_tx_t atl1c_xmit_frame(stru |
| } |
| |
| tpd_req = atl1c_cal_tpd_req(skb); |
| - if (!spin_trylock_irqsave(&adapter->tx_lock, flags)) { |
| - if (netif_msg_pktdata(adapter)) |
| - dev_info(&adapter->pdev->dev, "tx locked\n"); |
| - return NETDEV_TX_LOCKED; |
| - } |
| + spin_lock_irqsave(&adapter->tx_lock, flags); |
| |
| if (atl1c_tpd_avail(adapter, type) < tpd_req) { |
| /* no enough descriptor, just stop queue */ |
| --- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c |
| +++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c |
| @@ -1838,8 +1838,7 @@ static netdev_tx_t atl1e_xmit_frame(stru |
| return NETDEV_TX_OK; |
| } |
| tpd_req = atl1e_cal_tdp_req(skb); |
| - if (!spin_trylock_irqsave(&adapter->tx_lock, flags)) |
| - return NETDEV_TX_LOCKED; |
| + spin_lock_irqsave(&adapter->tx_lock, flags); |
| |
| if (atl1e_tpd_avail(adapter) < tpd_req) { |
| /* no enough descriptor, just stop queue */ |
| --- a/drivers/net/ethernet/chelsio/cxgb/sge.c |
| +++ b/drivers/net/ethernet/chelsio/cxgb/sge.c |
| @@ -1665,8 +1665,7 @@ static int t1_sge_tx(struct sk_buff *skb |
| struct cmdQ *q = &sge->cmdQ[qid]; |
| unsigned int credits, pidx, genbit, count, use_sched_skb = 0; |
| |
| - if (!spin_trylock(&q->lock)) |
| - return NETDEV_TX_LOCKED; |
| + spin_lock(&q->lock); |
| |
| reclaim_completed_tx(sge, q); |
| |
| --- a/drivers/net/ethernet/neterion/s2io.c |
| +++ b/drivers/net/ethernet/neterion/s2io.c |
| @@ -4089,12 +4089,7 @@ static netdev_tx_t s2io_xmit(struct sk_b |
| [skb->priority & (MAX_TX_FIFOS - 1)]; |
| fifo = &mac_control->fifos[queue]; |
| |
| - if (do_spin_lock) |
| - spin_lock_irqsave(&fifo->tx_lock, flags); |
| - else { |
| - if (unlikely(!spin_trylock_irqsave(&fifo->tx_lock, flags))) |
| - return NETDEV_TX_LOCKED; |
| - } |
| + spin_lock_irqsave(&fifo->tx_lock, flags); |
| |
| if (sp->config.multiq) { |
| if (__netif_subqueue_stopped(dev, fifo->fifo_no)) { |
| --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c |
| +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c |
| @@ -2109,10 +2109,8 @@ static int pch_gbe_xmit_frame(struct sk_ |
| struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring; |
| unsigned long flags; |
| |
| - if (!spin_trylock_irqsave(&tx_ring->tx_lock, flags)) { |
| - /* Collision - tell upper layer to requeue */ |
| - return NETDEV_TX_LOCKED; |
| - } |
| + spin_lock_irqsave(&tx_ring->tx_lock, flags); |
| + |
| if (unlikely(!PCH_GBE_DESC_UNUSED(tx_ring))) { |
| netif_stop_queue(netdev); |
| spin_unlock_irqrestore(&tx_ring->tx_lock, flags); |
| --- a/drivers/net/ethernet/tehuti/tehuti.c |
| +++ b/drivers/net/ethernet/tehuti/tehuti.c |
| @@ -1629,13 +1629,8 @@ static netdev_tx_t bdx_tx_transmit(struc |
| unsigned long flags; |
| |
| ENTER; |
| - local_irq_save(flags); |
| - if (!spin_trylock(&priv->tx_lock)) { |
| - local_irq_restore(flags); |
| - DBG("%s[%s]: TX locked, returning NETDEV_TX_LOCKED\n", |
| - BDX_DRV_NAME, ndev->name); |
| - return NETDEV_TX_LOCKED; |
| - } |
| + |
| + spin_lock_irqsave(&priv->tx_lock, flags); |
| |
| /* build tx descriptor */ |
| BDX_ASSERT(f->m.wptr >= f->m.memsz); /* started with valid wptr */ |
| --- a/drivers/net/rionet.c |
| +++ b/drivers/net/rionet.c |
| @@ -174,11 +174,7 @@ static int rionet_start_xmit(struct sk_b |
| unsigned long flags; |
| int add_num = 1; |
| |
| - local_irq_save(flags); |
| - if (!spin_trylock(&rnet->tx_lock)) { |
| - local_irq_restore(flags); |
| - return NETDEV_TX_LOCKED; |
| - } |
| + spin_lock_irqsave(&rnet->tx_lock, flags); |
| |
| if (is_multicast_ether_addr(eth->h_dest)) |
| add_num = nets[rnet->mport->id].nact; |