History log of /openbsd/sys/kern/kern_clock.c (Results 1 – 25 of 124)
Revision Date Author Comments
# 241d6723 08-Jul-2024 claudio <claudio@openbsd.org>

Rework per proc and per process time usage accounting

For procs (threads) the accounting happens now lockless by curproc using
a generation counter. Callers need to use tu_enter() and tu_leave() for

Rework per proc and per process time usage accounting

For procs (threads) the accounting happens now lockless by curproc using
a generation counter. Callers need to use tu_enter() and tu_leave() for this.
To read the proc p_tu struct tuagg_get_proc() should be used. It ensures
that the values read is consistent.

For processes only the time of exited threads is accumulated in ps_tu and
to get the proper process time usage tuagg_get_process() needs to be called.
tuagg_get_process() will sum up all procs p_tu plus the ps_tu.

This removes another SCHED_LOCK() dependency. Adjust the code in
exit1() and exit2() to correctly account for the full run time.
For this adjust sched_exit() to do the runtime accounting like it is done
in mi_switch().

OK jca@ dlg@

show more ...


# 8434116f 12-Feb-2024 cheloha <cheloha@openbsd.org>

kernel: disable hardclock() on secondary CPUs

There is no useful work left for secondary CPUs to do in hardclock().
Disable cq_hardclock on secondary CPUs and remove the now-unnecessary
early-return

kernel: disable hardclock() on secondary CPUs

There is no useful work left for secondary CPUs to do in hardclock().
Disable cq_hardclock on secondary CPUs and remove the now-unnecessary
early-return from hardclock().

This change reduces every system's normal clock interrupt rate by
(HZ - HZ/10) per secondary CPU. For example, an 8-core machine
with a HZ=100 kernel should see its clock interrupt rate drop from
~1600 to ~960.

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

ok kettenis@

show more ...


# c56c27b6 09-Feb-2024 cheloha <cheloha@openbsd.org>

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-frequenc

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@

show more ...


# 106c68c4 17-Oct-2023 cheloha <cheloha@openbsd.org>

clockintr: move callback-specific API behaviors to "clockrequest" namespace

The API's behavior when invoked from a callback function is impossible
to document. Move the special behavior into a dist

clockintr: move callback-specific API behaviors to "clockrequest" namespace

The API's behavior when invoked from a callback function is impossible
to document. Move the special behavior into a distinct namespace,
"clockrequest".

- Add a 'struct clockrequest'. Basically a stripped-down 'struct clockintr'
for exclusive use during clockintr_dispatch().
- In clockintr_queue, replace the "cq_shadow" clockintr with a "cq_request"
clockrequest. They serve the same purpose.
- CLST_SHADOW_PENDING -> CR_RESCHEDULE; different namespace, same meaning.
- CLST_IGNORE_SHADOW -> CLST_IGNORE_REQUEST; same meaning.
- Move shadow branch in clockintr_advance() to clockrequest_advance().
- clockintr_request_random() becomes clockrequest_advance_random().
- Delete dead shadow branches in clockintr_cancel(), clockintr_schedule().
- Callback functions now get a clockrequest pointer instead of a special
clockintr pointer: update all prototypes, callers.

No functional change intended.

show more ...


# 961828bc 11-Oct-2023 cheloha <cheloha@openbsd.org>

kernel: expand fixed clock interrupt periods to 64-bit values

Technically, all the current fixed clock interrupt periods fit within
an unsigned 32-bit value. But 32-bit multiplication is an acciden

kernel: expand fixed clock interrupt periods to 64-bit values

Technically, all the current fixed clock interrupt periods fit within
an unsigned 32-bit value. But 32-bit multiplication is an accident
waiting to happen. So, expand the fixed periods for hardclock,
statclock, profclock, and roundrobin to 64-bit values.

One exception: statclock_mask remains 32-bit because random(9) yields
32-bit values. Update the initclocks() comment to make it clear that
this is not an accident.

show more ...


# 061f668f 14-Sep-2023 cheloha <cheloha@openbsd.org>

