Commit 26b3871d authored by Divy Le Ray's avatar Divy Le Ray Committed by David S. Miller
Browse files

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: default avatarDivy Le Ray <divy@chelsio.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ff5e2b47
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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 */
+24 −8
Original line number Diff line number Diff line
@@ -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: