linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1 1/2] static_call: Properly initialise DEFINE_STATIC_CALL_RET0()
@ 2022-03-14 10:27 Christophe Leroy
  2022-03-14 10:27 ` [PATCH v1 2/2] static_call: Remove __DEFINE_STATIC_CALL macro Christophe Leroy
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Christophe Leroy @ 2022-03-14 10:27 UTC (permalink / raw)
  To: Peter Zijlstra, Josh Poimboeuf, Jason Baron, Steven Rostedt,
	Ard Biesheuvel, Thomas Gleixner, Michael Ellerman, Ingo Molnar,
	Borislav Petkov, Dave Hansen, H. Peter Anvin
  Cc: x86, linuxppc-dev, linux-kernel

When a static call is updated with __static_call_return0() as target,
arch_static_call_transform() set it to use an optimised set of
instructions which are meant to lay in the same cacheline.

But when initialising a static call with DEFINE_STATIC_CALL_RET0(),
we get a branch to the real __static_call_return0() function instead
of getting the optimised setup:

	c00d8120 <__SCT__perf_snapshot_branch_stack>:
	c00d8120:	4b ff ff f4 	b       c00d8114 <__static_call_return0>
	c00d8124:	3d 80 c0 0e 	lis     r12,-16370
	c00d8128:	81 8c 81 3c 	lwz     r12,-32452(r12)
	c00d812c:	7d 89 03 a6 	mtctr   r12
	c00d8130:	4e 80 04 20 	bctr
	c00d8134:	38 60 00 00 	li      r3,0
	c00d8138:	4e 80 00 20 	blr
	c00d813c:	00 00 00 00 	.long 0x0

Add ARCH_DEFINE_STATIC_CALL_RET0_TRAMP() defined by each architecture
to setup the optimised configuration, and rework
DEFINE_STATIC_CALL_RET0() to call it:

	c00d8120 <__SCT__perf_snapshot_branch_stack>:
	c00d8120:	48 00 00 14 	b       c00d8134 <__SCT__perf_snapshot_branch_stack+0x14>
	c00d8124:	3d 80 c0 0e 	lis     r12,-16370
	c00d8128:	81 8c 81 3c 	lwz     r12,-32452(r12)
	c00d812c:	7d 89 03 a6 	mtctr   r12
	c00d8130:	4e 80 04 20 	bctr
	c00d8134:	38 60 00 00 	li      r3,0
	c00d8138:	4e 80 00 20 	blr
	c00d813c:	00 00 00 00 	.long 0x0

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/powerpc/include/asm/static_call.h |  1 +
 arch/x86/include/asm/static_call.h     |  2 ++
 include/linux/static_call.h            | 20 +++++++++++++++++---
 3 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/include/asm/static_call.h b/arch/powerpc/include/asm/static_call.h
index 0a0bc79bd1fa..de1018cc522b 100644
--- a/arch/powerpc/include/asm/static_call.h
+++ b/arch/powerpc/include/asm/static_call.h
@@ -24,5 +24,6 @@
 
 #define ARCH_DEFINE_STATIC_CALL_TRAMP(name, func)	__PPC_SCT(name, "b " #func)
 #define ARCH_DEFINE_STATIC_CALL_NULL_TRAMP(name)	__PPC_SCT(name, "blr")
+#define ARCH_DEFINE_STATIC_CALL_RET0_TRAMP(name)	__PPC_SCT(name, "b .+20")
 
 #endif /* _ASM_POWERPC_STATIC_CALL_H */
diff --git a/arch/x86/include/asm/static_call.h b/arch/x86/include/asm/static_call.h
index ed4f8bb6c2d9..2455d721503e 100644
--- a/arch/x86/include/asm/static_call.h
+++ b/arch/x86/include/asm/static_call.h
@@ -38,6 +38,8 @@
 #define ARCH_DEFINE_STATIC_CALL_NULL_TRAMP(name)			\
 	__ARCH_DEFINE_STATIC_CALL_TRAMP(name, "ret; int3; nop; nop; nop")
 
+#define ARCH_DEFINE_STATIC_CALL_RET0_TRAMP(name)			\
+	ARCH_DEFINE_STATIC_CALL_TRAMP(name, __static_call_return0)
 
 #define ARCH_ADD_TRAMP_KEY(name)					\
 	asm(".pushsection .static_call_tramp_key, \"a\"		\n"	\
diff --git a/include/linux/static_call.h b/include/linux/static_call.h
index fcc5b48989b3..3c50b0fdda16 100644
--- a/include/linux/static_call.h
+++ b/include/linux/static_call.h
@@ -196,6 +196,14 @@ extern long __static_call_return0(void);
 	};								\
 	ARCH_DEFINE_STATIC_CALL_NULL_TRAMP(name)
 
+#define DEFINE_STATIC_CALL_RET0(name, _func)				\
+	DECLARE_STATIC_CALL(name, _func);				\
+	struct static_call_key STATIC_CALL_KEY(name) = {		\
+		.func = __static_call_return0,				\
+		.type = 1,						\
+	};								\
+	ARCH_DEFINE_STATIC_CALL_RET0_TRAMP(name)
+
 #define static_call_cond(name)	(void)__static_call(name)
 
 #define EXPORT_STATIC_CALL(name)					\
@@ -231,6 +239,12 @@ static inline int static_call_init(void) { return 0; }
 	};								\
 	ARCH_DEFINE_STATIC_CALL_NULL_TRAMP(name)
 
+#define DEFINE_STATIC_CALL_RET0(name, _func)				\
+	DECLARE_STATIC_CALL(name, _func);				\
+	struct static_call_key STATIC_CALL_KEY(name) = {		\
+		.func = __static_call_return0,				\
+	};								\
+	ARCH_DEFINE_STATIC_CALL_RET0_TRAMP(name)
 
 #define static_call_cond(name)	(void)__static_call(name)
 
@@ -284,6 +298,9 @@ static inline long __static_call_return0(void)
 		.func = NULL,						\
 	}
 
+#define DEFINE_STATIC_CALL_RET0(name, _func)				\
+	__DEFINE_STATIC_CALL(name, _func, __static_call_return0)
+
 static inline void __static_call_nop(void) { }
 
 /*
@@ -327,7 +344,4 @@ static inline int static_call_text_reserved(void *start, void *end)
 #define DEFINE_STATIC_CALL(name, _func)					\
 	__DEFINE_STATIC_CALL(name, _func, _func)
 
-#define DEFINE_STATIC_CALL_RET0(name, _func)				\
-	__DEFINE_STATIC_CALL(name, _func, __static_call_return0)
-
 #endif /* _LINUX_STATIC_CALL_H */
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v1 2/2] static_call: Remove __DEFINE_STATIC_CALL macro
  2022-03-14 10:27 [PATCH v1 1/2] static_call: Properly initialise DEFINE_STATIC_CALL_RET0() Christophe Leroy
@ 2022-03-14 10:27 ` Christophe Leroy
  2022-03-15 22:10   ` Josh Poimboeuf
  2022-03-15 22:10 ` [PATCH v1 1/2] static_call: Properly initialise DEFINE_STATIC_CALL_RET0() Josh Poimboeuf
  2022-03-18 17:39 ` Peter Zijlstra
  2 siblings, 1 reply; 5+ messages in thread
From: Christophe Leroy @ 2022-03-14 10:27 UTC (permalink / raw)
  To: Peter Zijlstra, Josh Poimboeuf, Jason Baron, Steven Rostedt,
	Ard Biesheuvel, Thomas Gleixner, Michael Ellerman, Ingo Molnar,
	Borislav Petkov, Dave Hansen, H. Peter Anvin
  Cc: x86, linuxppc-dev, linux-kernel

Only DEFINE_STATIC_CALL use __DEFINE_STATIC_CALL macro now when
CONFIG_HAVE_STATIC_CALL is selected.

Only keep __DEFINE_STATIC_CALL() for the generic fallback, and
also use it to implement DEFINE_STATIC_CALL_NULL() in that case.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 include/linux/static_call.h | 23 ++++++++++-------------
 1 file changed, 10 insertions(+), 13 deletions(-)

diff --git a/include/linux/static_call.h b/include/linux/static_call.h
index 3c50b0fdda16..df53bed9d71f 100644
--- a/include/linux/static_call.h
+++ b/include/linux/static_call.h
@@ -180,13 +180,13 @@ extern int static_call_text_reserved(void *start, void *end);
 
 extern long __static_call_return0(void);
 
-#define __DEFINE_STATIC_CALL(name, _func, _func_init)			\
+#define DEFINE_STATIC_CALL(name, _func)					\
 	DECLARE_STATIC_CALL(name, _func);				\
 	struct static_call_key STATIC_CALL_KEY(name) = {		\
-		.func = _func_init,					\
+		.func = _func,						\
 		.type = 1,						\
 	};								\
-	ARCH_DEFINE_STATIC_CALL_TRAMP(name, _func_init)
+	ARCH_DEFINE_STATIC_CALL_TRAMP(name, _func)
 
 #define DEFINE_STATIC_CALL_NULL(name, _func)				\
 	DECLARE_STATIC_CALL(name, _func);				\
@@ -225,12 +225,12 @@ extern long __static_call_return0(void);
 
 static inline int static_call_init(void) { return 0; }
 
-#define __DEFINE_STATIC_CALL(name, _func, _func_init)			\
+#define DEFINE_STATIC_CALL(name, _func)					\
 	DECLARE_STATIC_CALL(name, _func);				\
 	struct static_call_key STATIC_CALL_KEY(name) = {		\
-		.func = _func_init,					\
+		.func = _func,						\
 	};								\
-	ARCH_DEFINE_STATIC_CALL_TRAMP(name, _func_init)
+	ARCH_DEFINE_STATIC_CALL_TRAMP(name, _func)
 
 #define DEFINE_STATIC_CALL_NULL(name, _func)				\
 	DECLARE_STATIC_CALL(name, _func);				\
@@ -292,11 +292,11 @@ static inline long __static_call_return0(void)
 		.func = _func_init,					\
 	}
 
+#define DEFINE_STATIC_CALL(name, _func)					\
+	__DEFINE_STATIC_CALL(name, _func, _func)
+
 #define DEFINE_STATIC_CALL_NULL(name, _func)				\
-	DECLARE_STATIC_CALL(name, _func);				\
-	struct static_call_key STATIC_CALL_KEY(name) = {		\
-		.func = NULL,						\
-	}
+	__DEFINE_STATIC_CALL(name, _func, NULL)
 
 #define DEFINE_STATIC_CALL_RET0(name, _func)				\
 	__DEFINE_STATIC_CALL(name, _func, __static_call_return0)
@@ -341,7 +341,4 @@ static inline int static_call_text_reserved(void *start, void *end)
 
 #endif /* CONFIG_HAVE_STATIC_CALL */
 
-#define DEFINE_STATIC_CALL(name, _func)					\
-	__DEFINE_STATIC_CALL(name, _func, _func)
-
 #endif /* _LINUX_STATIC_CALL_H */
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v1 1/2] static_call: Properly initialise DEFINE_STATIC_CALL_RET0()
  2022-03-14 10:27 [PATCH v1 1/2] static_call: Properly initialise DEFINE_STATIC_CALL_RET0() Christophe Leroy
  2022-03-14 10:27 ` [PATCH v1 2/2] static_call: Remove __DEFINE_STATIC_CALL macro Christophe Leroy
