From: Boqun Feng <boqun@kernel.org>
To: Peter Zijlstra <peterz@infradead.org>
Cc: "Ingo Molnar" <mingo@kernel.org>, "Will Deacon" <will@kernel.org>,
"Boqun Feng" <boqun@kernel.org>,
"Waiman Long" <longman@redhat.com>, "Gary Guo" <gary@garyguo.net>,
"Alice Ryhl" <aliceryhl@google.com>,
"Lyude Paul" <lyude@redhat.com>,
"Daniel Almeida" <daniel.almeida@collabora.com>,
"Onur Özkan" <work@onurozkan.dev>,
"Miguel Ojeda" <ojeda@kernel.org>,
"Danilo Krummrich" <dakr@kernel.org>,
linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org,
"Heiko Carstens" <hca@linux.ibm.com>
Subject: [PATCH 12/24] s390/preempt: Enable HAS_SEPARATE_PREEMPT_RESCHED_BITS
Date: Fri, 31 Jul 2026 13:30:13 -0700 [thread overview]
Message-ID: <20260731203031.13679-13-boqun@kernel.org> (raw)
In-Reply-To: <20260731203031.13679-1-boqun@kernel.org>
From: Heiko Carstens <hca@linux.ibm.com>
Convert s390's preempt_count to 64 bit, and change the preempt
primitives accordingly.
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Boqun Feng <boqun@kernel.org>
Link: https://patch.msgid.link/20260509181249.16281C67-hca@linux.ibm.com
---
arch/s390/Kconfig | 1 +
arch/s390/include/asm/lowcore.h | 13 +++++++----
arch/s390/include/asm/preempt.h | 41 +++++++++++++++------------------
3 files changed, 29 insertions(+), 26 deletions(-)
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 84404e6778d5..378fcd2b6181 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -273,6 +273,7 @@ config S390
select PCI_MSI if PCI
select PCI_MSI_ARCH_FALLBACKS if PCI_MSI
select PCI_QUIRKS if PCI
+ select HAS_SEPARATE_PREEMPT_RESCHED_BITS
select SPARSE_IRQ
select SWIOTLB
select SYSCTL_EXCEPTION_TRACE
diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h
index 3b3ecc647993..5cef215d30e7 100644
--- a/arch/s390/include/asm/lowcore.h
+++ b/arch/s390/include/asm/lowcore.h
@@ -160,10 +160,15 @@ struct lowcore {
/* SMP info area */
__u32 cpu_nr; /* 0x03a0 */
__u32 softirq_pending; /* 0x03a4 */
- __s32 preempt_count; /* 0x03a8 */
- __u32 spinlock_lockval; /* 0x03ac */
- __u32 spinlock_index; /* 0x03b0 */
- __u8 pad_0x03b4[0x03b8-0x03b4]; /* 0x03b4 */
+ union {
+ struct {
+ __u32 need_resched; /* 0x03a8 */
+ __u32 count; /* 0x03ac */
+ } preempt;
+ __u64 preempt_count; /* 0x03a8 */
+ };
+ __u32 spinlock_lockval; /* 0x03b0 */
+ __u32 spinlock_index; /* 0x03b4 */
__u64 percpu_offset; /* 0x03b8 */
__u8 percpu_register; /* 0x03c0 */
__u8 pad_0x03c1[0x0400-0x03c1]; /* 0x03c1 */
diff --git a/arch/s390/include/asm/preempt.h b/arch/s390/include/asm/preempt.h
index 0a25d4648b4c..1d5e4d7e9e1b 100644
--- a/arch/s390/include/asm/preempt.h
+++ b/arch/s390/include/asm/preempt.h
@@ -8,11 +8,8 @@
#include <asm/cmpxchg.h>
#include <asm/march.h>
-/*
- * Use MSB so it is possible to read preempt_count with LLGT which
- * reads the least significant 31 bits with a single instruction.
- */
-#define PREEMPT_NEED_RESCHED 0x80000000
+/* Use MSB for PREEMPT_NEED_RESCHED mostly because it is available. */
+#define PREEMPT_NEED_RESCHED 0x8000000000000000UL
/*
* We use the PREEMPT_NEED_RESCHED bit as an inverted NEED_RESCHED such
@@ -26,25 +23,25 @@
*/
static __always_inline int preempt_count(void)
{
- unsigned long lc_preempt, count;
+ unsigned long lc_preempt;
+ int count;
- BUILD_BUG_ON(sizeof_field(struct lowcore, preempt_count) != sizeof(int));
- lc_preempt = offsetof(struct lowcore, preempt_count);
+ lc_preempt = offsetof(struct lowcore, preempt.count);
/* READ_ONCE(get_lowcore()->preempt_count) & ~PREEMPT_NEED_RESCHED */
asm_inline(
- ALTERNATIVE("llgt %[count],%[offzero](%%r0)\n",
- "llgt %[count],%[offalt](%%r0)\n",
+ ALTERNATIVE("ly %[count],%[offzero](%%r0)\n",
+ "ly %[count],%[offalt](%%r0)\n",
ALT_FEATURE(MFEATURE_LOWCORE))
: [count] "=d" (count)
: [offzero] "i" (lc_preempt),
[offalt] "i" (lc_preempt + LOWCORE_ALT_ADDRESS),
- "m" (((struct lowcore *)0)->preempt_count));
+ "m" (((struct lowcore *)0)->preempt.count));
return count;
}
-static __always_inline void preempt_count_set(int pc)
+static __always_inline void preempt_count_set(unsigned long pc)
{
- int old, new;
+ unsigned long old, new;
old = READ_ONCE(get_lowcore()->preempt_count);
do {
@@ -63,12 +60,12 @@ static __always_inline void preempt_count_set(int pc)
static __always_inline void set_preempt_need_resched(void)
{
- __atomic_and(~PREEMPT_NEED_RESCHED, &get_lowcore()->preempt_count);
+ __atomic64_and(~PREEMPT_NEED_RESCHED, (long *)&get_lowcore()->preempt_count);
}
static __always_inline void clear_preempt_need_resched(void)
{
- __atomic_or(PREEMPT_NEED_RESCHED, &get_lowcore()->preempt_count);
+ __atomic64_or(PREEMPT_NEED_RESCHED, (long *)&get_lowcore()->preempt_count);
}
static __always_inline bool test_preempt_need_resched(void)
@@ -88,8 +85,8 @@ static __always_inline void __preempt_count_add(int val)
lc_preempt = offsetof(struct lowcore, preempt_count);
asm_inline(
- ALTERNATIVE("asi %[offzero](%%r0),%[val]\n",
- "asi %[offalt](%%r0),%[val]\n",
+ ALTERNATIVE("agsi %[offzero](%%r0),%[val]\n",
+ "agsi %[offalt](%%r0),%[val]\n",
ALT_FEATURE(MFEATURE_LOWCORE))
: "+m" (((struct lowcore *)0)->preempt_count)
: [offzero] "i" (lc_preempt), [val] "i" (val),
@@ -98,7 +95,7 @@ static __always_inline void __preempt_count_add(int val)
return;
}
}
- __atomic_add(val, &get_lowcore()->preempt_count);
+ __atomic64_add(val, (long *)&get_lowcore()->preempt_count);
}
static __always_inline void __preempt_count_sub(int val)
@@ -119,15 +116,15 @@ static __always_inline bool __preempt_count_dec_and_test(void)
lc_preempt = offsetof(struct lowcore, preempt_count);
asm_inline(
- ALTERNATIVE("alsi %[offzero](%%r0),%[val]\n",
- "alsi %[offalt](%%r0),%[val]\n",
+ ALTERNATIVE("algsi %[offzero](%%r0),%[val]\n",
+ "algsi %[offalt](%%r0),%[val]\n",
ALT_FEATURE(MFEATURE_LOWCORE))
: "=@cc" (cc), "+m" (((struct lowcore *)0)->preempt_count)
: [offzero] "i" (lc_preempt), [val] "i" (-1),
[offalt] "i" (lc_preempt + LOWCORE_ALT_ADDRESS));
return (cc == 0) || (cc == 2);
#else
- return __atomic_add_const_and_test(-1, &get_lowcore()->preempt_count);
+ return __atomic64_add_const_and_test(-1, (long *)&get_lowcore()->preempt_count);
#endif
}
@@ -141,7 +138,7 @@ static __always_inline bool should_resched(int preempt_offset)
static __always_inline int __preempt_count_add_return(int val)
{
- return val + __atomic_add(val, &get_lowcore()->preempt_count);
+ return val + __atomic64_add(val, (long *)&get_lowcore()->preempt_count);
}
static __always_inline int __preempt_count_sub_return(int val)
--
2.50.1 (Apple Git-155)
next prev parent reply other threads:[~2026-07-31 20:30 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-31 20:30 [GIT PULL] [PATCH 00/24] Rust synchronization changes for v7.3 Boqun Feng
2026-07-31 20:30 ` [PATCH 01/24] preempt: Track NMI nesting to separate per-CPU counter Boqun Feng
2026-07-31 20:30 ` [PATCH 02/24] preempt: Introduce HARDIRQ_DISABLE_BITS Boqun Feng
2026-07-31 20:30 ` [PATCH 03/24] preempt: Introduce __preempt_count_{sub, add}_return() Boqun Feng
2026-07-31 20:30 ` [PATCH 04/24] openrisc: Include <linux/cpumask.h> in smp.h Boqun Feng
2026-07-31 20:30 ` [PATCH 05/24] irq & spin_lock: Add counted interrupt disabling/enabling Boqun Feng
2026-07-31 20:30 ` [PATCH 06/24] irq: Add KUnit test for refcounted interrupt enable/disable Boqun Feng
2026-07-31 20:30 ` [PATCH 07/24] locking: Switch to _irq_{disable,enable}() variants in cleanup guards Boqun Feng
2026-07-31 20:30 ` [PATCH 08/24] sched: Remove the unused preempt_offset parameter of __cant_sleep() Boqun Feng
2026-07-31 20:30 ` [PATCH 09/24] sched: Avoid signed comparison of preempt_count() in __cant_migrate() Boqun Feng
2026-07-31 20:30 ` [PATCH 10/24] preempt: Introduce HAS_SEPARATE_PREEMPT_RESCHED_BITS Boqun Feng
2026-07-31 20:30 ` [PATCH 11/24] arm64: sched/preempt: Enable HAS_SEPARATE_PREEMPT_RESCHED_BITS Boqun Feng
2026-07-31 20:30 ` Boqun Feng [this message]
2026-07-31 20:30 ` [PATCH 13/24] irq: Optimize reschedule check in local_interrupt_enable() Boqun Feng
2026-07-31 20:30 ` [PATCH 14/24] rust: Introduce interrupt module Boqun Feng
2026-07-31 20:30 ` [PATCH 15/24] rust: helper: Add spin_{un,}lock_irq_{enable,disable}() helpers Boqun Feng
2026-07-31 20:30 ` [PATCH 16/24] rust: sync: use super::* in spinlock.rs Boqun Feng
2026-07-31 20:30 ` [PATCH 17/24] rust: sync: Add SpinLockIrq Boqun Feng
2026-07-31 20:30 ` [PATCH 18/24] rust: sync: Introduce SpinLockIrq::lock_with() and friends Boqun Feng
2026-07-31 20:30 ` [PATCH 19/24] rust: sync: Add abstraction for synchronize_rcu() Boqun Feng
2026-07-31 20:30 ` [PATCH 20/24] rust: revocable: Use safe synchronize_rcu() abstraction Boqun Feng
2026-07-31 20:30 ` [PATCH 21/24] rust: sync: Use safe synchronize_rcu() abstraction in poll Boqun Feng
2026-07-31 20:30 ` [PATCH 22/24] rust: sync: Add helpers for mb, dma_mb and friends Boqun Feng
2026-07-31 20:30 ` [PATCH 23/24] rust: sync: Add generic memory barriers Boqun Feng
2026-07-31 20:30 ` [PATCH 24/24] rust: revocable: Use LKMM atomics instead of Rust atomics Boqun Feng
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260731203031.13679-13-boqun@kernel.org \
--to=boqun@kernel.org \
--cc=aliceryhl@google.com \
--cc=dakr@kernel.org \
--cc=daniel.almeida@collabora.com \
--cc=gary@garyguo.net \
--cc=hca@linux.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=longman@redhat.com \
--cc=lyude@redhat.com \
--cc=mingo@kernel.org \
--cc=ojeda@kernel.org \
--cc=peterz@infradead.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=will@kernel.org \
--cc=work@onurozkan.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox