diff options
author | Divy Le Ray <divy@chelsio.com> | 2007-02-24 19:44:12 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-02-27 04:27:12 -0500 |
commit | bae73f44472921008f8d0982344c53ae231445a1 (patch) | |
tree | 11d1fe507ac8e179803c9468791952c9c217f66b /drivers | |
parent | 99d7cf30b99a8b7863090d8a510d6a4d9ad082cf (diff) |
cxgb3 - Recovery from HW starvation of response queue entries.
Improve the traffic recovery after the HW ran out of response queue entries.
Signed-off-by: Divy Le Ray <divy@chelsio.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/cxgb3/adapter.h | 2 | ||||
-rw-r--r-- | drivers/net/cxgb3/sge.c | 15 |
2 files changed, 16 insertions, 1 deletions
diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h index 5c97a64451ce..01b99b901434 100644 --- a/drivers/net/cxgb3/adapter.h +++ b/drivers/net/cxgb3/adapter.h | |||
@@ -121,6 +121,8 @@ struct sge_rspq { /* state for an SGE response queue */ | |||
121 | unsigned long empty; /* # of times queue ran out of credits */ | 121 | unsigned long empty; /* # of times queue ran out of credits */ |
122 | unsigned long nomem; /* # of responses deferred due to no mem */ | 122 | unsigned long nomem; /* # of responses deferred due to no mem */ |
123 | unsigned long unhandled_irqs; /* # of spurious intrs */ | 123 | unsigned long unhandled_irqs; /* # of spurious intrs */ |
124 | unsigned long starved; | ||
125 | unsigned long restarted; | ||
124 | }; | 126 | }; |
125 | 127 | ||
126 | struct tx_desc; | 128 | struct tx_desc; |
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index 822a598c0db1..4ff0ab60c6c7 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c | |||
@@ -2376,13 +2376,26 @@ static void sge_timer_cb(unsigned long data) | |||
2376 | spin_unlock(&qs->txq[TXQ_OFLD].lock); | 2376 | spin_unlock(&qs->txq[TXQ_OFLD].lock); |
2377 | } | 2377 | } |
2378 | lock = (adap->flags & USING_MSIX) ? &qs->rspq.lock : | 2378 | lock = (adap->flags & USING_MSIX) ? &qs->rspq.lock : |
2379 | &adap->sge.qs[0].rspq.lock; | 2379 | &adap->sge.qs[0].rspq.lock; |
2380 | if (spin_trylock_irq(lock)) { | 2380 | if (spin_trylock_irq(lock)) { |
2381 | if (!napi_is_scheduled(qs->netdev)) { | 2381 | if (!napi_is_scheduled(qs->netdev)) { |
2382 | u32 status = t3_read_reg(adap, A_SG_RSPQ_FL_STATUS); | ||
2383 | |||
2382 | if (qs->fl[0].credits < qs->fl[0].size) | 2384 | if (qs->fl[0].credits < qs->fl[0].size) |
2383 | __refill_fl(adap, &qs->fl[0]); | 2385 | __refill_fl(adap, &qs->fl[0]); |
2384 | if (qs->fl[1].credits < qs->fl[1].size) | 2386 | if (qs->fl[1].credits < qs->fl[1].size) |
2385 | __refill_fl(adap, &qs->fl[1]); | 2387 | __refill_fl(adap, &qs->fl[1]); |
2388 | |||
2389 | if (status & (1 << qs->rspq.cntxt_id)) { | ||
2390 | qs->rspq.starved++; | ||
2391 | if (qs->rspq.credits) { | ||
2392 | refill_rspq(adap, &qs->rspq, 1); | ||
2393 | qs->rspq.credits--; | ||
2394 | qs->rspq.restarted++; | ||
2395 | t3_write_reg(adap, A_SG_RSPQ_FL_STATUS, | ||
2396 | 1 << qs->rspq.cntxt_id); | ||
2397 | } | ||
2398 | } | ||
2386 | } | 2399 | } |
2387 | spin_unlock_irq(lock); | 2400 | spin_unlock_irq(lock); |
2388 | } | 2401 | } |