cxgbe: Add a tunable to configure the SGE time scaler, which is

available starting with T6.  The values in the timer holdoff registers
are multiplied by the scaling factor before use.

dev.<nexus>.<n>.holdoff_timers shows the final values of the
timers in microseconds.

MFC after:	1 week
Sponsored by:	Chelsio Communications
This commit is contained in:
Navdeep Parhar 2017-04-15 17:00:50 +00:00
parent 7752043c9d
commit d491f8ca2f
3 changed files with 39 additions and 8 deletions

View File

@ -210,7 +210,7 @@ struct tp_rdma_stats {
};
struct sge_params {
int timer_val[SGE_NTIMERS];
int timer_val[SGE_NTIMERS]; /* final, scaled values */
int counter_val[SGE_NCOUNTERS];
int fl_starve_threshold;
int fl_starve_threshold2;

View File

@ -7907,7 +7907,7 @@ int t4_init_sge_params(struct adapter *adapter)
{
u32 r;
struct sge_params *sp = &adapter->params.sge;
unsigned i;
unsigned i, tscale = 1;
r = t4_read_reg(adapter, A_SGE_INGRESS_RX_THRESHOLD);
sp->counter_val[0] = G_THRESHOLD_0(r);
@ -7915,15 +7915,24 @@ int t4_init_sge_params(struct adapter *adapter)
sp->counter_val[2] = G_THRESHOLD_2(r);
sp->counter_val[3] = G_THRESHOLD_3(r);
if (chip_id(adapter) >= CHELSIO_T6) {
r = t4_read_reg(adapter, A_SGE_ITP_CONTROL);
tscale = G_TSCALE(r);
if (tscale == 0)
tscale = 1;
else
tscale += 2;
}
r = t4_read_reg(adapter, A_SGE_TIMER_VALUE_0_AND_1);
sp->timer_val[0] = core_ticks_to_us(adapter, G_TIMERVALUE0(r));
sp->timer_val[1] = core_ticks_to_us(adapter, G_TIMERVALUE1(r));
sp->timer_val[0] = core_ticks_to_us(adapter, G_TIMERVALUE0(r)) * tscale;
sp->timer_val[1] = core_ticks_to_us(adapter, G_TIMERVALUE1(r)) * tscale;
r = t4_read_reg(adapter, A_SGE_TIMER_VALUE_2_AND_3);
sp->timer_val[2] = core_ticks_to_us(adapter, G_TIMERVALUE2(r));
sp->timer_val[3] = core_ticks_to_us(adapter, G_TIMERVALUE3(r));
sp->timer_val[2] = core_ticks_to_us(adapter, G_TIMERVALUE2(r)) * tscale;
sp->timer_val[3] = core_ticks_to_us(adapter, G_TIMERVALUE3(r)) * tscale;
r = t4_read_reg(adapter, A_SGE_TIMER_VALUE_4_AND_5);
sp->timer_val[4] = core_ticks_to_us(adapter, G_TIMERVALUE4(r));
sp->timer_val[5] = core_ticks_to_us(adapter, G_TIMERVALUE5(r));
sp->timer_val[4] = core_ticks_to_us(adapter, G_TIMERVALUE4(r)) * tscale;
sp->timer_val[5] = core_ticks_to_us(adapter, G_TIMERVALUE5(r)) * tscale;
r = t4_read_reg(adapter, A_SGE_CONM_CTRL);
sp->fl_starve_threshold = G_EGRTHRESHOLD(r) * 2 + 1;

View File

@ -150,6 +150,13 @@ TUNABLE_INT("hw.cxgbe.largest_rx_cluster", &largest_rx_cluster);
static int safest_rx_cluster = PAGE_SIZE;
TUNABLE_INT("hw.cxgbe.safest_rx_cluster", &safest_rx_cluster);
/*
* The interrupt holdoff timers are multiplied by this value on T6+.
* 1 and 3-17 (both inclusive) are legal values.
*/
static int tscale = 1;
TUNABLE_INT("hw.cxgbe.tscale", &tscale);
struct txpkts {
u_int wr_type; /* type 0 or type 1 */
u_int npkt; /* # of packets in this work request */
@ -391,6 +398,12 @@ t4_sge_modload(void)
cong_drop = 0;
}
if (tscale != 1 && (tscale < 3 || tscale > 17)) {
printf("Invalid hw.cxgbe.tscale value (%d),"
" using 1 instead.\n", tscale);
tscale = 1;
}
extfree_refs = counter_u64_alloc(M_WAITOK);
extfree_rels = counter_u64_alloc(M_WAITOK);
counter_u64_zero(extfree_refs);
@ -583,6 +596,15 @@ t4_tweak_chip_settings(struct adapter *sc)
V_TIMERVALUE5(us_to_core_ticks(sc, intr_timer[5]));
t4_write_reg(sc, A_SGE_TIMER_VALUE_4_AND_5, v);
if (chip_id(sc) >= CHELSIO_T6) {
m = V_TSCALE(M_TSCALE);
if (tscale == 1)
v = 0;
else
v = V_TSCALE(tscale - 2);
t4_set_reg_field(sc, A_SGE_ITP_CONTROL, m, v);
}
/* 4K, 16K, 64K, 256K DDP "page sizes" for TDDP */
v = V_HPZ0(0) | V_HPZ1(2) | V_HPZ2(4) | V_HPZ3(6);
t4_write_reg(sc, A_ULP_RX_TDDP_PSZ, v);