summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeiko Carstens <hca@linux.ibm.com>2026-05-26 07:57:01 +0200
committerAlexander Gordeev <agordeev@linux.ibm.com>2026-06-03 15:32:47 +0200
commit9858c19a66386cb2553480643f2d4565993d1cd8 (patch)
tree24483ceee1ec27829d198e20fa853a5e6367795b
parentee8cefbfb0718bfe1460cf2ba72722c51f6789eb (diff)
s390/percpu: Provide arch_this_cpu_read() implementation
Provide an s390 specific implementation of arch_this_cpu_read() instead of the generic variant. The generic variant uses preempt_disable() / preempt_enable() pair and READ_ONCE(). Get rid of the preempt_disable() / preempt_enable() pairs by providing an own variant which makes use of the new percpu code section infrastructure. With this the text size of the kernel image is reduced by ~1k (defconfig). Also 87 generated preempt_schedule_notrace() function calls within the kernel image (modules not counted) are removed. Acked-by: Alexander Gordeev <agordeev@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
-rw-r--r--arch/s390/include/asm/percpu.h31
1 files changed, 31 insertions, 0 deletions
diff --git a/arch/s390/include/asm/percpu.h b/arch/s390/include/asm/percpu.h
index 5e0185e5960b..83195a5dc409 100644
--- a/arch/s390/include/asm/percpu.h
+++ b/arch/s390/include/asm/percpu.h
@@ -248,6 +248,37 @@ do { \
#endif /* MARCH_HAS_Z196_FEATURES */
+#define arch_this_cpu_read(pcp, op) \
+({ \
+ unsigned long lc_pcpr, lc_pcpo, res__; \
+ typedef typeof(pcp) pcp_op_T__; \
+ pcp_op_T__ *ptr__; \
+ \
+ lc_pcpr = offsetof(struct lowcore, percpu_register); \
+ lc_pcpo = offsetof(struct lowcore, percpu_offset); \
+ ptr__ = PERCPU_PTR(&(pcp)); \
+ asm_inline volatile( \
+ MVIY_PERCPU("%[disppcpr]", "%[dispaltpcpr]", "%[ptr__]")\
+ AG_ALT("%[disppcpo]", "%[dispaltpcpo]", "%[ptr__]") \
+ op " %[res__],0(%[ptr__])\n" \
+ MVIY_ALT("%[disppcpr]", "%[dispaltpcpr]") \
+ : [res__] "=&d" (res__), [ptr__] "+&a" (ptr__), \
+ "=m" (((struct lowcore *)0)->percpu_register) \
+ : [disppcpr] "i" (lc_pcpr), \
+ [disppcpo] "i" (lc_pcpo), \
+ [dispaltpcpr] "i" (lc_pcpr + LOWCORE_ALT_ADDRESS), \
+ [dispaltpcpo] "i" (lc_pcpo + LOWCORE_ALT_ADDRESS), \
+ "m" (*ptr__), \
+ "m" (((struct lowcore *)0)->percpu_offset) \
+ : "cc"); \
+ (pcp_op_T__)res__; \
+})
+
+#define this_cpu_read_1(pcp) arch_this_cpu_read(pcp, "llgc")
+#define this_cpu_read_2(pcp) arch_this_cpu_read(pcp, "llgh")
+#define this_cpu_read_4(pcp) arch_this_cpu_read(pcp, "llgf")
+#define this_cpu_read_8(pcp) arch_this_cpu_read(pcp, "lg")
+
#define arch_this_cpu_cmpxchg(pcp, oval, nval) \
({ \
typedef typeof(pcp) pcp_op_T__; \