cxgb3: ring rx door bell less frequently

Ring free lists door bell less frequently,
specifically every quarter of the active FL
size.

Signed-off-by: Divy Le Ray <divy@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Divy Le Ray 2009-03-12 21:13:43 +00:00 коммит произвёл David S. Miller
Родитель ff5e2b4732
Коммит 26b3871d2c
2 изменённых файлов: 25 добавлений и 8 удалений

Просмотреть файл

@ -91,6 +91,7 @@ struct rx_sw_desc;
struct sge_fl { /* SGE per free-buffer list state */
unsigned int buf_size; /* size of each Rx buffer */
unsigned int credits; /* # of available Rx buffers */
unsigned int pend_cred; /* new buffers since last FL DB ring */
unsigned int size; /* capacity of free list */
unsigned int cidx; /* consumer index */
unsigned int pidx; /* producer index */

Просмотреть файл

@ -62,6 +62,10 @@
#define SGE_RX_DROP_THRES 16
/*
* Max number of Rx buffers we replenish at a time.
*/
#define MAX_RX_REFILL 16U
/*
* Period of the Tx buffer reclaim timer. This timer does not need to run
* frequently as Tx buffers are usually reclaimed by new Tx packets.
@ -423,6 +427,14 @@ static int alloc_pg_chunk(struct sge_fl *q, struct rx_sw_desc *sd, gfp_t gfp,
return 0;
}
static inline void ring_fl_db(struct adapter *adap, struct sge_fl *q)
{
if (q->pend_cred >= q->credits / 4) {
q->pend_cred = 0;
t3_write_reg(adap, A_SG_KDOORBELL, V_EGRCNTX(q->cntxt_id));
}
}
/**
* refill_fl - refill an SGE free-buffer list
* @adapter: the adapter
@ -478,19 +490,19 @@ nomem: q->alloc_failed++;
sd = q->sdesc;
d = q->desc;
}
q->credits++;
count++;
}
wmb();
if (likely(count))
t3_write_reg(adap, A_SG_KDOORBELL, V_EGRCNTX(q->cntxt_id));
q->credits += count;
q->pend_cred += count;
ring_fl_db(adap, q);
return count;
}
static inline void __refill_fl(struct adapter *adap, struct sge_fl *fl)
{
refill_fl(adap, fl, min(16U, fl->size - fl->credits),
refill_fl(adap, fl, min(MAX_RX_REFILL, fl->size - fl->credits),
GFP_ATOMIC | __GFP_COMP);
}
@ -515,13 +527,15 @@ static void recycle_rx_buf(struct adapter *adap, struct sge_fl *q,
wmb();
to->len_gen = cpu_to_be32(V_FLD_GEN1(q->gen));
to->gen2 = cpu_to_be32(V_FLD_GEN2(q->gen));
q->credits++;
if (++q->pidx == q->size) {
q->pidx = 0;
q->gen ^= 1;
}
t3_write_reg(adap, A_SG_KDOORBELL, V_EGRCNTX(q->cntxt_id));
q->credits++;
q->pend_cred++;
ring_fl_db(adap, q);
}
/**
@ -732,7 +746,9 @@ recycle:
return skb;
}
if (unlikely(fl->credits < drop_thres))
if (unlikely(fl->credits < drop_thres) &&
refill_fl(adap, fl, min(MAX_RX_REFILL, fl->size - fl->credits - 1),
GFP_ATOMIC | __GFP_COMP) == 0)
goto recycle;
use_orig_buf: