From d491f8ca2f36bc7edc5d63ddeeb2cf38b864555b Mon Sep 17 00:00:00 2001 From: Navdeep Parhar Date: Sat, 15 Apr 2017 17:00:50 +0000 Subject: [PATCH] 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...holdoff_timers shows the final values of the timers in microseconds. MFC after: 1 week Sponsored by: Chelsio Communications --- sys/dev/cxgbe/common/common.h | 2 +- sys/dev/cxgbe/common/t4_hw.c | 23 ++++++++++++++++------- sys/dev/cxgbe/t4_sge.c | 22 ++++++++++++++++++++++ 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/sys/dev/cxgbe/common/common.h b/sys/dev/cxgbe/common/common.h index e113b760de45..f1904fbdfca0 100644 --- a/sys/dev/cxgbe/common/common.h +++ b/sys/dev/cxgbe/common/common.h @@ -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; diff --git a/sys/dev/cxgbe/common/t4_hw.c b/sys/dev/cxgbe/common/t4_hw.c index 2843c4fd3742..af3a855bc6d1 100644 --- a/sys/dev/cxgbe/common/t4_hw.c +++ b/sys/dev/cxgbe/common/t4_hw.c @@ -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; diff --git a/sys/dev/cxgbe/t4_sge.c b/sys/dev/cxgbe/t4_sge.c index aa0a8a3b804e..4929e37ba49c 100644 --- a/sys/dev/cxgbe/t4_sge.c +++ b/sys/dev/cxgbe/t4_sge.c @@ -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);