diff options
author | Lennert Buytenhek <buytenh@wantstofly.org> | 2008-08-23 19:59:05 -0400 |
---|---|---|
committer | Lennert Buytenhek <buytenh@marvell.com> | 2008-08-23 21:33:02 -0400 |
commit | 92c70f27d2a78873c940e77c7f075cd8e2e60a2d (patch) | |
tree | 837c9ba98d2140b551a48e758920598416d8419d | |
parent | 819ddcafb33136f2ba18018a22edcf857f640528 (diff) |
mv643xx_eth: fix double add_timer() on the receive oom timer
Commit 12e4ab79cd828563dc090d2117dc8626b344bc8f ("mv643xx_eth: be
more agressive about RX refill") changed the condition for the receive
out-of-memory timer to be scheduled from "the receive ring is empty"
to "the receive ring is not full".
This can lead to a situation where the receive out-of-memory timer is
pending because a previous rxq_refill() didn't manage to refill the
receive ring entirely as a result of being out of memory, and
rxq_refill() is then called again as a side effect of a packet receive
interrupt, and that rxq_refill() call then again does not succeed to
refill the entire receive ring with fresh empty skbuffs because we are
still out of memory, and then tries to call add_timer() on the already
scheduled out-of-memory timer.
This patch fixes this issue by changing the add_timer() call in
rxq_refill() to a mod_timer() call. If the OOM timer was not already
scheduled, this will behave as before, whereas if it was already
scheduled, this patch will push back its firing time a bit, which is
safe because we've (unsuccessfully) attempted to refill the receive
ring just before we do this.
Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
-rw-r--r-- | drivers/net/mv643xx_eth.c | 6 |
1 files changed, 2 insertions, 4 deletions
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index af279f26c407..8a91d79383dd 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c | |||
@@ -509,10 +509,8 @@ static void rxq_refill(struct rx_queue *rxq) | |||
509 | skb_reserve(skb, 2); | 509 | skb_reserve(skb, 2); |
510 | } | 510 | } |
511 | 511 | ||
512 | if (rxq->rx_desc_count != rxq->rx_ring_size) { | 512 | if (rxq->rx_desc_count != rxq->rx_ring_size) |
513 | rxq->rx_oom.expires = jiffies + (HZ / 10); | 513 | mod_timer(&rxq->rx_oom, jiffies + (HZ / 10)); |
514 | add_timer(&rxq->rx_oom); | ||
515 | } | ||
516 | 514 | ||
517 | spin_unlock_irqrestore(&mp->lock, flags); | 515 | spin_unlock_irqrestore(&mp->lock, flags); |
518 | } | 516 | } |