hardclock(9) could go.

"Mathew, Cherry G.*" <[email protected]>
Newsgroups gmane.os.netbsd.devel.kernel
Message-ID <[email protected]>
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)
hardclock-callout.diff (text/x-patch, 2.3 KB)
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();  
 }
 
 /*
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.