summaryrefslogtreecommitdiff
path: root/tools/perf/scripts/python/task-analyzer.py
diff options
context:
space:
mode:
authorMatt Turner <mattst88@gmail.com>2026-08-10 16:28:34 -0400
committerMagnus Lindholm <linmag7@gmail.com>2026-08-11 23:23:47 +0200
commit6f45effbd74012f1715584ba51abaa3196a47c08 (patch)
treef56bdc2fc949b95c94ec0b32a87da6b11f322465 /tools/perf/scripts/python/task-analyzer.py
parentbcfe3187412e342b4619efb92c945f073855ebc0 (diff)
alpha: run the remote RTC access in a worker, not an IPI callback
On Marvel the CMOS clock is only reachable from the boot cpu, so remote_read_time() and remote_set_time() bounce the access there with smp_call_function_single(), whose callback runs in hard interrupt context. alpha_rtc_read_time() calls mc146818_get_time() with a 10 ms timeout. That waits out the RTC update cycle in mc146818_avoid_UIP(), which drops rtc_lock and udelay()s 100 us at a time until the update completes or the timeout expires: for (i = 0; UIP_RECHECK_LOOPS_MS(i) < timeout; i++) { spin_lock_irqsave(&rtc_lock, flags); ... if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) { spin_unlock_irqrestore(&rtc_lock, flags); udelay(UIP_RECHECK_DELAY); continue; } So a clock read from a non-boot cpu can spin for up to 10 ms in hard interrupt context on the boot cpu, while the cpu that sent the request spins in smp_call_function_single() waiting for it to finish. mc146818_set_time() does not poll, but it takes rtc_lock too, and rtc_lock is a spinlock_t. Only raw spinlocks may be taken in hard interrupt context, so lockdep reports the write path as soon as a non-boot cpu sets the clock: [ BUG: Invalid wait context ] ----------------------------- swapper/0/0 is trying to lock: fffffc0003690470 (rtc_lock){....}-{3:3}, at: mc146818_set_time+0x74/0x450 other info that might help us debug this: context-{2:2} no locks held by swapper/0/0. stack backtrace: CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 7.2.0-rc1 #1 NONE Trace: [<fffffc000102ebb0>] dump_stack+0x28/0x44 [<fffffc000110efcc>] __lock_acquire+0xb0c/0x1060 [<fffffc000110f5f0>] lock_acquire.part.0+0xd0/0x300 [...] [<fffffc0001b0d834>] mc146818_set_time+0x74/0x450 [<fffffc0001f090cc>] _raw_spin_lock_irqsave+0x7c/0xc0 [<fffffc0001042f90>] do_remote_set+0x90/0xc0 [<fffffc000119c1a4>] __flush_smp_call_function_queue+0x314/0x5c0 [<fffffc000119c474>] generic_smp_call_function_single_interrupt+0x24/0x40 [<fffffc000103d984>] handle_ipi+0xa4/0x230 [<fffffc0001037044>] do_entInt+0x1a4/0x2e0 The rtc class ops are always called from process context, so there is no reason to run the access from an interrupt at all. Use work_on_cpu() to run it in a worker on the boot cpu. Alpha does not support cpu hotplug, so the boot cpu cannot go offline while the work is pending. Tested on an AlphaServer ES47 (Marvel/EV7): hwclock read and write pinned to a non-boot cpu, twenty times, with no splat. Signed-off-by: Matt Turner <mattst88@gmail.com> Reviewed-by: Magnus Lindholm <linmag7@gmail.com> Link: https://lore.kernel.org/r/20260810202835.3592833-1-mattst88@gmail.com Signed-off-by: Magnus Lindholm <linmag7@gmail.com>
Diffstat (limited to 'tools/perf/scripts/python/task-analyzer.py')
0 files changed, 0 insertions, 0 deletions