git: f771c03297b0 - stable/13 - cxgbe: Use secq(9) to manage the timestamp generations.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 11 Nov 2022 01:48:24 UTC
The branch stable/13 has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=f771c03297b0b187c63365aac061346748388e6d commit f771c03297b0b187c63365aac061346748388e6d Author: John Baldwin <jhb@FreeBSD.org> AuthorDate: 2022-09-26 21:58:06 +0000 Commit: John Baldwin <jhb@FreeBSD.org> CommitDate: 2022-11-11 01:26:44 +0000 cxgbe: Use secq(9) to manage the timestamp generations. This is mostly cosmetic, but it also doesn't leave a gap of time where no structures are valid. Instead, we permit the ISR to continue to use the previous structure if the write to update cal_current isn't yet visible. Reviewed by: gallatin Sponsored by: Chelsio Communications Differential Revision: https://reviews.freebsd.org/D36669 (cherry picked from commit cee4fc7cada8244f375a6542f03d1f255c719bf1) --- sys/dev/cxgbe/adapter.h | 3 ++- sys/dev/cxgbe/t4_main.c | 28 +++++++++++++++++----------- sys/dev/cxgbe/t4_sge.c | 11 ++++++----- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/sys/dev/cxgbe/adapter.h b/sys/dev/cxgbe/adapter.h index 4d246512b868..9e6ccaf31754 100644 --- a/sys/dev/cxgbe/adapter.h +++ b/sys/dev/cxgbe/adapter.h @@ -41,6 +41,7 @@ #include <sys/lock.h> #include <sys/malloc.h> #include <sys/rwlock.h> +#include <sys/seqc.h> #include <sys/sx.h> #include <sys/vmem.h> #include <vm/uma.h> @@ -867,7 +868,7 @@ struct clock_sync { uint64_t hw_prev; sbintime_t sbt_cur; sbintime_t sbt_prev; - uint32_t gen; + seqc_t gen; }; struct adapter { diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c index eff4db09aa12..b21b5a795fe3 100644 --- a/sys/dev/cxgbe/t4_main.c +++ b/sys/dev/cxgbe/t4_main.c @@ -1115,35 +1115,41 @@ t4_calibration(void *arg) { struct adapter *sc; struct clock_sync *cur, *nex; + uint64_t hw; + sbintime_t sbt; int next_up; sc = (struct adapter *)arg; + KASSERT((hw_off_limits(sc) == 0), ("hw_off_limits at t4_calibration")); + hw = t4_read_reg64(sc, A_SGE_TIMESTAMP_LO); + sbt = sbinuptime(); + cur = &sc->cal_info[sc->cal_current]; next_up = (sc->cal_current + 1) % CNT_CAL_INFO; nex = &sc->cal_info[next_up]; if (__predict_false(sc->cal_count == 0)) { /* First time in, just get the values in */ - cur->hw_cur = t4_read_reg64(sc, A_SGE_TIMESTAMP_LO); - cur->sbt_cur = sbinuptime(); + cur->hw_cur = hw; + cur->sbt_cur = sbt; sc->cal_count++; goto done; } - nex->hw_prev = cur->hw_cur; - nex->sbt_prev = cur->sbt_cur; - KASSERT((hw_off_limits(sc) == 0), ("hw_off_limits at t4_calibration")); - nex->hw_cur = t4_read_reg64(sc, A_SGE_TIMESTAMP_LO); - nex->sbt_cur = sbinuptime(); - if ((nex->hw_cur - nex->hw_prev) == 0) { + + if (cur->hw_cur == hw) { /* The clock is not advancing? */ sc->cal_count = 0; atomic_store_rel_int(&cur->gen, 0); goto done; } - atomic_store_rel_int(&cur->gen, 0); + + seqc_write_begin(&nex->gen); + nex->hw_prev = cur->hw_cur; + nex->sbt_prev = cur->sbt_cur; + nex->hw_cur = hw; + nex->sbt_cur = sbt; + seqc_write_end(&nex->gen); sc->cal_current = next_up; - sc->cal_gen++; - atomic_store_rel_int(&nex->gen, sc->cal_gen); done: callout_reset_sbt_curcpu(&sc->cal_callout, SBT_1S, 0, t4_calibration, sc, C_DIRECT_EXEC); diff --git a/sys/dev/cxgbe/t4_sge.c b/sys/dev/cxgbe/t4_sge.c index fc8a55111a4c..defd7d996f10 100644 --- a/sys/dev/cxgbe/t4_sge.c +++ b/sys/dev/cxgbe/t4_sge.c @@ -1520,16 +1520,17 @@ t4_tstmp_to_ns(struct adapter *sc, uint64_t lf) uint64_t hw_clk_div; sbintime_t sbt_cur_to_prev, sbt; uint64_t hw_tstmp = lf & 0xfffffffffffffffULL; /* 60b, not 64b. */ - uint32_t gen; + seqc_t gen; - do { + for (;;) { cur = &sc->cal_info[sc->cal_current]; - gen = atomic_load_acq_int(&cur->gen); + gen = seqc_read(&cur->gen); if (gen == 0) return (0); dcur = *cur; - atomic_thread_fence_acq(); - } while (gen != dcur.gen); + if (seqc_consistent(&cur->gen, gen)) + break; + } /* * Our goal here is to have a result that is: