[PATCH] alpha: Use work_on_cpu() for cross-CPU RTC access

Matt Turner <[email protected]> Thu, 28 May 2026 19:07:50 -0400
Newsgroups org.kernel.vger.linux-alpha,org.kernel.vger.linux-kernel,org.kernel.vger.stable
Message-ID <[email protected]>
smp_call_function_single() runs its callback in IPI (hardirq)
context. mc146818_set_time() and mc146818_get_time() take rtc_lock
(spinlock_t), which is a sleeping lock on PREEMPT_RT, triggering
a lockdep "Invalid wait context" splat on Marvel SMP.

work_on_cpu() runs the callback in a kthread (process) context,
which can acquire sleeping locks.

Cc: [email protected]
Assisted-by: Claude:claude-sonnet-4-6
Signed-off-by: Matt Turner <[email protected]>
---
 arch/alpha/kernel/rtc.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git ./arch/alpha/kernel/rtc.c ./arch/alpha/kernel/rtc.c
index cfdf90bc8b3f..4ad5846a1d71 100644
--- ./arch/alpha/kernel/rtc.c
+++ ./arch/alpha/kernel/rtc.c
@@ -15,6 +15,7 @@
 #include <linux/bcd.h>
 #include <linux/rtc.h>
 #include <linux/platform_device.h>
+#include <linux/workqueue.h>
 
 #include "proto.h"
 
@@ -155,11 +156,12 @@ union remote_data {
 	long retval;
 };
 
-static void
+static long
 do_remote_read(void *data)
 {
 	union remote_data *x = data;
 	x->retval = alpha_rtc_read_time(NULL, x->tm);
+	return 0;
 }
 
 static int
@@ -168,17 +170,18 @@ remote_read_time(struct device *dev, struct rtc_time *tm)
 	union remote_data x;
 	if (smp_processor_id() != boot_cpuid) {
 		x.tm = tm;
-		smp_call_function_single(boot_cpuid, do_remote_read, &x, 1);
+		work_on_cpu(boot_cpuid, do_remote_read, &x);
 		return x.retval;
 	}
 	return alpha_rtc_read_time(NULL, tm);
 }
 
-static void
+static long
 do_remote_set(void *data)
 {
 	union remote_data *x = data;
 	x->retval = alpha_rtc_set_time(NULL, x->tm);
+	return 0;
 }
 
 static int
@@ -187,7 +190,7 @@ remote_set_time(struct device *dev, struct rtc_time *tm)
 	union remote_data x;
 	if (smp_processor_id() != boot_cpuid) {
 		x.tm = tm;
-		smp_call_function_single(boot_cpuid, do_remote_set, &x, 1);
+		work_on_cpu(boot_cpuid, do_remote_set, &x);
 		return x.retval;
 	}
 	return alpha_rtc_set_time(NULL, tm);
-- 
2.53.0