1.\" $OpenBSD: clockintr.9,v 1.3 2022/11/10 23:57:31 jsg Exp $ 2.\" 3.\" Copyright (c) 2020-2022 Scott Cheloha <cheloha@openbsd.org> 4.\" 5.\" Permission to use, copy, modify, and distribute this software for any 6.\" purpose with or without fee is hereby granted, provided that the above 7.\" copyright notice and this permission notice appear in all copies. 8.\" 9.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16.\" 17.Dd $Mdocdate: November 10 2022 $ 18.Dt CLOCKINTR 9 19.Os 20.Sh NAME 21.Nm clockintr_init , 22.Nm clockintr_cpu_init , 23.Nm clockintr_dispatch , 24.Nm clockintr_setstatclockrate , 25.Nm clockintr_trigger 26.Nd clock interrupt scheduler 27.Sh SYNOPSIS 28.In sys/clockintr.h 29.Ft void 30.Fo clockintr_init 31.Fa "u_int flags" 32.Fc 33.Ft void 34.Fo clockintr_cpu_init 35.Fa "struct intrclock *ic" 36.Fc 37.Ft int 38.Fo clockintr_dispatch 39.Fa "void *frame" 40.Fc 41.Ft void 42.Fo clockintr_setstatclockrate 43.Fa "int freq" 44.Fc 45.Ft void 46.Fo clockintr_trigger 47.Fa "void" 48.Fc 49.In sys/kernel.h 50.Vt extern int hz; 51.Vt extern int stathz; 52.Vt extern int profhz; 53.In sys/sched.h 54.Vt extern int schedhz; 55.Sh DESCRIPTION 56The 57.Nm 58subsystem maintains a schedule of events, 59dispatches expired events, 60and rearms the local interrupt clock for each CPU in the system. 61.Pp 62The 63.Fn clockintr_init 64function initializes the subsystem as follows: 65.Bl -dash 66.It 67.Xr hardclock 9 68is configured to run 69.Xr hz 9 70times per second on each CPU. 71It is an error if 72.Vt hz 73is less than one or greater than one billion. 74.It 75.Fn statclock 76is configured to run 77.Vt stathz 78times per second on each CPU. 79It is an error if 80.Vt stathz 81is less than one or greater than one billion. 82.It 83When appropriate, 84.Fn statclock 85will be reconfigured to run 86.Vt profhz 87times per second on each CPU. 88.Vt profhz 89must be a non-zero integer multiple of 90.Vt stathz . 91It is an error if 92.Vt profhz 93is less than 94.Vt stathz 95or greater than one billion. 96.It 97If 98.Vt schedhz 99is non-zero, 100.Fn schedclock 101is configured to run 102.Vt schedhz 103times per second on each CPU. 104It is an error if 105.Vt schedhz 106is less than zero or greater than one billion. 107.El 108.Pp 109The event schedule has a resolution of one nanosecond and event periods are 110computed using integer division. 111If 112.Vt hz , 113.Vt stathz , 114.Vt profhz , 115or 116.Vt schedhz 117do not divide evenly into one billion, 118the corresponding event will not be dispatched at the specified frequency. 119.Pp 120The 121.Fn clockintr_init 122function accepts the bitwise OR of zero or more of the following 123.Fa flags : 124.Bl -tag -width CL_RNDSTAT 125.It Dv CL_RNDSTAT 126Randomize the 127.Fn statclock . 128Instead of using a fixed period, 129the subsystem will select pseudorandom intervals in a range such that 130the average 131.Fn statclock 132period is equal to the inverse of 133.Vt stathz . 134.El 135.Pp 136The 137.Fn clockintr_init 138function must be called exactly once and only by the primary CPU. 139It should be called after all timecounters are installed with 140.Xr tc_init 9 . 141.Pp 142The 143.Fn clockintr_cpu_init 144function prepares the calling CPU for 145.Fn clockintr_dispatch . 146The first time it is called on a given CPU, 147if 148.Fa ic 149is not 150.Dv NULL , 151the caller is configured to use the given 152.Fa intrclock 153during 154.Fn clockintr_dispatch ; 155otherwise the caller is responsible for rearming its own interrupt 156clock after each 157.Fn clockintr_dispatch . 158Subsequent calls ignore 159.Fa ic : 160instead, 161the caller's event schedule is advanced past any expired events 162without dispatching those events. 163It is an error to call this function before the subsystem is initialized with 164.Fn clockintr_init . 165All CPUs should call 166.Fn clockintr_cpu_init 167during each system resume after the system time is updated with 168.Xr inittodr 9 , 169otherwise they will needlessly dispatch every event that expired while 170the system was suspended. 171.Pp 172The 173.Fn clockintr_dispatch 174function executes all expired events on the caller's event schedule and, 175if configured, 176rearms the caller's interrupt clock to fire when the next event is scheduled 177to expire. 178The 179.Fa frame 180argument must point to the caller's 181.Dv clockframe 182struct. 183The 184.Fn clockintr_dispatch 185function should only be called from a clock interrupt handler at 186.Dv IPL_CLOCK 187.Pq see Xr spl 9 . 188It is an error to call this function on a given CPU before 189.Fn clockintr_cpu_init . 190.Pp 191The 192.Fn clockintr_setstatclockrate 193function changes the effective dispatch frequency for 194.Fn statclock 195to 196.Fa freq . 197It should be called from the machine-dependent 198.Fn setstatclockrate 199function after performing any needed hardware reconfiguration. 200It is an error if 201.Fa freq 202is not equal to 203.Vt stathz 204or 205.Vt profhz . 206It is an error to call this function before the subsystem is initialized with 207.Fn clockintr_init . 208.Pp 209The 210.Fn clockintr_trigger 211function causes the 212.Fn clockintr_dispatch 213function to run in the appropriate context as soon as possible if 214the caller was configured with an 215.Fa intrclock 216when 217.Fn clockintr_cpu_init 218was first called. 219If the caller was not configured with an 220.Fa intrclock , 221the function does nothing. 222It is an error to call this function on a given CPU before 223.Fn clockintr_cpu_init . 224.Pp 225The 226.Fa ic 227argument to 228.Fn clockintr_cpu_init 229points to an 230.Fa intrclock 231structure: 232.Bd -literal -offset indent 233struct intrclock { 234 void *ic_cookie; 235 void (*ic_rearm)(void *cookie, uint64_t nsecs); 236 void (*ic_trigger)(void *cookie); 237}; 238.Ed 239.Pp 240The 241.Fa intrclock 242structure provides the 243.Nm 244subsystem with a uniform interface for manipulating an interrupt clock. 245It has the following members: 246.Bl -tag -width XXXXXXXXXX 247.It Fa ic_cookie 248May point to any resources needed during 249.Fa ic_rearm 250or 251.Fa ic_trigger 252to arm the underlying interrupt clock 253.Pq see below . 254.It Fa ic_rearm 255Should cause 256.Fn clockintr_dispatch 257to run on the calling CPU in the appropriate context after at least 258.Fa nsecs 259nanoseconds have elapsed. 260The first argument, 261.Fa cookie , 262is the 263.Fa ic_cookie 264member of the parent structure. 265The second argument, 266.Fa nsecs , 267is a non-zero count of nanoseconds. 268.It Fa ic_trigger 269Should cause 270.Fn clockintr_dispatch 271to run on the calling CPU in the appropriate context as soon as possible. 272The first argument, 273.Fa cookie , 274is the 275.Fa ic_cookie 276member of the parent structure. 277.El 278.Sh CONTEXT 279The 280.Fn clockintr_init , 281.Fn clockintr_cpu_init , 282and 283.Fn clockintr_trigger 284functions may be called during autoconf. 285.Pp 286The 287.Fn clockintr_dispatch 288function may be called from interrupt context at 289.Dv IPL_CLOCK . 290.Pp 291The 292.Fn clockintr_setstatclockrate 293function may be called during autoconf, 294from process context, 295or from interrupt context. 296.Sh RETURN VALUES 297The 298.Fn clockintr_dispatch 299function returns non-zero if at least one event was dispatched, 300otherwise it returns zero. 301.Sh CODE REFERENCES 302.Pa sys/kern/kern_clockintr.c 303.Sh SEE ALSO 304.Xr hardclock 9 , 305.Xr hz 9 , 306.Xr inittodr 9 , 307.Xr nanouptime 9 , 308.Xr spl 9 , 309.Xr tc_init 9 , 310.Xr timeout 9 311.Rs 312.%A Steven McCanne 313.%A Chris Torek 314.%T A Randomized Sampling Clock for CPU Utilization Estimation and Code Profiling 315.%B \&In Proc. Winter 1993 USENIX Conference 316.%D 1993 317.%P pp. 387\(en394 318.%I USENIX Association 319.Re 320.Rs 321.%A Richard McDougall 322.%A Jim Mauro 323.%B Solaris Internals: Solaris 10 and OpenSolaris Kernel Architecture 324.%I Prentice Hall 325.%I Sun Microsystems Press 326.%D 2nd Edition, 2007 327.%P pp. 912\(en925 328.Re 329.Sh HISTORY 330The 331.Nm 332subsystem first appeared in 333.Ox 7.3 . 334