On Thu, Jan 07, 2021 at 11:15:42AM -0600, Scott Cheloha wrote:
> 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.

Updated diff.

- As noted by visa@, loongson already has a distinct statclock
  interrupt, so remove the changes to arch/loongson/dev/glxclk.c.

I have successful tests on these platforms:

- amd64
- luna88k
- hppa

Still need tests on these platforms:

- alpha
- i386
- mips64 (octeon will be sufficient)
- sgi
- sh

Related: is there a way to test i386 on amd64 hardware?

Index: sys/kern/kern_clock.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_clock.c,v
retrieving revision 1.102
diff -u -p -r1.102 kern_clock.c
--- sys/kern/kern_clock.c       13 Jan 2021 16:28:49 -0000      1.102
+++ sys/kern/kern_clock.c       14 Jan 2021 18:39:03 -0000
@@ -160,12 +160,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        14 Jan 2021 18:39:04 -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        14 Jan 2021 18:39:04 -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   14 Jan 2021 18:39:04 -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     14 Jan 2021 18:39:04 -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  14 Jan 2021 18:39:04 -0000
@@ -257,6 +257,7 @@ lapic_clockintr(void *arg)
        struct clockframe *frame = arg;
 
        hardclock(frame);
+       statclock(frame);
 
        clk_count.ec_count++;
 }
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    14 Jan 2021 18:39:04 -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      14 Jan 2021 18:39:04 -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 14 Jan 2021 18:39:04 -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      14 Jan 2021 18:39:04 -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