clockintr: move hz(9)-based initialization out to initclocks()

To separate the hardclock from the clock interrupt subsystem we'll
need to move all related state out first.

hz(9) is set when we retu

clockintr: move hz(9)-based initialization out to initclocks()

To separate the hardclock from the clock interrupt subsystem we'll
need to move all related state out first.

hz(9) is set when we return from cpu_initclocks(), so it's safe to
move hardclock_period and roundrobin_period initialization out into
initclocks(). Move hardclock_period itself out into kern_clock.c
alongside the statclock variables.

show more ...


# f36eae22 14-Sep-2023 cheloha <cheloha@openbsd.org>

clockintr, statclock: eliminate clockintr_statclock() wrapper

- Move remaining statclock variables from kern_clockintr.c to
kern_clock.c. Move statclock variable initialization from
clockintr_i

clockintr, statclock: eliminate clockintr_statclock() wrapper

- Move remaining statclock variables from kern_clockintr.c to
kern_clock.c. Move statclock variable initialization from
clockintr_init() into initclocks().

- Change statclock() prototype to make it a legal clockintr
callback function and establish the handle with statclock()
instead clockintr_statclock().

- Merge the contents of clockintr_statclock() into statclock().
statclock() can now reschedule itself and handles multiple
expirations transparently.

- Make statclock_avg visible from sys/systm.h so that clockintr_cpu_init()
can use it to advance the statclock across suspend/hibernate.

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

show more ...


# b3ef18bd 14-Sep-2023 cheloha <cheloha@openbsd.org>

clockintr: replace CL_RNDSTAT with global variable statclock_is_randomized

In order to separate the statclock from the clock interrupt subsystem
we need to move all statclock state out into the broa

clockintr: replace CL_RNDSTAT with global variable statclock_is_randomized

In order to separate the statclock from the clock interrupt subsystem
we need to move all statclock state out into the broader kernel.

Start by replacing the CL_RNDSTAT flag with a new global variable,
"statclock_is_randomized", in kern_clock.c. Update all clockintr_init()
callers to set the boolean instead of passing the flag.

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

show more ...


# 8a045750 09-Sep-2023 cheloha <cheloha@openbsd.org>

kernel: remove schedhz

Now that alpha no longer sets schedhz, schedhz is a dead variable.
Remove it.

For now, leave the schedclock() call in place in statclock(). It
still runs at its default rate

kernel: remove schedhz

Now that alpha no longer sets schedhz, schedhz is a dead variable.
Remove it.

For now, leave the schedclock() call in place in statclock(). It
still runs at its default rate of (stathz / 4).

Part of mpi@'s WIP scheduler patch. Suggested by mpi@.

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

ok mpi@

show more ...


# 11d1f9b2 23-Aug-2023 cheloha <cheloha@openbsd.org>

all platforms: separate cpu_initclocks() from cpu_startclock()

To give the primary CPU an opportunity to perform clock interrupt
preparation in a machine-independent manner we need to separate the
"

all platforms: separate cpu_initclocks() from cpu_startclock()

To give the primary CPU an opportunity to perform clock interrupt
preparation in a machine-independent manner we need to separate the
"initialization" parts of cpu_initclocks() from the "start the clock
interrupt" parts. Currently, cpu_initclocks() does everything all at
once, so there is no space for this MI setup.

Many platforms have more-or-less already done this separation by
implementing a separate routine named "cpu_startclock()". This patch
promotes cpu_startclock() from de facto standard to mandatory API.

- Prototype cpu_startclock() in sys/systm.h alongside cpu_initclocks().
The separation of responsibility between the two routines is a bit
fuzzy but the basic guidelines are as follows:

+ cpu_initclocks() must initialize hz, stathz, and profhz, and call
clockintr_init().

+ cpu_startclock() must call clockintr_cpu_init() and start the clock
interrupt cycle on the calling CPU.

These guidelines will shift in the future, but that's the way things
stand as of *this* commit.

- In initclocks(): first call cpu_initclocks(), then do MI setup, and
last call cpu_startclock().