@ 2022-03-15 22:10 ` Josh Poimboeuf
  2022-03-18 17:39 ` Peter Zijlstra
  2 siblings, 0 replies; 5+ messages in thread
From: Josh Poimboeuf @ 2022-03-15 22:10 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: x86, Peter Zijlstra, Dave Hansen, linux-kernel, Steven Rostedt,
	Jason Baron, Ingo Molnar, Borislav Petkov, H. Peter Anvin,
	Thomas Gleixner, linuxppc-dev, Ard Biesheuvel

On Mon, Mar 14, 2022 at 11:27:35AM +0100, Christophe Leroy wrote:
>  #define ARCH_DEFINE_STATIC_CALL_TRAMP(name, func)	__PPC_SCT(name, "b " #func)
>  #define ARCH_DEFINE_STATIC_CALL_NULL_TRAMP(name)	__PPC_SCT(name, "blr")
> +#define ARCH_DEFINE_STATIC_CALL_RET0_TRAMP(name)	__PPC_SCT(name, "b .+20")

There's a PPC_SCT_RET0 macro for this "20" offset, might as well use a
stringified version of that for robustness/readability.

Otherwise it looks reasonable.

Acked-by: Josh Poimboeuf <jpoimboe@redhat.com>

-- 
Josh


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v1 2/2] static_call: Remove __DEFINE_STATIC_CALL macro
  2022-03-14 10:27 ` [PATCH v1 2/2] static_call: Remove __DEFINE_STATIC_CALL macro Christophe Leroy
@ 2022-03-15 22:10   ` Josh Poimboeuf
  0 siblings, 0 replies; 5+ messages in thread
