Date: Thu, 7 Jul 2022 17:25:02 +0200 From: Sebastian Huber <sebastian.huber@embedded-brains.de> To: freebsd-hackers@freebsd.org Subject: [PATCH 2/6] pps: Simplify capture and event processing Message-ID: <20220707152506.55626-3-sebastian.huber@embedded-brains.de> In-Reply-To: <20220707152506.55626-1-sebastian.huber@embedded-brains.de> References: <20220707152506.55626-1-sebastian.huber@embedded-brains.de>
next in thread | previous in thread | raw e-mail | index | archive | help
Use local variables for the captured timehand and timecounter in pps_even= t(). This fixes a potential issue in the nsec preparation for hardpps(). Here= the timecounter was accessed through the captured timehand after the generati= on was checked. Make a snapshot of the relevent timehand values early in pps_event(). Ch= eck the timehand generation only once during the capture and event processing= . Use atomic_thread_fence_acq() similar to the other readers. --- sys/kern/kern_tc.c | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c index 20520adc0aba..b466fd4399e4 100644 --- a/sys/kern/kern_tc.c +++ b/sys/kern/kern_tc.c @@ -1772,14 +1772,14 @@ pps_capture(struct pps_state *pps) #endif tc =3D th->th_counter; pps->capcount =3D tc->tc_get_timecount(tc); - atomic_thread_fence_acq(); - if (pps->capgen !=3D th->th_generation) - pps->capgen =3D 0; } =20 void pps_event(struct pps_state *pps, int event) { + struct timehands *capth; + struct timecounter *captc; + uint64_t capth_scale; struct bintime bt; struct timespec ts, *tsp, *osp; u_int tcount, *pcount; @@ -1798,9 +1798,17 @@ pps_event(struct pps_state *pps, int event) /* Nothing to do if not currently set to capture this event type. */ if ((event & pps->ppsparam.mode) =3D=3D 0) return; + + /* Make a snapshot of the captured timehand */ + capth =3D pps->capth; + captc =3D capth->th_counter; + capth_scale =3D capth->th_scale; + tcount =3D capth->th_offset_count; + bt =3D capth->th_bintime; + /* If the timecounter was wound up underneath us, bail out. */ - if (pps->capgen =3D=3D 0 || pps->capgen !=3D - atomic_load_acq_int(&pps->capth->th_generation)) + atomic_thread_fence_acq(); + if (pps->capgen =3D=3D 0 || pps->capgen !=3D capth->th_generation) return; =20 /* Things would be easier with arrays. */ @@ -1838,25 +1846,19 @@ pps_event(struct pps_state *pps, int event) * If the timecounter changed, we cannot compare the count values, so * we have to drop the rest of the PPS-stuff until the next event. */ - if (pps->ppstc !=3D pps->capth->th_counter) { - pps->ppstc =3D pps->capth->th_counter; + if (__predict_false(pps->ppstc !=3D captc)) { + pps->ppstc =3D captc; *pcount =3D pps->capcount; pps->ppscount[2] =3D pps->capcount; return; } =20 /* Convert the count to a timespec. */ - tcount =3D pps->capcount - pps->capth->th_offset_count; - tcount &=3D pps->capth->th_counter->tc_counter_mask; - bt =3D pps->capth->th_bintime; - bintime_addx(&bt, pps->capth->th_scale * tcount); + tcount =3D pps->capcount - tcount; + tcount &=3D captc->tc_counter_mask; + bintime_addx(&bt, capth_scale * tcount); bintime2timespec(&bt, &ts); =20 - /* If the timecounter was wound up underneath us, bail out. */ - atomic_thread_fence_acq(); - if (pps->capgen !=3D pps->capth->th_generation) - return; - *pcount =3D pps->capcount; (*pseq)++; *tsp =3D ts; @@ -1890,9 +1892,9 @@ pps_event(struct pps_state *pps, int event) */ tcount =3D pps->capcount - pps->ppscount[2]; pps->ppscount[2] =3D pps->capcount; - tcount &=3D pps->capth->th_counter->tc_counter_mask; + tcount &=3D captc->tc_counter_mask; scale =3D (uint64_t)1 << 63; - scale /=3D pps->capth->th_counter->tc_frequency; + scale /=3D captc->tc_frequency; scale *=3D 2; bt.sec =3D 0; bt.frac =3D 0; --=20 2.35.3
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20220707152506.55626-3-sebastian.huber>