| From 2d5eaf3f046351244c97c2bc59b7ff8013ceb005 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> |
| --- |
| drivers/net/atl1c/atl1c_main.c | 7 ++----- |
| drivers/net/atl1e/atl1e_main.c | 3 +-- |
| drivers/net/chelsio/sge.c | 3 +-- |
| drivers/net/rionet.c | 6 +----- |
| drivers/net/s2io.c | 7 +------ |
| drivers/net/sungem.c | 6 ++---- |
| drivers/net/tehuti.c | 9 ++------- |
| 7 files changed, 10 insertions(+), 31 deletions(-) |
| |
| diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c |
| index 50dc531..a9c0b58 100644 |
| --- a/drivers/net/atl1c/atl1c_main.c |
| +++ b/drivers/net/atl1c/atl1c_main.c |
| @@ -2159,11 +2159,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 73302ae..a80e796 100644 |
| --- a/drivers/net/atl1e/atl1e_main.c |
| +++ b/drivers/net/atl1e/atl1e_main.c |
| @@ -1810,8 +1810,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 df3a141..8886c16 100644 |
| --- a/drivers/net/chelsio/sge.c |
| +++ b/drivers/net/chelsio/sge.c |
| @@ -1672,8 +1672,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 07eb884..5e82a12 100644 |
| --- a/drivers/net/rionet.c |
| +++ b/drivers/net/rionet.c |
| @@ -176,11 +176,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 92ae8d3..7e57dc4 100644 |
| --- a/drivers/net/s2io.c |
| +++ b/drivers/net/s2io.c |
| @@ -4147,12 +4147,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 e6880f1..d104520 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 f549309..6882943 100644 |
| --- a/drivers/net/tehuti.c |
| +++ b/drivers/net/tehuti.c |
| @@ -1633,13 +1633,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.0.4 |
| |