sparc64: pull retry logic out of tickcmpr_set(), sys_tickcmpr_set()
authorcheloha <cheloha@openbsd.org>
Thu, 29 Dec 2022 22:44:23 +0000 (22:44 +0000)
committercheloha <cheloha@openbsd.org>
Thu, 29 Dec 2022 22:44:23 +0000 (22:44 +0000)
Pull the retry logic out of tickcmpr_set() and sys_tickcmpr_set() into
C functions tick_rearm() and sys_tick_rearm(), respectively.  There is
nothing wrong with the retry logic in these assembly functions, but
it's better to keep equivalent code similar and this change realigns
the %TICK and %SYS_TICK rearm code with that of the Hummingbird
%STICK.

Tested by miod@ on UltraSPARC I, UltraSPARC II, and UltraSPARC IIe.

Link: https://marc.info/?l=openbsd-tech&m=167175014315419&w=2
ok kettenis@

sys/arch/sparc64/sparc64/clock.c
sys/arch/sparc64/sparc64/locore.s

index 56e1cb0..79a007c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: clock.c,v 1.73 2022/12/22 19:51:11 cheloha Exp $      */
+/*     $OpenBSD: clock.c,v 1.74 2022/12/29 22:44:23 cheloha Exp $      */
 /*     $NetBSD: clock.c,v 1.41 2001/07/24 19:29:25 eeh Exp $ */
 
 /*
@@ -150,6 +150,8 @@ void        tick_start(void);
 void   sys_tick_start(void);
 void   stick_start(void);
 
+void   tick_rearm(uint64_t);
+void   sys_tick_rearm(uint64_t);
 void   stick_rearm(uint64_t);
 
 int    tickintr(void *);
@@ -766,7 +768,7 @@ tickintr(void *cap)
 
        /* Reset the interrupt. */
        s = intr_disable();
-       tickcmpr_set(ci->ci_tick);
+       tick_rearm(ci->ci_tick);
        intr_restore(s);
 
        return (1);
@@ -789,7 +791,7 @@ sys_tickintr(void *cap)
 
        /* Reset the interrupt. */
        s = intr_disable();
-       sys_tickcmpr_set(ci->ci_tick);
+       sys_tick_rearm(ci->ci_tick);
        intr_restore(s);
 
        return (1);
@@ -875,17 +877,27 @@ tick_start(void)
 
        tick_enable();
 
-       /*
-        * Try to make the tick interrupts as synchronously as possible on
-        * all CPUs to avoid inaccuracies for migrating processes.
-        */
-
        s = intr_disable();
-       ci->ci_tick = roundup(tick(), tick_increment);
-       tickcmpr_set(ci->ci_tick);
+       ci->ci_tick = tick();
+       tick_rearm(ci->ci_tick);
        intr_restore(s);
 }
 
+void
+tick_rearm(uint64_t cmp)
+{
+       uint64_t now, off = 8;
+
+       tickcmpr_set(cmp);
+       now = tick();
+       while (cmp <= now) {
+               cmp += off;
+               tickcmpr_set(cmp);
+               now = tick();
+               off *= 2;
+       }
+}
+
 void
 sys_tick_start(void)
 {
@@ -897,17 +909,27 @@ sys_tick_start(void)
                sys_tick_enable();
        }
 
-       /*
-        * Try to make the tick interrupts as synchronously as possible on
-        * all CPUs to avoid inaccuracies for migrating processes.
-        */
-
        s = intr_disable();
-       ci->ci_tick = roundup(sys_tick(), tick_increment);
-       sys_tickcmpr_set(ci->ci_tick);
+       ci->ci_tick = sys_tick();
+       sys_tick_rearm(ci->ci_tick);
        intr_restore(s);
 }
 
+void
+sys_tick_rearm(uint64_t cmp)
+{
+       uint64_t now, off = 8;
+
+       sys_tickcmpr_set(cmp);
+       now = sys_tick();
+       while (cmp <= now) {
+               cmp += off;
+               sys_tickcmpr_set(cmp);
+               now = sys_tick();
+               off *= 2;
+       }
+}
+
 void
 stick_start(void)
 {
@@ -916,11 +938,6 @@ stick_start(void)
 
        tick_enable();
 
-       /*
-        * Try to make the tick interrupts as synchronously as possible on
-        * all CPUs to avoid inaccuracies for migrating processes.
-        */
-
        s = intr_disable();
        ci->ci_tick = stick();
        stick_rearm(ci->ci_tick);
index aa2e206..9d25d55 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: locore.s,v 1.195 2022/12/22 19:51:11 cheloha Exp $    */
+/*     $OpenBSD: locore.s,v 1.196 2022/12/29 22:44:23 cheloha Exp $    */
 /*     $NetBSD: locore.s,v 1.137 2001/08/13 06:10:10 jdolecek Exp $    */
 
 /*
@@ -7477,22 +7477,9 @@ END(tick_enable)
  * sure those two instructions are in the same cache line.
  */
 ENTRY(tickcmpr_set)
-       ba      1f
-        mov    8, %o2                  ! Initial step size
        .align  64
-1:     wr      %o0, 0, %tick_cmpr
+       wr      %o0, 0, %tick_cmpr
        rd      %tick_cmpr, %g0
-
-       rd      %tick, %o1              ! Read current %tick
-       sllx    %o1, 1, %o1
-       srlx    %o1, 1, %o1
-
-       cmp     %o0, %o1                ! Make sure the value we wrote to
-       bg,pt   %xcc, 2f                !   %tick_cmpr was in the future.
-        add    %o0, %o2, %o0           ! If not, add the step size, double
-       ba,pt   %xcc, 1b                !   the step size and try again.
-        sllx   %o2, 1, %o2
-2:
        retl
         nop
 END(tickcmpr_set)
@@ -7518,22 +7505,9 @@ ENTRY(sys_tick_enable)
 END(sys_tick_enable)
 
 ENTRY(sys_tickcmpr_set)
-       ba      1f
-        mov    8, %o2                  ! Initial step size
        .align  64
-1:     wr      %o0, 0, %sys_tick_cmpr
+       wr      %o0, 0, %sys_tick_cmpr
        rd      %sys_tick_cmpr, %g0
-
-       rd      %sys_tick, %o1          ! Read current %sys_tick
-       sllx    %o1, 1, %o1
-       srlx    %o1, 1, %o1
-
-       cmp     %o0, %o1                ! Make sure the value we wrote to
-       bg,pt   %xcc, 2f                !   %sys_tick_cmpr was in the future.
-        add    %o0, %o2, %o0           ! If not, add the step size, double
-       ba,pt   %xcc, 1b                !   the step size and try again.
-        sllx   %o2, 1, %o2
-2:
        retl
         nop
 END(sys_tickcmpr_set)