On 19/05/23 12:21, Peter Zijlstra wrote: > With the intent to provide local_clock_noinstr(), a variant of > local_clock() that's safe to be called from noinstr code (with the > assumption that any such code will already be non-preemptible), > prepare for things by providing a noinstr sched_clock_read() function. > > Specifically, preempt_enable_*() calls out to schedule(), which upsets > noinstr validation efforts. > > Signed-off-by: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx> > --- > arch/arm64/include/asm/arch_timer.h | 8 ---- > drivers/clocksource/arm_arch_timer.c | 60 ++++++++++++++++++++++++++--------- > 2 files changed, 47 insertions(+), 21 deletions(-) > > --- a/arch/arm64/include/asm/arch_timer.h > +++ b/arch/arm64/include/asm/arch_timer.h > @@ -88,13 +88,7 @@ static inline notrace u64 arch_timer_rea > > #define arch_timer_reg_read_stable(reg) \ > ({ \ > - u64 _val; \ > - \ > - preempt_disable_notrace(); \ > - _val = erratum_handler(read_ ## reg)(); \ > - preempt_enable_notrace(); \ > - \ > - _val; \ > + erratum_handler(read_ ## reg)(); \ > }) > > /* > --- a/drivers/clocksource/arm_arch_timer.c > +++ b/drivers/clocksource/arm_arch_timer.c > @@ -191,22 +191,40 @@ u32 arch_timer_reg_read(int access, enum > return val; > } > > -static notrace u64 arch_counter_get_cntpct_stable(void) > +static noinstr u64 _arch_counter_get_cntpct_stable(void) > { > return __arch_counter_get_cntpct_stable(); > } > I tripped over the underscores when reviewing this :( This must be getting close to the symbol length limit, but could we give this a helpful prefix or suffix? raw_* or *_noinstr? > @@ -1074,6 +1092,13 @@ struct arch_timer_kvm_info *arch_timer_g > > static void __init arch_counter_register(unsigned type) > { > + /* > + * Default to cp15 based access because arm64 uses this function for > + * sched_clock() before DT is probed and the cp15 method is guaranteed > + * to exist on arm64. arm doesn't use this before DT is probed so even > + * if we don't have the cp15 accessors we won't have a problem. > + */ > + u64 (*scr)(void) = arch_counter_get_cntvct; So this bit sent me on a little spelunking session :-) >From a control flow perspective the initialization isn't required, but then I looked into the comment and found it comes from the arch_timer_read_counter() definition... Which itself doesn't get used by sched_clock() until the sched_clock_register() below! So AFAICT that comment was true as of 220069945b29 ("clocksource: arch_timer: Add support for memory mapped timers") but not after a commit that came 2 months later: 65cd4f6c99c1 ("arch_timer: Move to generic sched_clock framework") which IIUC made arm/arm64 follow the default approach of using the jiffy-based sched_clock() before probing DT/ACPI and registering a "proper" sched_clock. All of that to say: the comment about arch_timer_read_counter() vs early sched_clock() doesn't apply anymore, but I think we need to keep its initalization around for stuff like get_cycles(). This initialization here should be OK to put to the bin, though.