From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-yx1-f48.google.com (mail-yx1-f48.google.com [74.125.224.48]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 67BB734EF03 for ; Mon, 10 Aug 2026 20:28:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.224.48 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786393719; cv=none; b=feTCsGQ2ZZvBGIUhYFIG0Dmcq7R+QXseDw5C0rlpERPXR3o+h7VYgIQ1PlAeCP0NosVoDsJpnzA0EJRCKyLLILksCq4fiLxyTQYJl+eBYa8rbUPz9sc+2CgyqYcYspcL6IVaNOOZFVjEXkXbXsgFHh/ufJYU2YU0ZD8p/TT2pAk= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786393719; c=relaxed/simple; bh=9C9TgfXvkBzp6XYopWkeSHxNp6MGu7RsULLPbYf/Sfs=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=G9+rc/2gcb5zdXJk1uBUOYqr5mz9UaZt8ftOrsjDZpWHXZrOCS6IEcFrKiWuC6eJvTrPRPNcyqkH4cKixD8D9+ZonudzmOthnoXbsGguDnh6+buDgE2ZTCnTSDFLfewWo6cY+AsIFiQEhnTXMAr69pgnjELLyDYG8Enxrv4zHA8= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=RprA09/n; arc=none smtp.client-ip=74.125.224.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="RprA09/n" Received: by mail-yx1-f48.google.com with SMTP id 956f58d0204a3-668432fe416so92823d50.0 for ; Mon, 10 Aug 2026 13:28:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786393717; x=1786998517; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to:content-type; bh=q+DPdTtuH5XAk98BcCWRfP1NphG14hosZAKK3q89iAc=; b=RprA09/nfs+uWHRW0p56tJNoP99vLWIhzaqPzsksaXU9eJv9E2wtoPepfC5g9fR4Zi yMGzy6TP5xMv1OQBjw/z0dQjOqVlddBlBe1uNltSPeQD5JYqEwZ3CN2J1iFPlR4+Tul0 /Sb8ibjwsI4QU/fq2MHvP19qLl5E8d8I+j71yo8JXafsqhU/IonpgiQcKCeNXfzKaYZe EQj/LzeAY8XUrE1ifUUT2lS2cFJwNQ/U3S4AcIMLchP+rykGSlSq71kNRes161XC2isK ZCI1r3mrGM5xdqSl+rLAQHC1Dhj0BcGkHmSjpPkJNpoDHq7oomYmpX4tZYKdSvHQ89qS JbMA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786393717; x=1786998517; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=q+DPdTtuH5XAk98BcCWRfP1NphG14hosZAKK3q89iAc=; b=OsGC5Whthbo+yY1qFIdb1IP3t2HF2PuC102Qaop8kZf4t6Abo5L2NZ4X1d+aHVFolb Bl4ZFbAaBT4HgrYk9HL7pfe1Ha0HPPxyz+eBtz8Dz9aLW1aYx4HqA6JCZvtIGHAXoYJ/ obge8g2A524/ayO1fvZ1Hp2dQhtauls/KXK7wkUlGd7ixhqiuhbT1w3zKM6R9hbBj486 MsbADugBYXvmy8HoRIVb7ghDzf34sGCX4/L7W4nT5BnvgnFnwGtckEz8XjpvwfNlqjFa apGorCSjpngSxbMhsTYSktXo61GAKKMF8o211LUq8TVfxn0FtIj0V22YpdtGTyuWxHGP yFJg== X-Forwarded-Encrypted: i=1; AHgh+Rqv1FKZtCJcqd6gVxIVPLVaFuizPL3ZZYH1fZAOQRdt57XICKJaRSJrclWpgJvUltf2SYSQwKd2dPbe778=@vger.kernel.org X-Gm-Message-State: AOJu0Yw8901V6WsaRC38W68kFP6ROGrvEUNbvfApFA4zw0RW1j97FVJt SOsPvvEokfkUWMbZaFWP9RC7KWrplokxEsndHNWsbiKXdygt4RJL9c8X X-Gm-Gg: AR+sD11/DcnKWAu/9Dv9wO5YhRJJpmlj5PwZRdQpeFUxUrA5xfS+CF0siVSXt7lpMpo FnxNSHnu4VLbc0CsqcKYujOb2Cu89nlR6R8VUH9N1a+dkkPUxJYrcYossf/8HYGv9o4J8j/BwYz wvIzE5kSumSzQ2vesol0V03ZQK7rswfB0PCilN4WEpuw/ob9GuLGVaYtDCbyU5sccEhIk7smOmw M7YwGH8JsiBkBuaGh9WA87piauzN6XMU4Vv5qQANsHhYvxT1agD/Hxfeue+Af8QQkJee3q7vr4W 68lNiwMMFMEM0kLU2lsJ5fl0JYnsNPL7WSe1pQbmUrrFFcbt8zjDVAtexa7CNAWRaU4/eGGKPRu xIZcs7IR3jM8fCzJHBLGz4oHrGOIZ2ytnzgeJk8CW180V5MVZa8ddb/KQsb+Nfin13DiJrcu/RR Rz65TA6FQpWSrlYKDSVw9EgnjlQiQGIjWiWiSrKo49MD2JSzFiYltRiXUP X-Received: by 2002:a05:690e:488a:b0:667:5cde:6f36 with SMTP id 956f58d0204a3-6699ac4cafbmr19992520d50.33.1786393717369; Mon, 10 Aug 2026 13:28:37 -0700 (PDT) Received: from localhost ([67.197.119.189]) by smtp.gmail.com with ESMTPSA id 956f58d0204a3-66acafbbd4csm7020690d50.17.2026.08.10.13.28.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Aug 2026 13:28:36 -0700 (PDT) From: Matt Turner To: linux-alpha@vger.kernel.org Cc: Richard Henderson , Magnus Lindholm , Matt Turner , linux-kernel@vger.kernel.org Subject: [PATCH 1/2] alpha: run the remote RTC access in a worker, not an IPI callback Date: Mon, 10 Aug 2026 16:28:34 -0400 Message-ID: <20260810202835.3592833-1-mattst88@gmail.com> X-Mailer: git-send-email 2.54.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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: [] dump_stack+0x28/0x44 [] __lock_acquire+0xb0c/0x1060 [] lock_acquire.part.0+0xd0/0x300 [...] [] mc146818_set_time+0x74/0x450 [] _raw_spin_lock_irqsave+0x7c/0xc0 [] do_remote_set+0x90/0xc0 [] __flush_smp_call_function_queue+0x314/0x5c0 [] generic_smp_call_function_single_interrupt+0x24/0x40 [] handle_ipi+0xa4/0x230 [] 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 --- arch/alpha/kernel/rtc.c | 37 ++++++++++++------------------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/arch/alpha/kernel/rtc.c b/arch/alpha/kernel/rtc.c index cfdf90bc8b3f..9e7d714ef6f8 100644 --- a/arch/alpha/kernel/rtc.c +++ b/arch/alpha/kernel/rtc.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "proto.h" @@ -142,54 +143,40 @@ static const struct rtc_class_ops alpha_rtc_ops = { }; /* - * Similarly, except do the actual CMOS access on the boot cpu only. - * This requires marshalling the data across an interprocessor call. + * Similarly, except do the actual CMOS access on the boot cpu only. The + * access polls for the RTC update cycle and takes rtc_lock, so run it in a + * worker on that cpu rather than from an interprocessor interrupt. */ #if defined(CONFIG_SMP) && \ (defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_MARVEL)) # define HAVE_REMOTE_RTC 1 -union remote_data { - struct rtc_time *tm; - 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 alpha_rtc_read_time(NULL, data); } static int 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); - return x.retval; - } + if (smp_processor_id() != boot_cpuid) + return work_on_cpu(boot_cpuid, do_remote_read, tm); 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 alpha_rtc_set_time(NULL, data); } static int 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); - return x.retval; - } + if (smp_processor_id() != boot_cpuid) + return work_on_cpu(boot_cpuid, do_remote_set, tm); return alpha_rtc_set_time(NULL, tm); } -- 2.54.0