- On platforms where cpu_startclock() already exists: don't call
cpu_startclock() from cpu_initclocks() anymore.

- On platforms where cpu_startclock() doesn't yet exist: implement it.
Usually this is as simple as dividing cpu_initclocks() in two.

Tested on amd64 (i8254, lapic), arm64, i386 (i8254, lapic), macppc,
mips64/octeon, and sparc64. Tested on arm/armv7 (agtimer(4)) by
phessler@ and jmatthew@. Tested on m88k/luna88k by aoyama@. Tested
on powerpc64 by gkoehler@ and mlarkin@. Tested on riscv64 by
jmatthew@.

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

show more ...


# 5b707e82 22-Aug-2023 jsg <jsg@openbsd.org>

avoid an ifdef in hardclock()
ok miod@ cheloha@


# 8afcf90f 12-Aug-2023 miod <miod@openbsd.org>

Repair compilability for non-MULTIPROCESSOR kernels.


# 9ac452c7 11-Aug-2023 cheloha <cheloha@openbsd.org>

hardclock(9), roundrobin: make roundrobin() an independent clock interrupt

- Remove the roundrobin() call from hardclock(9).

- Revise roundrobin() to make it a valid clock interrupt callback.
It

hardclock(9), roundrobin: make roundrobin() an independent clock interrupt

- Remove the roundrobin() call from hardclock(9).

- Revise roundrobin() to make it a valid clock interrupt callback.
It is still periodic and it still runs at one tenth of the hardclock
frequency.

- Account for multiple expirations in roundrobin(): if two or more
roundrobin periods have elapsed, set SPCF_SHOULDYIELD on the running
thread immediately to simulate normal behavior.

- Each schedstate_percpu has its own roundrobin() handle, spc_roundrobin.
spc_roundrobin is started/advanced during clockintr_cpu_init().
Intervals elapsed across suspend/resume are discarded.

- rrticks_init and schedstate_percpu.spc_rrticks are now useless:
delete them.

Tweaked by mpi@. With input from mpi@ and claudio@.

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

ok mpi@ claudio@

show more ...


# 44e0cbf2 05-Aug-2023 cheloha <cheloha@openbsd.org>

hardclock(9): move setitimer(2) code into itimer_update()

- Move the setitimer(2) code responsible for updating the ITIMER_VIRTUAL
and ITIMER_PROF timers from hardclock(9) into a new clock interru

hardclock(9): move setitimer(2) code into itimer_update()

- Move the setitimer(2) code responsible for updating the ITIMER_VIRTUAL
and ITIMER_PROF timers from hardclock(9) into a new clock interrupt
routine, itimer_update(). itimer_update() is periodic and runs at the
same frequency as the hardclock.

+ Revise itimerdecr() to run within itimer_mtx instead of entering
and leaving it.

- Each schedstate_percpu has its own itimer_update() handle, spc_itimer.
A new scheduler flag, SPCF_ITIMER, indicates whether spc_itimer was
started during the last mi_switch() and needs to be stopped during the
next mi_switch() or sched_exit().

- A new per-process flag, PS_ITIMER, indicates whether ITIMER_VIRTUAL
and/or ITIMER_PROF are running. Checking the flag is easier than
entering itimer_mtx to check process.ps_timer[]. The flag is set
and cleared in a new helper function, process_reset_itimer_flag().

- In setitimer(), call need_resched() when the state of ITIMER_VIRTUAL
or ITIMER_PROF is changed to force an mi_switch() and update
spc_itimer.

claudio@ notes that ITIMER_PROF could be implemented as a high-res
timer using the thread's execution time as a guide for when to
interrupt the process and assert SIGPROF. This would probably work
really well in single-threaded processes. ITIMER_VIRTUAL would be
more difficult to make high-res, though, as you need to exclude time
spent in the kernel.

Tested on powerpc64 by gkoehler@. With input from claudio@.

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

ok claudio@

show more ...


# 06bd3d80 01-Aug-2023 claudio <claudio@openbsd.org>