From: Josh Poimboeuf @ 2022-03-15 22:10 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: x86, Peter Zijlstra, Dave Hansen, linux-kernel, Steven Rostedt,
	Jason Baron, Ingo Molnar, Borislav Petkov, H. Peter Anvin,
	Thomas Gleixner, linuxppc-dev, Ard Biesheuvel

On Mon, Mar 14, 2022 at 11:27:36AM +0100, Christophe Leroy wrote:
> Only DEFINE_STATIC_CALL use __DEFINE_STATIC_CALL macro now when
> CONFIG_HAVE_STATIC_CALL is selected.
> 
> Only keep __DEFINE_STATIC_CALL() for the generic fallback, and
> also use it to implement DEFINE_STATIC_CALL_NULL() in that case.
> 
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>

Acked-by: Josh Poimboeuf <jpoimboe@redhat.com>

-- 
Josh


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v1 1/2] static_call: Properly initialise DEFINE_STATIC_CALL_RET0()
  2022-03-14 10:27 [PATCH v1 1/2] static_call: Properly initialise DEFINE_STATIC_CALL_RET0() Christophe Leroy
  2022-03-14 10:27 ` [PATCH v1 2/2] static_call: Remove __DEFINE_STATIC_CALL macro Christophe Leroy
  2022-03-15 22:10 ` [PATCH v1 1/2] static_call: Properly initialise DEFINE_STATIC_CALL_RET0() Josh Poimboeuf
@ 2022-03-18 17:39 ` Peter Zijlstra
  2 siblings, 0 replies; 5+ messages in thread
From: Peter Zijlstra @ 2022-03-18 17:39 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: x86, H. Peter Anvin, Dave Hansen, linux-kernel, Steven Rostedt,
	Jason Baron, Ingo Molnar, Borislav Petkov, Josh Poimboeuf,
	Thomas Gleixner, linuxppc-dev, Ard Biesheuvel



Thanks!

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2022-03-18 17:40 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-03-14 10:27 [PATCH v1 1/2] static_call: Properly initialise DEFINE_STATIC_CALL_RET0() Christophe Leroy
2022-03-14 10:27 ` [PATCH v1 2/2] static_call: Remove __DEFINE_STATIC_CALL macro Christophe Leroy
2022-03-15 22:10   ` Josh Poimboeuf
2022-03-15 22:10 ` [PATCH v1 1/2] static_call: Properly initialise DEFINE_STATIC_CALL_RET0() Josh Poimboeuf
2022-03-18 17:39 ` Peter Zijlstra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).