dt(4): move interval/profile entry points to dedicated clockintr callback
authorcheloha <cheloha@openbsd.org>
Fri, 9 Feb 2024 17:42:18 +0000 (17:42 +0000)
committercheloha <cheloha@openbsd.org>
Fri, 9 Feb 2024 17:42:18 +0000 (17:42 +0000)
commitc56c27b6fbb4ff0f6c0243877f7595614e0bb92e
treef4fde5540c5da991ae616fb10e53707c32558d98
parent0d53143dca7c4d83472683f12d7e8cfeb031a881
dt(4): move interval/profile entry points to dedicated clockintr callback

To improve the utility of dt(4)'s interval and profile probes we need
to move the probe entry points from the fixed-frequency hardclock() to
a dedicated clock interrupt callback so that the probes can fire at
arbitrary frequencies.

- Remove entry points for interval/profile probes from hardclock().

- Merge dt_prov_profile_enter(), dt_prov_interval_enter(), and
  dt_prov_profile_fire() into one function, dt_clock().  This is
  the now-unified callback for interval/profile probes.  dt_clock()
  will consume multiple events during a single execution if it is
  delayed, but on platforms with high quality interrupt clocks this
  should be rare.

- Each struct dt_pcb gets its own clockintr handle, dp_clockintr.

- In struct dt_pcb, replace dp_maxtick/dp_nticks with dp_nsecs,
  the PCB's sampling period.  Aynchronous probes must initialize
  dp_nsecs to a non-zero value during dtpv_alloc().

- In struct dt_pcb, replace dp_cpuid with dp_cpu so that
  dt_ioctl_record_start() knows where to bind the PCB's
  dp_clockintr.

- dt_ioctl_record_start() binds, staggers, and starts all
  interval/profile PCBs on the given dt_softc.  Each dp_clockintr
  is given a reference to its enclosing PCB so that dt_clock()
  doesn't need to search for it.  The staggering sort-of simulates
  the current behavior under hardclock().

- dt_ioctl_record_stop() unbinds all interval/profile PCBs.  The
  CL_BARRIER ensures that dp_clockintr's PCB reference is not in
  use by dt_clock() so that the PCB may be safely freed upon
  return from dt_ioctl_record_stop().  Blocking while holding
  dt_lock is not ideal, but in practice blocking in this spot is
  rare and dt_clock() completes quickly on all but the oldest
  hardware.  An extremely unlucky thread could block for every
  interval/profile PCB on the softc, but this is implausible.

DT_FA_PROFILE values are up-to-date for amd64, i386, and macppc.
Somebody with the right hardware needs to check-and-maybe-fix the
values on octeon, powerpc64, and sparc64.

Joint effort with mpi@.

Thread: https://marc.info/?l=openbsd-tech&m=170629371821879&w=2

ok mpi@
sys/dev/dt/dt_dev.c
sys/dev/dt/dt_prov_profile.c
sys/dev/dt/dtvar.h
sys/kern/kern_clock.c