aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDivy Le Ray <divy@chelsio.com>2007-02-24 19:44:12 -0500
committerJeff Garzik <jeff@garzik.org>2007-02-27 04:27:12 -0500
commitbae73f44472921008f8d0982344c53ae231445a1 (patch)
tree11d1fe507ac8e179803c9468791952c9c217f66b /drivers
parent99d7cf30b99a8b7863090d8a510d6a4d9ad082cf (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.h2
-rw-r--r--drivers/net/cxgb3/sge.c15
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
126struct tx_desc; 128struct 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 }