Don't force early wrap around for jiffies.

In inteldrm the function intel_dp_wait_source_oui() can be called before
last_oui_write is set and so the code requires a positive initial jiffies
value. O

Don't force early wrap around for jiffies.

In inteldrm the function intel_dp_wait_source_oui() can be called before
last_oui_write is set and so the code requires a positive initial jiffies
value. On linux this is the case for 64bit systems (but not for 32bit) and
because of this idiosyncracy this bug was introduced in upstream intel code.
Instead of adding another OpenBSD specific quirk to drm code alter our
jiffies initalisation.

Systems affected are at least "ALDERLAKE_P, gen 12" and "TIGERLAKE, gen 12"
Suggested fix by kettenis@
OK jsg@

show more ...


# 671537bf 25-Jul-2023 cheloha <cheloha@openbsd.org>

statclock: move profil(2), GPROF code to profclock(), gmonclock()

This patch isolates profil(2) and GPROF from statclock(). Currently,
statclock() implements both profil(2) and GPROF through a comp

statclock: move profil(2), GPROF code to profclock(), gmonclock()

This patch isolates profil(2) and GPROF from statclock(). Currently,
statclock() implements both profil(2) and GPROF through a complex
mechanism involving both platform code (setstatclockrate) and the
scheduler (pscnt, psdiv, and psratio). We have a machine-independent
interface to the clock interrupt hardware now, so we no longer need to
do it this way.

- Move profil(2)-specific code from statclock() to a new clock
interrupt callback, profclock(), in subr_prof.c. Each
schedstate_percpu has its own profclock handle. The profclock is
enabled/disabled for a given CPU when it is needed by the running
thread during mi_switch() and sched_exit().

- Move GPROF-specific code from statclock() to a new clock interrupt
callback, gmonclock(), in subr_prof.c. Where available, each cpu_info
has its own gmonclock handle . The gmonclock is enabled/disabled for
a given CPU via sysctl(2) in prof_state_toggle().

- Both profclock() and gmonclock() have a fixed period, profclock_period,
that is initialized during initclocks().

- Export clockintr_advance(), clockintr_cancel(), clockintr_establish(),
and clockintr_stagger() via <sys/clockintr.h>. They have external
callers now.

- Delete pscnt, psdiv, psratio. From schedstate_percpu, also delete
spc_pscnt and spc_psdiv. The statclock frequency is not dynamic
anymore so these variables are now useless.

- Delete code/state related to the dynamic statclock frequency from
kern_clockintr.c. The statclock frequency can still be pseudo-random,
so move the contents of clockintr_statvar_init() into clockintr_init().

With input from miod@, deraadt@, and claudio@. Early revisions
cleaned up by claudio. Early revisions tested by claudio@. Tested by
cheloha@ on amd64, arm64, macppc, octeon, and sparc64 (sun4v).
Compile- and boot- tested on i386 by mlarkin@. riscv64 compilation
bugs found by mlarkin@. Tested on riscv64 by jca@. Tested on
powerpc64 by gkoehler@.

show more ...


# d624e113 25-Apr-2023 cheloha <cheloha@openbsd.org>

addupc_intr: support adding multiple profiling ticks at once

Add a third parameter to addupc_intr(), "u_long nticks". This will
allow us to credit more than one profiling tick to the thread at once

addupc_intr: support adding multiple profiling ticks at once

Add a third parameter to addupc_intr(), "u_long nticks". This will
allow us to credit more than one profiling tick to the thread at once.
Should be useful in the unusual case where the clock interrupt is
masked for an extended period.

show more ...


# d8920042 03-Mar-2023 cheloha <cheloha@openbsd.org>

initclocks: don't reinitialize ticks, jiffies at runtime

Various drivers use ticks/jiffies before initclocks(). It isn't
generally safe to reinitialize them at runtime. Hoist the conditional
defin

initclocks: don't reinitialize ticks, jiffies at runtime

