To keep the %TICK and %SYS_TICK code aligned with the Hummingbird %STICK code, let's pull the retry logic out of tickcmpr_set() and sys_tickcmpr_set() into tick_rearm() and sys_tick_rearm(), respectively.
As far as I know, the retry logic in these assembly routines is not defective, but keeping equivalent code similar is good and it doesn't hurt to have less assembly code where it isn't strictly necessary. With this complete, we can then rebase and retry the clockintr switch patch for sparc64. ok? Index: clock.c =================================================================== RCS file: /cvs/src/sys/arch/sparc64/sparc64/clock.c,v retrieving revision 1.73 diff -u -p -r1.73 clock.c --- clock.c 22 Dec 2022 19:51:11 -0000 1.73 +++ clock.c 22 Dec 2022 23:04:49 -0000 @@ -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,18 +877,28 @@ 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) { struct cpu_info *ci = curcpu(); @@ -897,29 +909,34 @@ 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) { struct cpu_info *ci = curcpu(); u_int64_t s; 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(); Index: locore.s =================================================================== RCS file: /cvs/src/sys/arch/sparc64/sparc64/locore.s,v retrieving revision 1.195 diff -u -p -r1.195 locore.s --- locore.s 22 Dec 2022 19:51:11 -0000 1.195 +++ locore.s 22 Dec 2022 23:04:51 -0000 @@ -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)