* [PATCH] net: gainfar: fix race between issuing and completing Tx
@ 2013-12-06 12:35 Nikita Yushchenko
2013-12-10 1:29 ` David Miller
0 siblings, 1 reply; 2+ messages in thread
From: Nikita Yushchenko @ 2013-12-06 12:35 UTC (permalink / raw)
To: David S. Miller, Claudiu Manoil, netdev
Cc: linux-kernel, Dmitry Krivoschekov, Konstantin Baydarov,
Nikita Yushchenko
gfar_poll() checked Tx queue status without locking, thus allowing
gfar_start_xmit() to alter it in parallel, which caused hang on every
other nfsroot boot with RT enabled.
This patch raises locking from gfar_clean_tx_ring() up to gfar_poll().
With this change applied, hangs are no longer reproduced.
Signed-off-by: Nikita Yushchenko <nyushchenko@dev.rtsoft.ru>
---
drivers/net/ethernet/freescale/gianfar.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index 0343a14..9ac1946 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -2499,7 +2499,6 @@ static void gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
skb_dirtytx = tx_queue->skb_dirtytx;
while ((skb = tx_queue->tx_skbuff[skb_dirtytx])) {
- unsigned long flags;
frags = skb_shinfo(skb)->nr_frags;
@@ -2561,9 +2560,7 @@ static void gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
TX_RING_MOD_MASK(tx_ring_size);
howmany++;
- spin_lock_irqsave(&tx_queue->txlock, flags);
tx_queue->num_txbdfree += nr_txbds;
- spin_unlock_irqrestore(&tx_queue->txlock, flags);
}
/* If we freed a buffer, we can restart transmission, if necessary */
@@ -2838,6 +2835,7 @@ static int gfar_poll(struct napi_struct *napi, int budget)
int has_tx_work;
unsigned long rstat_rxf;
int num_act_queues;
+ unsigned long flags;
/* Clear IEVENT, so interrupts aren't called again
* because of the packets that have already arrived
@@ -2854,11 +2852,13 @@ static int gfar_poll(struct napi_struct *napi, int budget)
has_tx_work = 0;
for_each_set_bit(i, &gfargrp->tx_bit_map, priv->num_tx_queues) {
tx_queue = priv->tx_queue[i];
+ spin_lock_irqsave(&tx_queue->txlock, flags);
/* run Tx cleanup to completion */
if (tx_queue->tx_skbuff[tx_queue->skb_dirtytx]) {
gfar_clean_tx_ring(tx_queue);
has_tx_work = 1;
}
+ spin_unlock_irqrestore(&tx_queue->txlock, flags);
}
for_each_set_bit(i, &gfargrp->rx_bit_map, priv->num_rx_queues) {
--
1.7.0.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] net: gainfar: fix race between issuing and completing Tx
2013-12-06 12:35 [PATCH] net: gainfar: fix race between issuing and completing Tx Nikita Yushchenko
@ 2013-12-10 1:29 ` David Miller
0 siblings, 0 replies; 2+ messages in thread
From: David Miller @ 2013-12-10 1:29 UTC (permalink / raw)
To: nyushchenko
Cc: claudiu.manoil, netdev, linux-kernel, dkrivoschokov, kbaidarov
From: Nikita Yushchenko <nyushchenko@dev.rtsoft.ru>
Date: Fri, 6 Dec 2013 16:35:59 +0400
> gfar_poll() checked Tx queue status without locking, thus allowing
> gfar_start_xmit() to alter it in parallel, which caused hang on every
> other nfsroot boot with RT enabled.
>
> This patch raises locking from gfar_clean_tx_ring() up to gfar_poll().
> With this change applied, hangs are no longer reproduced.
>
> Signed-off-by: Nikita Yushchenko <nyushchenko@dev.rtsoft.ru>
This is not sufficient.
You've left a huge comment in gfar_start_xmit() which explains that
the current locking is correct.
Whoever wrote that comment thought there were no problems with the
current arrangement.
If you want to change it, you have to adjust this comment, and also
explain exactly what races without your proposed change.
If you are going to take this lock, you might want to consider using
netif_tx_lock() since that is held across the entirety of any
netdev_ops->ndo_start_xmit() invocation.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2013-12-10 1:29 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-12-06 12:35 [PATCH] net: gainfar: fix race between issuing and completing Tx Nikita Yushchenko
2013-12-10 1:29 ` David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).