| From beb72f006bb5f8f5d7e632f057abe93882218aba Mon Sep 17 00:00:00 2001 |
| From: Thomas Gleixner <tglx@linutronix.de> |
| Date: Sat, 20 Jun 2009 11:36:54 +0200 |
| Subject: [PATCH 083/274] 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 | 7 +++---- |
| drivers/net/ethernet/tehuti/tehuti.c | 9 ++------- |
| drivers/net/rionet.c | 6 +----- |
| 7 files changed, 10 insertions(+), 31 deletions(-) |
| |
| diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c |
| index 65fe632..47520ad 100644 |
| --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c |
| +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c |
| @@ -2239,11 +2239,7 @@ static netdev_tx_t atl1c_xmit_frame(struct sk_buff *skb, |
| } |
| |
| 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 */ |
| diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c |
| index 93ff2b2..cecc414 100644 |
| --- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c |
| +++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c |
| @@ -1822,8 +1822,7 @@ static netdev_tx_t atl1e_xmit_frame(struct sk_buff *skb, |
| 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 */ |
| diff --git a/drivers/net/ethernet/chelsio/cxgb/sge.c b/drivers/net/ethernet/chelsio/cxgb/sge.c |
| index 47a8435..279c04e 100644 |
| --- a/drivers/net/ethernet/chelsio/cxgb/sge.c |
| +++ b/drivers/net/ethernet/chelsio/cxgb/sge.c |
| @@ -1678,8 +1678,7 @@ static int t1_sge_tx(struct sk_buff *skb, struct adapter *adapter, |
| 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); |
| |
| diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c |
| index 6338ef8..ad2f094 100644 |
| --- 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_buff *skb, struct net_device *dev) |
| [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)) { |
| diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c |
| index 1e38d50..f017954 100644 |
| --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c |
| +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c |
| @@ -2128,10 +2128,9 @@ static int pch_gbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev) |
| adapter->stats.tx_length_errors++; |
| return NETDEV_TX_OK; |
| } |
| - 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); |
| diff --git a/drivers/net/ethernet/tehuti/tehuti.c b/drivers/net/ethernet/tehuti/tehuti.c |
| index ad973ff..1afa33c 100644 |
| --- a/drivers/net/ethernet/tehuti/tehuti.c |
| +++ b/drivers/net/ethernet/tehuti/tehuti.c |
| @@ -1606,13 +1606,8 @@ static netdev_tx_t bdx_tx_transmit(struct sk_buff *skb, |
| 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 */ |
| diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c |
| index 1470d3e..8873a3b 100644 |
| --- a/drivers/net/rionet.c |
| +++ b/drivers/net/rionet.c |
| @@ -178,11 +178,7 @@ static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev) |
| 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 = nact; |
| -- |
| 1.7.10.4 |
| |