tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
hardclock(9) could go.
Hello,
I'm investigating how to make our kernel less reliant on hardclock(9)
being called at hz(9).
Please find attached a patch to reduce hardclock(9)'s responsibilities
wrt the rest of the system timekeeping.
The idea is that hardclock(9) will drive callout_hardclock() for now,
until we modify the latter to not expect a fixed "tick" rate (ie; hz) -
at which point we have the option of several callers - for eg: a
carefully crafted one-shot interrupt at a programmable timespan.
With this patch, I'd like to understand what it does to the system as-is
- so ideally as many configs as possible (different arch/ and MP/UP) as
well as virtualisation situations (eg: Xen).
I look forward to your comments and test results, if any.
Many Thanks,
--
Math/(~cherry)
diff -r 95278b51da8b sys/kern/kern_clock.c
--- a/sys/kern/kern_clock.c Tue Mar 19 10:53:00 2024 +0000
+++ b/sys/kern/kern_clock.c Wed Mar 20 05:24:07 2024 +0000
@@ -107,6 +107,9 @@
static int sysctl_kern_clockrate(SYSCTLFN_PROTO);
+static callout_t clocktick_coh_var, *clocktick_coh =
+ &clocktick_coh_var; /* Callout handle for clock tick */
+
/*
* Clock handling routines.
*
@@ -222,6 +225,42 @@
return atomic_load_relaxed(&hardclock_ticks);
}
+static void
+clocktick(void *coptr)
+{
+ struct lwp *l;
+ struct cpu_info *ci;
+
+ ci = curcpu();
+ l = ci->ci_onproc;
+
+ /*
+ * If no separate schedclock is provided, call it here
+ * at about 16 Hz.
+ */
+ if (schedhz == 0) {
+ if ((int)(--ci->ci_schedstate.spc_schedticks) <= 0) {
+ schedclock(l);
+ ci->ci_schedstate.spc_schedticks = hardscheddiv;
+ }
+ }
+ if ((--ci->ci_schedstate.spc_ticks) <= 0)
+ sched_tick(ci);
+
+ if (CPU_IS_PRIMARY(ci)) {
+ atomic_store_relaxed(&hardclock_ticks,
+ atomic_load_relaxed(&hardclock_ticks) + 1);
+ tc_ticktock();
+ }
+
+ /*
+ * Make sure the CPUs and timecounter are making progress.
+ */
+ heartbeat();
+
+ callout_schedule(clocktick_coh, 1); /* Schedule next one */
+}
+
/*
* Initialize clock frequencies and start both clocks running.
*/
@@ -254,6 +293,10 @@
*/
intr_timecounter.tc_frequency = hz;
tc_init(&intr_timecounter);
+ callout_init(clocktick_coh, CALLOUT_MPSAFE);
+ callout_setfunc(clocktick_coh, clocktick, curcpu());
+ callout_schedule(clocktick_coh, 1); /* Schedule first one */
+ callout_hardclock(); /* And kick it down the road */
/*
* Compute profhz and stathz, fix profhz if needed.
@@ -318,33 +361,9 @@
if (stathz == 0)
statclock(frame);
/*
- * If no separate schedclock is provided, call it here
- * at about 16 Hz.
- */
- if (schedhz == 0) {
- if ((int)(--ci->ci_schedstate.spc_schedticks) <= 0) {
- schedclock(l);
- ci->ci_schedstate.spc_schedticks = hardscheddiv;
- }
- }
- if ((--ci->ci_schedstate.spc_ticks) <= 0)
- sched_tick(ci);
-
- if (CPU_IS_PRIMARY(ci)) {
- atomic_store_relaxed(&hardclock_ticks,
- atomic_load_relaxed(&hardclock_ticks) + 1);
- tc_ticktock();
- }
-
- /*
- * Make sure the CPUs and timecounter are making progress.
- */
- heartbeat();
-
- /*
* Update real-time timeout queue.
*/
- callout_hardclock();
+ callout_hardclock();
}
/*
Home |
Main Index |
Thread Index |
Old Index