diff options
-rw-r--r-- | drivers/net/cxgb3/adapter.h | 1 | ||||
-rw-r--r-- | drivers/net/cxgb3/sge.c | 32 |
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; | |||
91 | struct sge_fl { /* SGE per free-buffer list state */ | 91 | struct 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 | ||
430 | static 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 | ||
491 | static inline void __refill_fl(struct adapter *adap, struct sge_fl *fl) | 503 | static 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 | ||
738 | use_orig_buf: | 754 | use_orig_buf: |