Hi,

I want to isolate statclock() from hardclock(9).  This will simplify
the logic in my WIP dynamic clock interrupt framework.

Currently, if stathz is zero, we call statclock() from within
hardclock(9).  It looks like this (see sys/kern/kern_clock.c):

void
hardclock(struct clockframe *frame)
{
        /* [...] */

        if (stathz == 0)
                statclock(frame);

        /* [...] */

This is the case on alpha, amd64 (w/ lapic), hppa, i386 (w/ lapic),
loongson, luna88k, mips64, and sh.

(We seem to do it on sgi, too.  I was under the impression that sgi
*was* a mips64 platform, yet sgi seems to it have its own clock
interrupt code distinct from mips64's general clock interrupt code
which is used by e.g. octeon).

However, if stathz is not zero we call statclock() separately.  This
is the case on armv7, arm, arm64, macppc, powerpc64, and sparc64.

(The situation for the general powerpc code and socppc in particular
is a mystery to me.)

If we could remove this MD distinction it would make my MI framework
simpler.  Instead of checking stathz and conditionally starting a
statclock event I will be able to unconditionally start a statclock
event on all platforms on every CPU.

In general I don't think the "is stathz zero?" variance between
platforms is useful:

- The difference is invisible to userspace, as we hide the fact that
  stathz is zero from e.g. the kern.clockrate sysctl.

- We run statclock() at some point, regardless of whether stathz is
  zero.  If statclock() is run from hardclock(9) then isn't stathz
  effectively equal to hz?

- Because stathz might be zero we need to add a bunch of safety checks
  to our MI code to ensure we don't accidentally divide by zero.

Maybe we can ensure stathz is non-zero in a later diff...

--

Anyway, I don't think I have missed any platforms.  However, if
platform experts could weigh in here to verify my changes (and test
them!) I'd really appreciate it.

In particular, I'm confused about how clock interrupts work on
powerpc, socppc, and sgi.

--

Thoughts?  Platform-specific OKs?

Index: sys/kern/kern_clock.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_clock.c,v
retrieving revision 1.101
diff -u -p -r1.101 kern_clock.c
--- sys/kern/kern_clock.c       21 Jan 2020 16:16:23 -0000      1.101
+++ sys/kern/kern_clock.c       7 Jan 2021 16:37:09 -0000
@@ -164,12 +164,6 @@ hardclock(struct clockframe *frame)
                }
        }
 
-       /*
-        * If no separate statistics clock is available, run it from here.
-        */
-       if (stathz == 0)
-               statclock(frame);
-
        if (--ci->ci_schedstate.spc_rrticks <= 0)
                roundrobin(ci);
 
Index: sys/arch/alpha/alpha/clock.c
===================================================================
RCS file: /cvs/src/sys/arch/alpha/alpha/clock.c,v
retrieving revision 1.24
diff -u -p -r1.24 clock.c
--- sys/arch/alpha/alpha/clock.c        6 Jul 2020 13:33:06 -0000       1.24
+++ sys/arch/alpha/alpha/clock.c        7 Jan 2021 16:37:09 -0000
@@ -136,6 +136,13 @@ clockattach(dev, fns)
  * Machine-dependent clock routines.
  */
 
+void
+clockintr(struct clockframe *frame)
+{
+       hardclock(frame);
+       statclock(frame);
+}
+
 /*
  * Start the real-time and statistics clocks. Leave stathz 0 since there
  * are no other timers available.
@@ -165,7 +172,7 @@ cpu_initclocks(void)
         * hardclock, which would then fall over because the pointer
         * to the virtual timers wasn't set at that time.
         */
-       platform.clockintr = hardclock;
+       platform.clockintr = clockintr;
        schedhz = 16;
 
        evcount_attach(&clk_count, "clock", &clk_irq);
