| From 4a633714d8cd36f73f45d21968e3cd32ec1cf204 Mon Sep 17 00:00:00 2001 |
| From: Thomas Gleixner <tglx@linutronix.de> |
| Date: Sat, 20 Jun 2009 11:36:54 +0200 |
| Subject: [PATCH] drivers/net: fix livelock issues |
| |
| commit 6c37c1b53945ccc8aa55e1eac48bed3ef89bbde4 in tip. |
| |
| 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> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c |
| index 2f4be59..5b44d14 100644 |
| --- a/drivers/net/atl1c/atl1c_main.c |
| +++ b/drivers/net/atl1c/atl1c_main.c |
| @@ -2064,11 +2064,8 @@ 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 (skb->mark == 0x01) |
| type = atl1c_trans_high; |
| else |
| diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c |
| index 08f8c09..5df9cfd 100644 |
| --- a/drivers/net/atl1e/atl1e_main.c |
| +++ b/drivers/net/atl1e/atl1e_main.c |
| @@ -1823,8 +1823,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/chelsio/sge.c b/drivers/net/chelsio/sge.c |
| index 109d278..abd372a 100644 |
| --- a/drivers/net/chelsio/sge.c |
| +++ b/drivers/net/chelsio/sge.c |
| @@ -1671,8 +1671,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/rionet.c b/drivers/net/rionet.c |
| index ede937e..53345da 100644 |
| --- a/drivers/net/rionet.c |
| +++ b/drivers/net/rionet.c |
| @@ -175,11 +175,7 @@ static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev) |
| u16 destid; |
| unsigned long flags; |
| |
| - 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 ((rnet->tx_cnt + 1) > RIONET_TX_RING_SIZE) { |
| netif_stop_queue(ndev); |
| diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c |
| index 3c4836d..9984903 100644 |
| --- a/drivers/net/s2io.c |
| +++ b/drivers/net/s2io.c |
| @@ -4146,12 +4146,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/sungem.c b/drivers/net/sungem.c |
| index b571a1b..c3a1180 100644 |
| --- a/drivers/net/sungem.c |
| +++ b/drivers/net/sungem.c |
| @@ -1034,10 +1034,8 @@ static netdev_tx_t gem_start_xmit(struct sk_buff *skb, |
| (csum_stuff_off << 21)); |
| } |
| |
| - if (!spin_trylock_irqsave(&gp->tx_lock, flags)) { |
| - /* Tell upper layer to requeue */ |
| - return NETDEV_TX_LOCKED; |
| - } |
| + spin_lock_irqsave(&gp->tx_lock, flags); |
| + |
| /* We raced with gem_do_stop() */ |
| if (!gp->running) { |
| spin_unlock_irqrestore(&gp->tx_lock, flags); |
| diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c |
| index 80b404f..1013891 100644 |
| --- a/drivers/net/tehuti.c |
| +++ b/drivers/net/tehuti.c |
| @@ -1639,13 +1639,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 */ |
| -- |
| 1.7.1.1 |
| |