* [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 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
* 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
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).