* [PATCH v3 0/1] powerpc: Enable dynamic preemption
@ 2025-01-06 5:19 Shrikanth Hegde
2025-01-06 5:19 ` [PATCH v3 1/1] " Shrikanth Hegde
2025-01-21 7:25 ` [PATCH v3 0/1] " Shrikanth Hegde
0 siblings, 2 replies; 10+ messages in thread
From: Shrikanth Hegde @ 2025-01-06 5:19 UTC (permalink / raw)
To: mpe, maddy, linuxppc-dev; +Cc: sshegde, npiggin, christophe.leroy, linux-kernel
Now that preempt=lazy patches[1] are in powerpc-next tree, sending out the
patch to support dynamic preemption based on DYNAMIC_KEY.
base: powerpc-next
Once the arch supports static inline calls, it would be needed to
evaluate to see if that gives better performance.
v2->v3:
- fixed a build error reported by linux test robot by including jump
label header.
v1->v2:
- Instead of copying asm-generic preempt.h content include it in
arch/asm preempt.h. (Christophe Leroy)
- Merge the patches into one patch (Christophe Leroy)
v1: https://lore.kernel.org/all/20241125042212.1522315-1-sshegde@linux.ibm.com/
v2: https://lore.kernel.org/all/20250102191856.499424-1-sshegde@linux.ibm.com/
[1]: https://lore.kernel.org/all/173572211264.1875638.9927288574435880962.b4-ty@linux.ibm.com/
Shrikanth Hegde (1):
powerpc: Enable dynamic preemption
arch/powerpc/Kconfig | 1 +
arch/powerpc/include/asm/preempt.h | 12 ++++++++++++
arch/powerpc/kernel/interrupt.c | 6 +++++-
arch/powerpc/kernel/traps.c | 6 +++++-
arch/powerpc/lib/vmx-helper.c | 2 +-
5 files changed, 24 insertions(+), 3 deletions(-)
create mode 100644 arch/powerpc/include/asm/preempt.h
--
2.39.3
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v3 1/1] powerpc: Enable dynamic preemption
2025-01-06 5:19 [PATCH v3 0/1] powerpc: Enable dynamic preemption Shrikanth Hegde
@ 2025-01-06 5:19 ` Shrikanth Hegde
2025-01-30 14:54 ` Sebastian Andrzej Siewior
2025-01-21 7:25 ` [PATCH v3 0/1] " Shrikanth Hegde
1 sibling, 1 reply; 10+ messages in thread
From: Shrikanth Hegde @ 2025-01-06 5:19 UTC (permalink / raw)
To: mpe, maddy, linuxppc-dev; +Cc: sshegde, npiggin, christophe.leroy, linux-kernel
Once the lazy preemption is supported, it would be desirable to change
the preemption models at runtime. So add support for dynamic preemption
using DYNAMIC_KEY.
In irq-exit to kernel path, use preempt_model_preemptible for decision.
Other way would be using static key based decision. Keeping it
simpler since key based change didn't show performance improvement.
Also print the right preemption model in __die.
::Tested lightly on Power10 LPAR
Performance numbers indicate that, preempt=none(no dynamic) and
preempt=none(dynamic) are similar.
cat /sys/kernel/debug/sched/preempt
(none) voluntary full lazy
perf stat -e probe:__cond_resched -a sleep 1
Performance counter stats for 'system wide':
1,253 probe:__cond_resched
echo full > /sys/kernel/debug/sched/preempt
cat /sys/kernel/debug/sched/preempt
none voluntary (full) lazy
perf stat -e probe:__cond_resched -a sleep 1
Performance counter stats for 'system wide':
0 probe:__cond_resched
Signed-off-by: Shrikanth Hegde <sshegde@linux.ibm.com>
---
arch/powerpc/Kconfig | 1 +
arch/powerpc/include/asm/preempt.h | 12 ++++++++++++
arch/powerpc/kernel/interrupt.c | 6 +++++-
arch/powerpc/kernel/traps.c | 6 +++++-
arch/powerpc/lib/vmx-helper.c | 2 +-
5 files changed, 24 insertions(+), 3 deletions(-)
create mode 100644 arch/powerpc/include/asm/preempt.h
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index db9f7b2d07bf..b14218344e74 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -272,6 +272,7 @@ config PPC
select HAVE_PERF_EVENTS_NMI if PPC64
select HAVE_PERF_REGS
select HAVE_PERF_USER_STACK_DUMP
+ select HAVE_PREEMPT_DYNAMIC_KEY
select HAVE_RETHOOK if KPROBES
select HAVE_REGS_AND_STACK_ACCESS_API
select HAVE_RELIABLE_STACKTRACE
diff --git a/arch/powerpc/include/asm/preempt.h b/arch/powerpc/include/asm/preempt.h
new file mode 100644
index 000000000000..eb1ed8295f13
--- /dev/null
+++ b/arch/powerpc/include/asm/preempt.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_POWERPC_PREEMPT_H
+#define __ASM_POWERPC_PREEMPT_H
+
+#include <asm-generic/preempt.h>
+
+#if defined(CONFIG_PREEMPT_DYNAMIC) && defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
+#include <linux/jump_label.h>
+DECLARE_STATIC_KEY_TRUE(sk_dynamic_irqentry_exit_cond_resched);
+#endif
+
+#endif /* __ASM_POWERPC_PREEMPT_H */
diff --git a/arch/powerpc/kernel/interrupt.c b/arch/powerpc/kernel/interrupt.c
index 8f4acc55407b..8e2400ba208c 100644
--- a/arch/powerpc/kernel/interrupt.c
+++ b/arch/powerpc/kernel/interrupt.c
@@ -25,6 +25,10 @@
unsigned long global_dbcr0[NR_CPUS];
#endif
+#if defined(CONFIG_PREEMPT_DYNAMIC) && defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
+DEFINE_STATIC_KEY_TRUE(sk_dynamic_irqentry_exit_cond_resched);
+#endif
+
#ifdef CONFIG_PPC_BOOK3S_64
DEFINE_STATIC_KEY_FALSE(interrupt_exit_not_reentrant);
static inline bool exit_must_hard_disable(void)
@@ -396,7 +400,7 @@ notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs)
/* Returning to a kernel context with local irqs enabled. */
WARN_ON_ONCE(!(regs->msr & MSR_EE));
again:
- if (IS_ENABLED(CONFIG_PREEMPTION)) {
+ if (preempt_model_preemptible()) {
/* Return to preemptible kernel context */
if (unlikely(read_thread_flags() & _TIF_NEED_RESCHED)) {
if (preempt_count() == 0)
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index edf5cabe5dfd..2556fa8ec019 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -266,7 +266,11 @@ static int __die(const char *str, struct pt_regs *regs, long err)
printk("%s PAGE_SIZE=%luK%s%s%s%s%s%s %s\n",
IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN) ? "LE" : "BE",
PAGE_SIZE / 1024, get_mmu_str(),
- IS_ENABLED(CONFIG_PREEMPT) ? " PREEMPT" : "",
+ preempt_model_none() ? "none" :
+ preempt_model_voluntary() ? "voluntary" :
+ preempt_model_full() ? "full" :
+ preempt_model_lazy() ? "lazy" :
+ "",
IS_ENABLED(CONFIG_SMP) ? " SMP" : "",
IS_ENABLED(CONFIG_SMP) ? (" NR_CPUS=" __stringify(NR_CPUS)) : "",
debug_pagealloc_enabled() ? " DEBUG_PAGEALLOC" : "",
diff --git a/arch/powerpc/lib/vmx-helper.c b/arch/powerpc/lib/vmx-helper.c
index 58ed6bd613a6..7b069c832ce2 100644
--- a/arch/powerpc/lib/vmx-helper.c
+++ b/arch/powerpc/lib/vmx-helper.c
@@ -45,7 +45,7 @@ int exit_vmx_usercopy(void)
* set and we are preemptible. The hack here is to schedule a
* decrementer to fire here and reschedule for us if necessary.
*/
- if (IS_ENABLED(CONFIG_PREEMPTION) && need_resched())
+ if (preempt_model_preemptible() && need_resched())
set_dec(1);
return 0;
}
--
2.39.3
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v3 0/1] powerpc: Enable dynamic preemption
2025-01-06 5:19 [PATCH v3 0/1] powerpc: Enable dynamic preemption Shrikanth Hegde
2025-01-06 5:19 ` [PATCH v3 1/1] " Shrikanth Hegde
@ 2025-01-21 7:25 ` Shrikanth Hegde
1 sibling, 0 replies; 10+ messages in thread
From: Shrikanth Hegde @ 2025-01-21 7:25 UTC (permalink / raw)
To: mpe, maddy, linuxppc-dev
Cc: npiggin, christophe.leroy, linux-kernel,
Sebastian Andrzej Siewior, Ankur Arora
On 1/6/25 10:49, Shrikanth Hegde wrote:
> Now that preempt=lazy patches[1] are in powerpc-next tree, sending out the
> patch to support dynamic preemption based on DYNAMIC_KEY.
>
> base: powerpc-next
>
+ankur, sebastian; sorry for not cc'ing earlier.
> Once the arch supports static inline calls, it would be needed to
> evaluate to see if that gives better performance.
>
> v2->v3:
> - fixed a build error reported by linux test robot by including jump
> label header.
>
> v1->v2:
> - Instead of copying asm-generic preempt.h content include it in
> arch/asm preempt.h. (Christophe Leroy)
> - Merge the patches into one patch (Christophe Leroy)
>
> v1: https://lore.kernel.org/all/20241125042212.1522315-1-sshegde@linux.ibm.com/
> v2: https://lore.kernel.org/all/20250102191856.499424-1-sshegde@linux.ibm.com/
> [1]: https://lore.kernel.org/all/173572211264.1875638.9927288574435880962.b4-ty@linux.ibm.com/
>
> Shrikanth Hegde (1):
> powerpc: Enable dynamic preemption
>
> arch/powerpc/Kconfig | 1 +
> arch/powerpc/include/asm/preempt.h | 12 ++++++++++++
> arch/powerpc/kernel/interrupt.c | 6 +++++-
> arch/powerpc/kernel/traps.c | 6 +++++-
> arch/powerpc/lib/vmx-helper.c | 2 +-
> 5 files changed, 24 insertions(+), 3 deletions(-)
> create mode 100644 arch/powerpc/include/asm/preempt.h
>
Hi maddy, mpe, christophe.
Now that preempt=lazy is merged upstream, is would be start to enable
dynamic preemption to make use of all preemption models at runtime.
Are there any concerns with this patch?
Thanks.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 1/1] powerpc: Enable dynamic preemption
2025-01-06 5:19 ` [PATCH v3 1/1] " Shrikanth Hegde
@ 2025-01-30 14:54 ` Sebastian Andrzej Siewior
2025-01-30 15:03 ` Christophe Leroy
2025-01-30 16:57 ` Shrikanth Hegde
0 siblings, 2 replies; 10+ messages in thread
From: Sebastian Andrzej Siewior @ 2025-01-30 14:54 UTC (permalink / raw)
To: Shrikanth Hegde
Cc: mpe, maddy, linuxppc-dev, npiggin, christophe.leroy, linux-kernel
On 2025-01-06 10:49:19 [+0530], Shrikanth Hegde wrote:
> --- a/arch/powerpc/kernel/interrupt.c
> +++ b/arch/powerpc/kernel/interrupt.c
> @@ -25,6 +25,10 @@
> unsigned long global_dbcr0[NR_CPUS];
> #endif
>
> +#if defined(CONFIG_PREEMPT_DYNAMIC) && defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
> +DEFINE_STATIC_KEY_TRUE(sk_dynamic_irqentry_exit_cond_resched);
> +#endif
I am uncertain here: Do you need to DEFINE it? It is set by the sched
core which also defines it. It should be same thing after all, right?
> +
> #ifdef CONFIG_PPC_BOOK3S_64
> DEFINE_STATIC_KEY_FALSE(interrupt_exit_not_reentrant);
> static inline bool exit_must_hard_disable(void)
> @@ -396,7 +400,7 @@ notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs)
> /* Returning to a kernel context with local irqs enabled. */
> WARN_ON_ONCE(!(regs->msr & MSR_EE));
> again:
> - if (IS_ENABLED(CONFIG_PREEMPTION)) {
> + if (preempt_model_preemptible()) {
CONFIG_HAVE_PREEMPT_DYNAMIC_KEY is the only option, right? Wouldn't
| #DEFINE need_irq_preemption() \
| (static_branch_unlikely(&sk_dynamic_irqentry_exit_cond_resched))
|
| if (need_irq_preemption()) {
be a bit smaller/ quicker? This could be a fast path ;)
> /* Return to preemptible kernel context */
> if (unlikely(read_thread_flags() & _TIF_NEED_RESCHED)) {
> if (preempt_count() == 0)
> diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
> index edf5cabe5dfd..2556fa8ec019 100644
> --- a/arch/powerpc/kernel/traps.c
> +++ b/arch/powerpc/kernel/traps.c
> @@ -266,7 +266,11 @@ static int __die(const char *str, struct pt_regs *regs, long err)
> printk("%s PAGE_SIZE=%luK%s%s%s%s%s%s %s\n",
> IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN) ? "LE" : "BE",
> PAGE_SIZE / 1024, get_mmu_str(),
> - IS_ENABLED(CONFIG_PREEMPT) ? " PREEMPT" : "",
> + preempt_model_none() ? "none" :
> + preempt_model_voluntary() ? "voluntary" :
> + preempt_model_full() ? "full" :
> + preempt_model_lazy() ? "lazy" :
> + "",
So intend to rework this part. I have patches stashed at
https://git.kernel.org/pub/scm/linux/kernel/git/bigeasy/staging.git/log/?h=preemption_string
which I didn't sent yet due to the merge window. Just a heads up ;)
> IS_ENABLED(CONFIG_SMP) ? " SMP" : "",
> IS_ENABLED(CONFIG_SMP) ? (" NR_CPUS=" __stringify(NR_CPUS)) : "",
> debug_pagealloc_enabled() ? " DEBUG_PAGEALLOC" : "",
Sebastian
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 1/1] powerpc: Enable dynamic preemption
2025-01-30 14:54 ` Sebastian Andrzej Siewior
@ 2025-01-30 15:03 ` Christophe Leroy
2025-01-30 16:14 ` Sebastian Andrzej Siewior
2025-01-30 16:57 ` Shrikanth Hegde
1 sibling, 1 reply; 10+ messages in thread
From: Christophe Leroy @ 2025-01-30 15:03 UTC (permalink / raw)
To: Sebastian Andrzej Siewior, Shrikanth Hegde
Cc: mpe, maddy, linuxppc-dev, npiggin, linux-kernel
Le 30/01/2025 à 15:54, Sebastian Andrzej Siewior a écrit :
> On 2025-01-06 10:49:19 [+0530], Shrikanth Hegde wrote:
>> --- a/arch/powerpc/kernel/interrupt.c
>> +++ b/arch/powerpc/kernel/interrupt.c
>> @@ -25,6 +25,10 @@
>> unsigned long global_dbcr0[NR_CPUS];
>> #endif
>>
>> +#if defined(CONFIG_PREEMPT_DYNAMIC) && defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
>> +DEFINE_STATIC_KEY_TRUE(sk_dynamic_irqentry_exit_cond_resched);
>> +#endif
>
> I am uncertain here: Do you need to DEFINE it? It is set by the sched
> core which also defines it. It should be same thing after all, right?
As far as I can see it is not handled by sched core.
$ git grep sk_dynamic_irqentry_exit_cond_resched
arch/arm64/include/asm/preempt.h:DECLARE_STATIC_KEY_TRUE(sk_dynamic_irqentry_exit_cond_resched);
arch/arm64/kernel/entry-common.c:DEFINE_STATIC_KEY_TRUE(sk_dynamic_irqentry_exit_cond_resched);
arch/arm64/kernel/entry-common.c:
(static_branch_unlikely(&sk_dynamic_irqentry_exit_cond_resched))
include/linux/entry-common.h:DECLARE_STATIC_KEY_TRUE(sk_dynamic_irqentry_exit_cond_resched);
kernel/entry/common.c:DEFINE_STATIC_KEY_TRUE(sk_dynamic_irqentry_exit_cond_resched);
kernel/entry/common.c: if
(!static_branch_unlikely(&sk_dynamic_irqentry_exit_cond_resched))
It is in common entry but arm64 and powerpc don't use common entry.
$ git grep GENERIC_ENTRY arch
arch/Kconfig:config GENERIC_ENTRY
arch/loongarch/Kconfig: select GENERIC_ENTRY
arch/riscv/Kconfig: select GENERIC_ENTRY
arch/s390/Kconfig: select GENERIC_ENTRY
arch/x86/Kconfig: select GENERIC_ENTRY
Christophe
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 1/1] powerpc: Enable dynamic preemption
2025-01-30 15:03 ` Christophe Leroy
@ 2025-01-30 16:14 ` Sebastian Andrzej Siewior
0 siblings, 0 replies; 10+ messages in thread
From: Sebastian Andrzej Siewior @ 2025-01-30 16:14 UTC (permalink / raw)
To: Christophe Leroy
Cc: Shrikanth Hegde, mpe, maddy, linuxppc-dev, npiggin, linux-kernel
On 2025-01-30 16:03:09 [+0100], Christophe Leroy wrote:
> Le 30/01/2025 à 15:54, Sebastian Andrzej Siewior a écrit :
> > On 2025-01-06 10:49:19 [+0530], Shrikanth Hegde wrote:
> > > --- a/arch/powerpc/kernel/interrupt.c
> > > +++ b/arch/powerpc/kernel/interrupt.c
> > > @@ -25,6 +25,10 @@
> > > unsigned long global_dbcr0[NR_CPUS];
> > > #endif
> > > +#if defined(CONFIG_PREEMPT_DYNAMIC) && defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
> > > +DEFINE_STATIC_KEY_TRUE(sk_dynamic_irqentry_exit_cond_resched);
> > > +#endif
> >
> > I am uncertain here: Do you need to DEFINE it? It is set by the sched
> > core which also defines it. It should be same thing after all, right?
>
> As far as I can see it is not handled by sched core.
…
> It is in common entry but arm64 and powerpc don't use common entry.
Okay. So it is defined in the generic part (so you have to define it on
power) but it is used by sched-core (search for
preempt_dynamic_enable(irqentry_exit_cond_resched);
).
It might make sense to define it there (in the sched part where it is
used) but this is out of scope here, it just confused me :)
Thanks for the pointer.
> Christophe
Sebastian
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 1/1] powerpc: Enable dynamic preemption
2025-01-30 14:54 ` Sebastian Andrzej Siewior
2025-01-30 15:03 ` Christophe Leroy
@ 2025-01-30 16:57 ` Shrikanth Hegde
2025-01-30 20:26 ` Sebastian Andrzej Siewior
1 sibling, 1 reply; 10+ messages in thread
From: Shrikanth Hegde @ 2025-01-30 16:57 UTC (permalink / raw)
To: Sebastian Andrzej Siewior
Cc: mpe, maddy, linuxppc-dev, npiggin, christophe.leroy, linux-kernel
On 1/30/25 20:24, Sebastian Andrzej Siewior wrote:
> On 2025-01-06 10:49:19 [+0530], Shrikanth Hegde wrote:
>> --- a/arch/powerpc/kernel/interrupt.c
>
Thanks for taking a look.
>> +
>> #ifdef CONFIG_PPC_BOOK3S_64
>> DEFINE_STATIC_KEY_FALSE(interrupt_exit_not_reentrant);
>> static inline bool exit_must_hard_disable(void)
>> @@ -396,7 +400,7 @@ notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs)
>> /* Returning to a kernel context with local irqs enabled. */
>> WARN_ON_ONCE(!(regs->msr & MSR_EE));
>> again:
>> - if (IS_ENABLED(CONFIG_PREEMPTION)) {
>> + if (preempt_model_preemptible()) {
>
> CONFIG_HAVE_PREEMPT_DYNAMIC_KEY is the only option, right? Wouldn't
>
> | #DEFINE need_irq_preemption() \
> | (static_branch_unlikely(&sk_dynamic_irqentry_exit_cond_resched))
> |
> | if (need_irq_preemption()) {
>
> be a bit smaller/ quicker? This could be a fast path ;)
I am okay with either way. I did try both[1], there wasn't any significant difference,
hence chose a simpler one. May be system size, workload pattern might matter.
Let me do some more testing to see which one wins.
Is there any specific benchmark which might help here?
[1]: https://lore.kernel.org/all/b98b7795-070a-4d9c-9599-445c2ff55fd7@linux.ibm.com/
>
>> /* Return to preemptible kernel context */
>> if (unlikely(read_thread_flags() & _TIF_NEED_RESCHED)) {
>> if (preempt_count() == 0)
>> diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
>> index edf5cabe5dfd..2556fa8ec019 100644
>> --- a/arch/powerpc/kernel/traps.c
>> +++ b/arch/powerpc/kernel/traps.c
>> @@ -266,7 +266,11 @@ static int __die(const char *str, struct pt_regs *regs, long err)
>> printk("%s PAGE_SIZE=%luK%s%s%s%s%s%s %s\n",
>> IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN) ? "LE" : "BE",
>> PAGE_SIZE / 1024, get_mmu_str(),
>> - IS_ENABLED(CONFIG_PREEMPT) ? " PREEMPT" : "",
>> + preempt_model_none() ? "none" :
>> + preempt_model_voluntary() ? "voluntary" :
>> + preempt_model_full() ? "full" :
>> + preempt_model_lazy() ? "lazy" :
>> + "",
>
> So intend to rework this part. I have patches stashed at
> https://git.kernel.org/pub/scm/linux/kernel/git/bigeasy/staging.git/log/?h=preemption_string
>
> which I didn't sent yet due to the merge window. Just a heads up ;)
Makes sense. I had seen at-least two places where this code was there, ftrace/powerpc.
There were way more places..
You want me to remove this part?
>
>> IS_ENABLED(CONFIG_SMP) ? " SMP" : "",
>> IS_ENABLED(CONFIG_SMP) ? (" NR_CPUS=" __stringify(NR_CPUS)) : "",
>> debug_pagealloc_enabled() ? " DEBUG_PAGEALLOC" : "",
>
> Sebastian
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 1/1] powerpc: Enable dynamic preemption
2025-01-30 16:57 ` Shrikanth Hegde
@ 2025-01-30 20:26 ` Sebastian Andrzej Siewior
2025-01-31 6:09 ` Christophe Leroy
0 siblings, 1 reply; 10+ messages in thread
From: Sebastian Andrzej Siewior @ 2025-01-30 20:26 UTC (permalink / raw)
To: Shrikanth Hegde
Cc: mpe, maddy, linuxppc-dev, npiggin, christophe.leroy, linux-kernel
On 2025-01-30 22:27:07 [+0530], Shrikanth Hegde wrote:
> > | #DEFINE need_irq_preemption() \
> > | (static_branch_unlikely(&sk_dynamic_irqentry_exit_cond_resched))
> > |
> > | if (need_irq_preemption()) {
> >
> > be a bit smaller/ quicker? This could be a fast path ;)
>
> I am okay with either way. I did try both[1], there wasn't any significant difference,
> hence chose a simpler one. May be system size, workload pattern might matter.
>
> Let me do some more testing to see which one wins.
> Is there any specific benchmark which might help here?
No idea. As per bean counting: preempt_model_preemptible() should
resolve in two function calls + conditional in the dynamic case. This
should be more expensive compared to a nop/ branch ;)
But you would still need preempt_model_preemptible() for the !DYN case.
> > > + preempt_model_voluntary() ? "voluntary" :
> > > + preempt_model_full() ? "full" :
> > > + preempt_model_lazy() ? "lazy" :
> > > + "",
> >
> > So intend to rework this part. I have patches stashed at
> > https://git.kernel.org/pub/scm/linux/kernel/git/bigeasy/staging.git/log/?h=preemption_string
> >
> > which I didn't sent yet due to the merge window. Just a heads up ;)
>
> Makes sense. I had seen at-least two places where this code was there, ftrace/powerpc.
> There were way more places..
>
> You want me to remove this part?
No, just be aware.
I don't know how this will be routed I guess we merge the sched pieces
first and then I submit the other pieces via the relevant maintainer
tree. In that case please be aware that all parts get removed/ replaced
properly.
Sebastian
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 1/1] powerpc: Enable dynamic preemption
2025-01-30 20:26 ` Sebastian Andrzej Siewior
@ 2025-01-31 6:09 ` Christophe Leroy
2025-01-31 6:54 ` Shrikanth Hegde
0 siblings, 1 reply; 10+ messages in thread
From: Christophe Leroy @ 2025-01-31 6:09 UTC (permalink / raw)
To: Sebastian Andrzej Siewior, Shrikanth Hegde
Cc: mpe, maddy, linuxppc-dev, npiggin, linux-kernel
Le 30/01/2025 à 21:26, Sebastian Andrzej Siewior a écrit :
> On 2025-01-30 22:27:07 [+0530], Shrikanth Hegde wrote:
>>> | #DEFINE need_irq_preemption() \
>>> | (static_branch_unlikely(&sk_dynamic_irqentry_exit_cond_resched))
>>> |
>>> | if (need_irq_preemption()) {
>>>
>>> be a bit smaller/ quicker? This could be a fast path ;)
>>
>> I am okay with either way. I did try both[1], there wasn't any significant difference,
>> hence chose a simpler one. May be system size, workload pattern might matter.
>>
>> Let me do some more testing to see which one wins.
>> Is there any specific benchmark which might help here?
>
> No idea. As per bean counting: preempt_model_preemptible() should
> resolve in two function calls + conditional in the dynamic case. This
> should be more expensive compared to a nop/ branch ;)
I did a build comparison on pmac32_defconfig + dynamic preemption, the
static branch looks definitely more optimal:
Without static branch:
...
294: 7c 08 02 a6 mflr r0
298: 90 01 00 24 stw r0,36(r1)
29c: 48 00 00 01 bl 29c <interrupt_exit_kernel_prepare+0x50>
29c: R_PPC_REL24 preempt_model_full
2a0: 2c 03 00 00 cmpwi r3,0
2a4: 41 82 00 a4 beq 348 <interrupt_exit_kernel_prepare+0xfc>
...
2a8: 81 22 00 4c lwz r9,76(r2)
2ac: 71 29 00 04 andi. r9,r9,4
2b0: 40 82 00 d4 bne 384 <interrupt_exit_kernel_prepare+0x138>
...
2b4: 7d 20 00 a6 mfmsr r9
2b8: 55 29 07 fa rlwinm r9,r9,0,31,29
...
348: 48 00 00 01 bl 348 <interrupt_exit_kernel_prepare+0xfc>
348: R_PPC_REL24 preempt_model_lazy
34c: 2c 03 00 00 cmpwi r3,0
350: 40 a2 ff 58 bne 2a8 <interrupt_exit_kernel_prepare+0x5c>
354: 4b ff ff 60 b 2b4 <interrupt_exit_kernel_prepare+0x68>
With the static branch:
...
294: 48 00 00 58 b 2ec <interrupt_exit_kernel_prepare+0xa0>
...
298: 7d 20 00 a6 mfmsr r9
29c: 55 29 07 fa rlwinm r9,r9,0,31,29
...
2ec: 81 22 00 4c lwz r9,76(r2)
2f0: 71 29 00 04 andi. r9,r9,4
2f4: 41 82 ff a4 beq 298 <interrupt_exit_kernel_prepare+0x4c>
...
With the static branch it is just an unconditional branch being later
replaced by a NOP. It must be more efficient.
So in first case we need to get and save LR, call preempt_model_full(),
compare with 0, call preempt_model_lazy() and compare again, and at some
point read and restore LR.
And the preempt_model_() functions are not tiny functions:
00003620 <preempt_model_full>:
3620: 3d 20 00 00 lis r9,0
3622: R_PPC_ADDR16_HA preempt_dynamic_mode
3624: 94 21 ff f0 stwu r1,-16(r1)
3628: 80 69 00 00 lwz r3,0(r9)
362a: R_PPC_ADDR16_LO preempt_dynamic_mode
362c: 2c 03 ff ff cmpwi r3,-1
3630: 41 82 00 18 beq 3648 <preempt_model_full+0x28>
3634: 68 63 00 02 xori r3,r3,2
3638: 38 21 00 10 addi r1,r1,16
363c: 7c 63 00 34 cntlzw r3,r3
3640: 54 63 d9 7e srwi r3,r3,5
3644: 4e 80 00 20 blr
...
3648: 0f e0 00 00 twui r0,0
364c: 68 63 00 02 xori r3,r3,2
3650: 38 21 00 10 addi r1,r1,16
3654: 7c 63 00 34 cntlzw r3,r3
3658: 54 63 d9 7e srwi r3,r3,5
365c: 4e 80 00 20 blr
00003660 <preempt_model_lazy>:
3660: 3d 20 00 00 lis r9,0
3662: R_PPC_ADDR16_HA preempt_dynamic_mode
3664: 94 21 ff f0 stwu r1,-16(r1)
3668: 80 69 00 00 lwz r3,0(r9)
366a: R_PPC_ADDR16_LO preempt_dynamic_mode
366c: 2c 03 ff ff cmpwi r3,-1
3670: 41 82 00 18 beq 3688 <preempt_model_lazy+0x28>
3674: 68 63 00 03 xori r3,r3,3
3678: 38 21 00 10 addi r1,r1,16
367c: 7c 63 00 34 cntlzw r3,r3
3680: 54 63 d9 7e srwi r3,r3,5
3684: 4e 80 00 20 blr
...
3688: 0f e0 00 00 twui r0,0
368c: 68 63 00 03 xori r3,r3,3
3690: 38 21 00 10 addi r1,r1,16
3694: 7c 63 00 34 cntlzw r3,r3
3698: 54 63 d9 7e srwi r3,r3,5
369c: 4e 80 00 20 blr
> But you would still need preempt_model_preemptible() for the !DYN case.
>
>>>> + preempt_model_voluntary() ? "voluntary" :
>>>> + preempt_model_full() ? "full" :
>>>> + preempt_model_lazy() ? "lazy" :
>>>> + "",
>>>
>>> So intend to rework this part. I have patches stashed at
>>> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit.kernel.org%2Fpub%2Fscm%2Flinux%2Fkernel%2Fgit%2Fbigeasy%2Fstaging.git%2Flog%2F%3Fh%3Dpreemption_string&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C553a8f640a9c4514597d08dd416c6534%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C638738655988556429%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=ZfVQi1iRYaVCTrZ5vIhOQ7yAKaDnOwFi0NRjycfrI5A%3D&reserved=0
>>>
>>> which I didn't sent yet due to the merge window. Just a heads up ;)
>>
>> Makes sense. I had seen at-least two places where this code was there, ftrace/powerpc.
>> There were way more places..
>>
>> You want me to remove this part?
>
> No, just be aware.
> I don't know how this will be routed I guess we merge the sched pieces
> first and then I submit the other pieces via the relevant maintainer
> tree. In that case please be aware that all parts get removed/ replaced
> properly.
>
> Sebastian
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 1/1] powerpc: Enable dynamic preemption
2025-01-31 6:09 ` Christophe Leroy
@ 2025-01-31 6:54 ` Shrikanth Hegde
0 siblings, 0 replies; 10+ messages in thread
From: Shrikanth Hegde @ 2025-01-31 6:54 UTC (permalink / raw)
To: Christophe Leroy, Sebastian Andrzej Siewior
Cc: mpe, maddy, linuxppc-dev, npiggin, linux-kernel
On 1/31/25 11:39, Christophe Leroy wrote:
>
>
> Le 30/01/2025 à 21:26, Sebastian Andrzej Siewior a écrit :
>> On 2025-01-30 22:27:07 [+0530], Shrikanth Hegde wrote:
>>>> | #DEFINE need_irq_preemption() \
>>>> |
>>>> (static_branch_unlikely(&sk_dynamic_irqentry_exit_cond_resched))
>>>> |
>>>> | if (need_irq_preemption()) {
>>>>
>>>> be a bit smaller/ quicker? This could be a fast path ;)
>>>
>>> I am okay with either way. I did try both[1], there wasn't any
>>> significant difference,
>>> hence chose a simpler one. May be system size, workload pattern might
>>> matter.
>>>
>>> Let me do some more testing to see which one wins.
>>> Is there any specific benchmark which might help here?
>>
>> No idea. As per bean counting: preempt_model_preemptible() should
>> resolve in two function calls + conditional in the dynamic case. This
>> should be more expensive compared to a nop/ branch ;)
>
> I did a build comparison on pmac32_defconfig + dynamic preemption, the
> static branch looks definitely more optimal:
>
> Without static branch:
>
> ...
> 294: 7c 08 02 a6 mflr r0
> 298: 90 01 00 24 stw r0,36(r1)
> 29c: 48 00 00 01 bl 29c <interrupt_exit_kernel_prepare+0x50>
> 29c: R_PPC_REL24 preempt_model_full
> 2a0: 2c 03 00 00 cmpwi r3,0
> 2a4: 41 82 00 a4 beq 348 <interrupt_exit_kernel_prepare+0xfc>
> ...
> 2a8: 81 22 00 4c lwz r9,76(r2)
> 2ac: 71 29 00 04 andi. r9,r9,4
> 2b0: 40 82 00 d4 bne 384 <interrupt_exit_kernel_prepare+0x138>
> ...
> 2b4: 7d 20 00 a6 mfmsr r9
> 2b8: 55 29 07 fa rlwinm r9,r9,0,31,29
> ...
> 348: 48 00 00 01 bl 348 <interrupt_exit_kernel_prepare+0xfc>
> 348: R_PPC_REL24 preempt_model_lazy
> 34c: 2c 03 00 00 cmpwi r3,0
> 350: 40 a2 ff 58 bne 2a8 <interrupt_exit_kernel_prepare+0x5c>
> 354: 4b ff ff 60 b 2b4 <interrupt_exit_kernel_prepare+0x68>
>
> With the static branch:
>
> ...
> 294: 48 00 00 58 b 2ec <interrupt_exit_kernel_prepare+0xa0>
> ...
> 298: 7d 20 00 a6 mfmsr r9
> 29c: 55 29 07 fa rlwinm r9,r9,0,31,29
> ...
> 2ec: 81 22 00 4c lwz r9,76(r2)
> 2f0: 71 29 00 04 andi. r9,r9,4
> 2f4: 41 82 ff a4 beq 298 <interrupt_exit_kernel_prepare+0x4c>
> ...
>
> With the static branch it is just an unconditional branch being later
> replaced by a NOP. It must be more efficient.
>
> So in first case we need to get and save LR, call preempt_model_full(),
> compare with 0, call preempt_model_lazy() and compare again, and at some
> point read and restore LR.
>
> And the preempt_model_() functions are not tiny functions:
>
> 00003620 <preempt_model_full>:
> 3620: 3d 20 00 00 lis r9,0
> 3622: R_PPC_ADDR16_HA preempt_dynamic_mode
> 3624: 94 21 ff f0 stwu r1,-16(r1)
> 3628: 80 69 00 00 lwz r3,0(r9)
> 362a: R_PPC_ADDR16_LO preempt_dynamic_mode
> 362c: 2c 03 ff ff cmpwi r3,-1
> 3630: 41 82 00 18 beq 3648 <preempt_model_full+0x28>
> 3634: 68 63 00 02 xori r3,r3,2
> 3638: 38 21 00 10 addi r1,r1,16
> 363c: 7c 63 00 34 cntlzw r3,r3
> 3640: 54 63 d9 7e srwi r3,r3,5
> 3644: 4e 80 00 20 blr
> ...
> 3648: 0f e0 00 00 twui r0,0
> 364c: 68 63 00 02 xori r3,r3,2
> 3650: 38 21 00 10 addi r1,r1,16
> 3654: 7c 63 00 34 cntlzw r3,r3
> 3658: 54 63 d9 7e srwi r3,r3,5
> 365c: 4e 80 00 20 blr
>
> 00003660 <preempt_model_lazy>:
> 3660: 3d 20 00 00 lis r9,0
> 3662: R_PPC_ADDR16_HA preempt_dynamic_mode
> 3664: 94 21 ff f0 stwu r1,-16(r1)
> 3668: 80 69 00 00 lwz r3,0(r9)
> 366a: R_PPC_ADDR16_LO preempt_dynamic_mode
> 366c: 2c 03 ff ff cmpwi r3,-1
> 3670: 41 82 00 18 beq 3688 <preempt_model_lazy+0x28>
> 3674: 68 63 00 03 xori r3,r3,3
> 3678: 38 21 00 10 addi r1,r1,16
> 367c: 7c 63 00 34 cntlzw r3,r3
> 3680: 54 63 d9 7e srwi r3,r3,5
> 3684: 4e 80 00 20 blr
> ...
> 3688: 0f e0 00 00 twui r0,0
> 368c: 68 63 00 03 xori r3,r3,3
> 3690: 38 21 00 10 addi r1,r1,16
> 3694: 7c 63 00 34 cntlzw r3,r3
> 3698: 54 63 d9 7e srwi r3,r3,5
> 369c: 4e 80 00 20 blr
>
>
>
That's convincing. Thanks for the pointers. I will move it into static
branch method.
That makes the code same for arm64/powerpc. Maybe its worth moving it
into sched/core. Let me try that as well.
PS: on leave next week, so will be sending the patches after i get back.
>> But you would still need preempt_model_preemptible() for the !DYN case.
>>
>>>>> + preempt_model_voluntary() ? "voluntary" :
>>>>> + preempt_model_full() ? "full" :
>>>>> + preempt_model_lazy() ? "lazy" :
>>>>> + "",
>>>>
>>>> So intend to rework this part. I have patches stashed at
>>>> https://eur01.safelinks.protection.outlook.com/?
>>>> url=https%3A%2F%2Fgit.kernel.org%2Fpub%2Fscm%2Flinux%2Fkernel%2Fgit%2Fbigeasy%2Fstaging.git%2Flog%2F%3Fh%3Dpreemption_string&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C553a8f640a9c4514597d08dd416c6534%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C638738655988556429%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=ZfVQi1iRYaVCTrZ5vIhOQ7yAKaDnOwFi0NRjycfrI5A%3D&reserved=0
>>>>
>>>> which I didn't sent yet due to the merge window. Just a heads up ;)
>>>
>>> Makes sense. I had seen at-least two places where this code was
>>> there, ftrace/powerpc.
>>> There were way more places..
>>>
>>> You want me to remove this part?
>>
>> No, just be aware.
>> I don't know how this will be routed I guess we merge the sched pieces
>> first and then I submit the other pieces via the relevant maintainer
>> tree. In that case please be aware that all parts get removed/ replaced
>> properly.
>>
>> Sebastian
>
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2025-01-31 6:54 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-01-06 5:19 [PATCH v3 0/1] powerpc: Enable dynamic preemption Shrikanth Hegde
2025-01-06 5:19 ` [PATCH v3 1/1] " Shrikanth Hegde
2025-01-30 14:54 ` Sebastian Andrzej Siewior
2025-01-30 15:03 ` Christophe Leroy
2025-01-30 16:14 ` Sebastian Andrzej Siewior
2025-01-30 16:57 ` Shrikanth Hegde
2025-01-30 20:26 ` Sebastian Andrzej Siewior
2025-01-31 6:09 ` Christophe Leroy
2025-01-31 6:54 ` Shrikanth Hegde
2025-01-21 7:25 ` [PATCH v3 0/1] " Shrikanth Hegde
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).