Various drivers use ticks/jiffies before initclocks(). It isn't
generally safe to reinitialize them at runtime. Hoist the conditional
definition of HZ from param.c into sys/kernel.h so we can see it from
kern_clock.c and statically initialize ticks/jiffies to the desired
offset.

With this change, timeouts scheduled before initclocks() do not all
fire immediately during the first softclock().

With input from kettenis@.

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

show more ...


# 9bcfcad5 04-Feb-2023 cheloha <cheloha@openbsd.org>

kernel: stathz is always non-zero after cpu_initclocks()

Now that the clockintr switch is complete, cpu_initclocks() always
initializes stathz to a non-zero value. We don't call statclock()
from ha

kernel: stathz is always non-zero after cpu_initclocks()

Now that the clockintr switch is complete, cpu_initclocks() always
initializes stathz to a non-zero value. We don't call statclock()
from hardclock(9) anymore and, more broadly, we don't need to test
whether stathz is non-zero before using it.

With input from kettenis@.

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

ok kettenis@ miod@

show more ...


# 0d280c5f 14-Aug-2022 jsg <jsg@openbsd.org>

remove unneeded includes in sys/kern
ok mpi@ miod@


# 553933d8 10-Jul-2022 mlarkin <mlarkin@openbsd.org>

Remove trailing whitespace. No code change.


# c8da0207 16-Feb-2022 jsg <jsg@openbsd.org>

unifdef PROC_PC
ok guenther@ rob@


# 9589ba9d 13-Jan-2021 cheloha <cheloha@openbsd.org>

kernel, sysctl(8): remove dead variable: tickadj

The global "tickadj" variable is a remnant of the old NTP adjustment
code we used in the kernel before the current timecounter subsystem
was imported

kernel, sysctl(8): remove dead variable: tickadj

The global "tickadj" variable is a remnant of the old NTP adjustment
code we used in the kernel before the current timecounter subsystem
was imported from FreeBSD circa 2004 or 2005.

Fifteen years hence it is completely vestigial and we can remove it.
We probably should have removed it long ago but I guess it slipped
through the cracks. FreeBSD removed it in 2002:

https://cgit.freebsd.org/src/commit/?id=e1d970f1811e5e1e9c912c032acdcec6521b2a6d

NetBSD and DragonflyBSD can probably remove it, too.

We export tickadj via the kern.clockrate sysctl(2), so update sysctl.2
and sysctl(8) accordingly. Hypothetically this change could break
someone's sysctl(8) parsing script. I don't think that's very likely.

ok mvs@

show more ...


# 91b2ecf6 21-Jan-2020 mpi <mpi@openbsd.org>

Import dt(4) a driver and framework for Dynamic Profiling.

The design is fairly simple: events, in the form of descriptors on a
ring, are being produced in any kernel context and being consumed by
a

Import dt(4) a driver and framework for Dynamic Profiling.

The design is fairly simple: events, in the form of descriptors on a
ring, are being produced in any kernel context and being consumed by
a userland process reading /dev/dt.

Code and hooks are all guarded under '#if NDT > 0' so this commit
shouldn't introduce any change as long as dt(4) is disable in GENERIC.

ok kettenis@, visa@, jasper@, deraadt@

show more ...


# 8fe879fb 02-Nov-2019 cheloha <cheloha@openbsd.org>

softclock: move softintr registration/scheduling into timeout module

softclock() is scheduled from hardclock(9) because long ago callouts were
processed from hardclock(9) directly. The introduction

softclock: move softintr registration/scheduling into timeout module

softclock() is scheduled from hardclock(9) because long ago callouts were
processed from hardclock(9) directly. The introduction of timeout(9) circa
2000 moved all callout processing into a dedicated module, but the softclock
scheduling stayed behind in hardclock(9).

We can move all the softclock() "stuff" into the timeout module to make
kern_clock.c a bit cleaner. Neither initclocks() nor hardclock(9) need
to "know" about softclock(). The initial softclock() softintr registration
can be done from timeout_proc_init() and softclock() can be scheduled
from timeout_hardclock_update().

ok visa@

show more ...


12345