Index: sys/arch/amd64/amd64/lapic.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/lapic.c,v
retrieving revision 1.57
diff -u -p -r1.57 lapic.c
--- sys/arch/amd64/amd64/lapic.c        6 Sep 2020 20:50:00 -0000       1.57
+++ sys/arch/amd64/amd64/lapic.c        7 Jan 2021 16:37:09 -0000
@@ -452,6 +452,7 @@ lapic_clockintr(void *arg, struct intrfr
        floor = ci->ci_handled_intr_level;
        ci->ci_handled_intr_level = ci->ci_ilevel;
        hardclock((struct clockframe *)&frame);
+       statclock((struct clockframe *)&frame);
        ci->ci_handled_intr_level = floor;
 
        clk_count.ec_count++;
Index: sys/arch/hppa/dev/clock.c
===================================================================
RCS file: /cvs/src/sys/arch/hppa/dev/clock.c,v
retrieving revision 1.31
diff -u -p -r1.31 clock.c
--- sys/arch/hppa/dev/clock.c   6 Jul 2020 13:33:07 -0000       1.31
+++ sys/arch/hppa/dev/clock.c   7 Jan 2021 16:37:09 -0000
@@ -43,7 +43,7 @@
 
 u_long cpu_hzticks;
 
-int    cpu_hardclock(void *);
+int    cpu_clockintr(void *);
 u_int  itmr_get_timecount(struct timecounter *);
 
 struct timecounter itmr_timecounter = {
@@ -106,7 +106,7 @@ cpu_initclocks(void)
 }
 
 int
-cpu_hardclock(void *v)
+cpu_clockintr(void *v)
 {
        struct cpu_info *ci = curcpu();
        u_long __itmr, delta, eta;
@@ -114,14 +114,15 @@ cpu_hardclock(void *v)
        register_t eiem;
 
        /*
-        * Invoke hardclock as many times as there has been cpu_hzticks
-        * ticks since the last interrupt.
+        * Invoke hardclock and statclock as many times as there has been
+        * cpu_hzticks ticks since the last interrupt.
         */
        for (;;) {
                mfctl(CR_ITMR, __itmr);
                delta = __itmr - ci->ci_itmr;
                if (delta >= cpu_hzticks) {
                        hardclock(v);
+                       statclock(v);
                        ci->ci_itmr += cpu_hzticks;
                } else
                        break;
Index: sys/arch/hppa/dev/cpu.c
===================================================================
RCS file: /cvs/src/sys/arch/hppa/dev/cpu.c,v
retrieving revision 1.42
diff -u -p -r1.42 cpu.c
--- sys/arch/hppa/dev/cpu.c     29 May 2020 04:42:23 -0000      1.42
+++ sys/arch/hppa/dev/cpu.c     7 Jan 2021 16:37:09 -0000
@@ -89,7 +89,7 @@ cpuattach(struct device *parent, struct 
        extern u_int cpu_ticksnum, cpu_ticksdenom;
        extern u_int fpu_enable;
        /* clock.c */
-       extern int cpu_hardclock(void *);
+       extern int cpu_clockintr(void *);
        /* ipi.c */
        extern int hppa_ipi_intr(void *);
 
@@ -173,7 +173,7 @@ cpuattach(struct device *parent, struct 
                printf(", %u/%u D/I BTLBs",
                    pdc_btlb.finfo.num_i, pdc_btlb.finfo.num_d);
 
-       cpu_intr_establish(IPL_CLOCK, 31, cpu_hardclock, NULL, "clock");
+       cpu_intr_establish(IPL_CLOCK, 31, cpu_clockintr, NULL, "clock");
 #ifdef MULTIPROCESSOR
        cpu_intr_establish(IPL_IPI, 30, hppa_ipi_intr, NULL, "ipi");
 #endif
Index: sys/arch/i386/i386/lapic.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/lapic.c,v
retrieving revision 1.47
diff -u -p -r1.47 lapic.c
--- sys/arch/i386/i386/lapic.c  30 Jul 2018 14:19:12 -0000      1.47
+++ sys/arch/i386/i386/lapic.c  7 Jan 2021 16:37:09 -0000
@@ -257,6 +257,7 @@ lapic_clockintr(void *arg)
        struct clockframe *frame = arg;
 
        hardclock(frame);
+       statclock(frame);
 
        clk_count.ec_count++;
 }
Index: sys/arch/loongson/dev/glxclk.c
===================================================================
RCS file: /cvs/src/sys/arch/loongson/dev/glxclk.c,v
retrieving revision 1.5
diff -u -p -r1.5 glxclk.c
--- sys/arch/loongson/dev/glxclk.c      19 Jul 2015 21:11:47 -0000      1.5
+++ sys/arch/loongson/dev/glxclk.c      7 Jan 2021 16:37:09 -0000
@@ -286,6 +286,7 @@ glxclk_intr(void *arg)
                return 1;
 
        hardclock(frame);
+       statclock(frame);
 
        return 1;
 }
Index: sys/arch/luna88k/luna88k/clock.c
===================================================================
RCS file: /cvs/src/sys/arch/luna88k/luna88k/clock.c,v
retrieving revision 1.15
diff -u -p -r1.15 clock.c
--- sys/arch/luna88k/luna88k/clock.c    6 Jul 2020 13:33:07 -0000       1.15
+++ sys/arch/luna88k/luna88k/clock.c    7 Jan 2021 16:37:09 -0000
@@ -165,8 +165,10 @@ clockintr(void *eframe)
                clockevc->ec_count++;
 
        *(volatile uint32_t *)(ci->ci_clock_ack) = ~0;
-       if (clockinitted)
+       if (clockinitted) {
                hardclock(eframe);
+               statclock(eframe);
+       }
        return 1;
 }
 
Index: sys/arch/mips64/mips64/clock.c
===================================================================
RCS file: /cvs/src/sys/arch/mips64/mips64/clock.c,v
retrieving revision 1.42
diff -u -p -r1.42 clock.c
--- sys/arch/mips64/mips64/clock.c      30 Jun 2020 14:56:10 -0000      1.42
+++ sys/arch/mips64/mips64/clock.c      7 Jan 2021 16:37:09 -0000
@@ -151,6 +151,7 @@ cp0_int5(uint32_t mask, struct trapframe
                while (ci->ci_pendingticks) {
                        cp0_clock_count.ec_count++;
                        hardclock(tf);
+                       statclock(tf);
                        ci->ci_pendingticks--;
                }
 #ifdef MULTIPROCESSOR
Index: sys/arch/sgi/localbus/int.c
===================================================================
RCS file: /cvs/src/sys/arch/sgi/localbus/int.c,v
retrieving revision 1.15
diff -u -p -r1.15 int.c
--- sys/arch/sgi/localbus/int.c 24 Feb 2018 11:42:31 -0000      1.15
+++ sys/arch/sgi/localbus/int.c 7 Jan 2021 16:37:09 -0000
@@ -524,6 +524,7 @@ int_8254_intr0(uint32_t hwpend, struct t
                        while (ci->ci_pendingticks) {
                                int_clock_count.ec_count++;
                                hardclock(tf);
+                               statclock(tf);
                                ci->ci_pendingticks--;
                        }
                }
Index: sys/arch/sh/sh/clock.c
===================================================================
RCS file: /cvs/src/sys/arch/sh/sh/clock.c,v
retrieving revision 1.11
diff -u -p -r1.11 clock.c
--- sys/arch/sh/sh/clock.c      20 Oct 2020 15:59:17 -0000      1.11
+++ sys/arch/sh/sh/clock.c      7 Jan 2021 16:37:10 -0000
@@ -333,6 +333,7 @@ sh3_clock_intr(void *arg) /* trap frame 
        _reg_bclr_2(SH3_TCR0, TCR_UNF);
 
        hardclock(arg);
+       statclock(arg);
 
        return (1);
 }
@@ -354,6 +355,7 @@ sh4_clock_intr(void *arg) /* trap frame 
        _reg_bclr_2(SH4_TCR0, TCR_UNF);
 
        hardclock(arg);
+       statclock(arg);
 
        return (1);
 }

Reply via email to