aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/cxgb3/adapter.h1
-rw-r--r--drivers/net/cxgb3/sge.c32
2 files changed, 25 insertions, 8 deletions
diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h
index fbe15699584e..95dce4832478 100644
--- a/drivers/net/cxgb3/adapter.h
+++ b/drivers/net/cxgb3/adapter.h
@@ -91,6 +91,7 @@ struct rx_sw_desc;
91struct sge_fl { /* SGE per free-buffer list state */ 91struct sge_fl { /* SGE per free-buffer list state */
92 unsigned int buf_size; /* size of each Rx buffer */ 92 unsigned int buf_size; /* size of each Rx buffer */
93 unsigned int credits; /* # of available Rx buffers */ 93 unsigned int credits; /* # of available Rx buffers */
94 unsigned int pend_cred; /* new buffers since last FL DB ring */
94 unsigned int size; /* capacity of free list */ 95 unsigned int size; /* capacity of free list */
95 unsigned int cidx; /* consumer index */ 96 unsigned int cidx; /* consumer index */
96 unsigned int pidx; /* producer index */ 97 unsigned int pidx; /* producer index */
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index 8205aa4ae945..882beafeb74c 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -63,6 +63,10 @@
63#define SGE_RX_DROP_THRES 16 63#define SGE_RX_DROP_THRES 16
64 64
65/* 65/*
66 * Max number of Rx buffers we replenish at a time.
67 */
68#define MAX_RX_REFILL 16U
69/*
66 * Period of the Tx buffer reclaim timer. This timer does not need to run 70 * Period of the Tx buffer reclaim timer. This timer does not need to run
67 * frequently as Tx buffers are usually reclaimed by new Tx packets. 71 * frequently as Tx buffers are usually reclaimed by new Tx packets.
68 */ 72 */
@@ -423,6 +427,14 @@ static int alloc_pg_chunk(struct sge_fl *q, struct rx_sw_desc *sd, gfp_t gfp,
423 return 0; 427 return 0;
424} 428}
425 429
430static inline void ring_fl_db(struct adapter *adap, struct sge_fl *q)
431{
432 if (q->pend_cred >= q->credits / 4) {
433 q->pend_cred = 0;
434 t3_write_reg(adap, A_SG_KDOORBELL, V_EGRCNTX(q->cntxt_id));
435 }
436}
437
426/** 438/**
427 * refill_fl - refill an SGE free-buffer list 439 * refill_fl - refill an SGE free-buffer list
428 * @adapter: the adapter 440 * @adapter: the adapter
@@ -478,19 +490,19 @@ nomem: q->alloc_failed++;
478 sd = q->sdesc; 490 sd = q->sdesc;
479 d = q->desc; 491 d = q->desc;
480 } 492 }
481 q->credits++;
482 count++; 493 count++;
483 } 494 }
484 wmb(); 495
485 if (likely(count)) 496 q->credits += count;
486 t3_write_reg(adap, A_SG_KDOORBELL, V_EGRCNTX(q->cntxt_id)); 497 q->pend_cred += count;
498 ring_fl_db(adap, q);
487 499
488 return count; 500 return count;
489} 501}
490 502
491static inline void __refill_fl(struct adapter *adap, struct sge_fl *fl) 503static inline void __refill_fl(struct adapter *adap, struct sge_fl *fl)
492{ 504{
493 refill_fl(adap, fl, min(16U, fl->size - fl->credits), 505 refill_fl(adap, fl, min(MAX_RX_REFILL, fl->size - fl->credits),
494 GFP_ATOMIC | __GFP_COMP); 506 GFP_ATOMIC | __GFP_COMP);
495} 507}
496 508
@@ -515,13 +527,15 @@ static void recycle_rx_buf(struct adapter *adap, struct sge_fl *q,
515 wmb(); 527 wmb();
516 to->len_gen = cpu_to_be32(V_FLD_GEN1(q->gen)); 528 to->len_gen = cpu_to_be32(V_FLD_GEN1(q->gen));
517 to->gen2 = cpu_to_be32(V_FLD_GEN2(q->gen)); 529 to->gen2 = cpu_to_be32(V_FLD_GEN2(q->gen));
518 q->credits++;
519 530
520 if (++q->pidx == q->size) { 531 if (++q->pidx == q->size) {
521 q->pidx = 0; 532 q->pidx = 0;
522 q->gen ^= 1; 533 q->gen ^= 1;
523 } 534 }
524 t3_write_reg(adap, A_SG_KDOORBELL, V_EGRCNTX(q->cntxt_id)); 535
536 q->credits++;
537 q->pend_cred++;
538 ring_fl_db(adap, q);
525} 539}
526 540
527/** 541/**
@@ -732,7 +746,9 @@ recycle:
732 return skb; 746 return skb;
733 } 747 }
734 748
735 if (unlikely(fl->credits < drop_thres)) 749 if (unlikely(fl->credits < drop_thres) &&
750 refill_fl(adap, fl, min(MAX_RX_REFILL, fl->size - fl->credits - 1),
751 GFP_ATOMIC | __GFP_COMP) == 0)
736 goto recycle; 752 goto recycle;
737 753
738use_orig_buf: 754use_orig_buf: