From: Mark Rutland <mark.rutland@arm.com>
To: Frederic Weisbecker <frederic@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org, ardb@kernel.org,
catalin.marinas@arm.com, juri.lelli@redhat.com,
linux-kernel@vger.kernel.org, mingo@redhat.com,
peterz@infradead.org, will@kernel.org
Subject: Re: [PATCH 5/6] sched/preempt: add PREEMPT_DYNAMIC using static keys
Date: Thu, 3 Feb 2022 09:51:46 +0000 [thread overview]
Message-ID: <YfulsiWkphburRNX@FVFF77S0Q05N> (raw)
In-Reply-To: <20220202232145.GA461279@lothringen>
On Thu, Feb 03, 2022 at 12:21:45AM +0100, Frederic Weisbecker wrote:
> On Tue, Nov 09, 2021 at 05:24:07PM +0000, Mark Rutland wrote:
> > diff --git a/include/linux/kernel.h b/include/linux/kernel.h
> > index e5359b09de1d..8a94ccfc7dc8 100644
> > --- a/include/linux/kernel.h
> > +++ b/include/linux/kernel.h
> > @@ -93,7 +93,7 @@ struct user;
> > extern int __cond_resched(void);
> > # define might_resched() __cond_resched()
> >
> > -#elif defined(CONFIG_PREEMPT_DYNAMIC)
> > +#elif defined(CONFIG_PREEMPT_DYNAMIC) && defined(CONFIG_HAVE_PREEMPT_DYNAMIC_CALL)
> >
> > extern int __cond_resched(void);
> >
> > @@ -104,6 +104,11 @@ static __always_inline void might_resched(void)
> > static_call_mod(might_resched)();
> > }
> >
> > +#elif defined(CONFIG_PREEMPT_DYNAMIC) && defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
> > +
> > +extern int dynamic_might_resched(void);
> > +# define might_resched() dynamic_might_resched()
> > +
> > #else
> >
> > # define might_resched() do { } while (0)
> > diff --git a/include/linux/sched.h b/include/linux/sched.h
> > index 78c351e35fec..7710b6593c72 100644
> > --- a/include/linux/sched.h
> > +++ b/include/linux/sched.h
> > @@ -2008,7 +2008,7 @@ static inline int test_tsk_need_resched(struct task_struct *tsk)
> > #if !defined(CONFIG_PREEMPTION) || defined(CONFIG_PREEMPT_DYNAMIC)
> > extern int __cond_resched(void);
> >
> > -#ifdef CONFIG_PREEMPT_DYNAMIC
> > +#if defined(CONFIG_PREEMPT_DYNAMIC) && defined(CONFIG_HAVE_PREEMPT_DYNAMIC_CALL)
> >
> > DECLARE_STATIC_CALL(cond_resched, __cond_resched);
> >
> > @@ -2017,6 +2017,14 @@ static __always_inline int _cond_resched(void)
> > return static_call_mod(cond_resched)();
> > }
> >
> > +#elif defined(CONFIG_PREEMPT_DYNAMIC) && defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
> > +extern int dynamic_cond_resched(void);
> > +
> > +static __always_inline int _cond_resched(void)
> > +{
> > + return dynamic_cond_resched();
>
> So in the end this is creating an indirect call for every preemption entrypoint.
Huh? "indirect call" usually means a branch to a function pointer, and I don't
think that's what you mean here. Do you just mean that we add a (direct)
call+return?
This gets inlined, and will be just a direct call to dynamic_cond_resched().
e,g. on arm64 this will be a single instruction:
bl dynamic_cond_resched
... and (as the commit message desribes) then the implementation of
dynamic_cond_resched will be the same as the regular __cond_resched *but* the
static key trampoline is inlined at the start, e.g.
| <dynamic_cond_resched>:
| bti c
| b <dynamic_cond_resched+0x10>
| mov w0, #0x0 // #0
| ret
| mrs x0, sp_el0
| ldr x0, [x0, #8]
| cbnz x0, <dynamic_cond_resched+0x8>
| paciasp
| stp x29, x30, [sp, #-16]!
| mov x29, sp
| bl <preempt_schedule_common>
| mov w0, #0x1 // #1
| ldp x29, x30, [sp], #16
| autiasp
| ret
... compared to the regular form of the function:
| <__cond_resched>:
| bti c
| mrs x0, sp_el0
| ldr x1, [x0, #8]
| cbz x1, <__cond_resched+0x18>
| mov w0, #0x0 // #0
| ret
| paciasp
| stp x29, x30, [sp, #-16]!
| mov x29, sp
| bl <preempt_schedule_common>
| mov w0, #0x1 // #1
| ldp x29, x30, [sp], #16
| autiasp
| ret
> It seems to me that this loses the whole point of using static keys.
As above, I don't think that's the case. Relative to static keys using
trampolines (which is all arm64 can implement), the gain is that we inline the
trampoline into the *callee*. That saves on I-cache footprint, the compiler can
generate the early returns more optimally (and compatibly with an CFI scheme we
wish to use), and we don't have to maintain a separate patching mechanism.
If you think that static call trampolines lose the whole point of static keys
then we've lost to begin with, since that's all we can reasonably implement.
> Is there something that prevents from using inlines or macros?
Inlining of *what* ?
Thanks,
Mark.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
WARNING: multiple messages have this Message-ID (diff)
From: Mark Rutland <mark.rutland@arm.com>
To: Frederic Weisbecker <frederic@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org, ardb@kernel.org,
catalin.marinas@arm.com, juri.lelli@redhat.com,
linux-kernel@vger.kernel.org, mingo@redhat.com,
peterz@infradead.org, will@kernel.org
Subject: Re: [PATCH 5/6] sched/preempt: add PREEMPT_DYNAMIC using static keys
Date: Thu, 3 Feb 2022 09:51:46 +0000 [thread overview]
Message-ID: <YfulsiWkphburRNX@FVFF77S0Q05N> (raw)
In-Reply-To: <20220202232145.GA461279@lothringen>
On Thu, Feb 03, 2022 at 12:21:45AM +0100, Frederic Weisbecker wrote:
> On Tue, Nov 09, 2021 at 05:24:07PM +0000, Mark Rutland wrote:
> > diff --git a/include/linux/kernel.h b/include/linux/kernel.h
> > index e5359b09de1d..8a94ccfc7dc8 100644
> > --- a/include/linux/kernel.h
> > +++ b/include/linux/kernel.h
> > @@ -93,7 +93,7 @@ struct user;
> > extern int __cond_resched(void);
> > # define might_resched() __cond_resched()
> >
> > -#elif defined(CONFIG_PREEMPT_DYNAMIC)
> > +#elif defined(CONFIG_PREEMPT_DYNAMIC) && defined(CONFIG_HAVE_PREEMPT_DYNAMIC_CALL)
> >
> > extern int __cond_resched(void);
> >
> > @@ -104,6 +104,11 @@ static __always_inline void might_resched(void)
> > static_call_mod(might_resched)();
> > }
> >
> > +#elif defined(CONFIG_PREEMPT_DYNAMIC) && defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
> > +
> > +extern int dynamic_might_resched(void);
> > +# define might_resched() dynamic_might_resched()
> > +
> > #else
> >
> > # define might_resched() do { } while (0)
> > diff --git a/include/linux/sched.h b/include/linux/sched.h
> > index 78c351e35fec..7710b6593c72 100644
> > --- a/include/linux/sched.h
> > +++ b/include/linux/sched.h
> > @@ -2008,7 +2008,7 @@ static inline int test_tsk_need_resched(struct task_struct *tsk)
> > #if !defined(CONFIG_PREEMPTION) || defined(CONFIG_PREEMPT_DYNAMIC)
> > extern int __cond_resched(void);
> >
> > -#ifdef CONFIG_PREEMPT_DYNAMIC
> > +#if defined(CONFIG_PREEMPT_DYNAMIC) && defined(CONFIG_HAVE_PREEMPT_DYNAMIC_CALL)
> >
> > DECLARE_STATIC_CALL(cond_resched, __cond_resched);
> >
> > @@ -2017,6 +2017,14 @@ static __always_inline int _cond_resched(void)
> > return static_call_mod(cond_resched)();
> > }
> >
> > +#elif defined(CONFIG_PREEMPT_DYNAMIC) && defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
> > +extern int dynamic_cond_resched(void);
> > +
> > +static __always_inline int _cond_resched(void)
> > +{
> > + return dynamic_cond_resched();
>
> So in the end this is creating an indirect call for every preemption entrypoint.
Huh? "indirect call" usually means a branch to a function pointer, and I don't
think that's what you mean here. Do you just mean that we add a (direct)
call+return?
This gets inlined, and will be just a direct call to dynamic_cond_resched().
e,g. on arm64 this will be a single instruction:
bl dynamic_cond_resched
... and (as the commit message desribes) then the implementation of
dynamic_cond_resched will be the same as the regular __cond_resched *but* the
static key trampoline is inlined at the start, e.g.
| <dynamic_cond_resched>:
| bti c
| b <dynamic_cond_resched+0x10>
| mov w0, #0x0 // #0
| ret
| mrs x0, sp_el0
| ldr x0, [x0, #8]
| cbnz x0, <dynamic_cond_resched+0x8>
| paciasp
| stp x29, x30, [sp, #-16]!
| mov x29, sp
| bl <preempt_schedule_common>
| mov w0, #0x1 // #1
| ldp x29, x30, [sp], #16
| autiasp
| ret
... compared to the regular form of the function:
| <__cond_resched>:
| bti c
| mrs x0, sp_el0
| ldr x1, [x0, #8]
| cbz x1, <__cond_resched+0x18>
| mov w0, #0x0 // #0
| ret
| paciasp
| stp x29, x30, [sp, #-16]!
| mov x29, sp
| bl <preempt_schedule_common>
| mov w0, #0x1 // #1
| ldp x29, x30, [sp], #16
| autiasp
| ret
> It seems to me that this loses the whole point of using static keys.
As above, I don't think that's the case. Relative to static keys using
trampolines (which is all arm64 can implement), the gain is that we inline the
trampoline into the *callee*. That saves on I-cache footprint, the compiler can
generate the early returns more optimally (and compatibly with an CFI scheme we
wish to use), and we don't have to maintain a separate patching mechanism.
If you think that static call trampolines lose the whole point of static keys
then we've lost to begin with, since that's all we can reasonably implement.
> Is there something that prevents from using inlines or macros?
Inlining of *what* ?
Thanks,
Mark.
next prev parent reply other threads:[~2022-02-03 10:10 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-11-09 17:24 [PATCH 0/6] arm64 / sched/preempt: support PREEMPT_DYNAMIC with static keys Mark Rutland
2021-11-09 17:24 ` Mark Rutland
2021-11-09 17:24 ` [PATCH 1/6] sched/preempt: move PREEMPT_DYNAMIC logic later Mark Rutland
2021-11-09 17:24 ` Mark Rutland
2021-11-09 17:24 ` [PATCH 2/6] sched/preempt: refactor sched_dynamic_update() Mark Rutland
2021-11-09 17:24 ` Mark Rutland
2021-12-10 15:13 ` Frederic Weisbecker
2021-12-10 15:13 ` Frederic Weisbecker
2022-02-02 15:13 ` Mark Rutland
2022-02-02 15:13 ` Mark Rutland
2022-02-02 16:01 ` Frederic Weisbecker
2022-02-02 16:01 ` Frederic Weisbecker
2022-02-02 18:08 ` Mark Rutland
2022-02-02 18:08 ` Mark Rutland
2022-02-03 11:52 ` Frederic Weisbecker
2022-02-03 11:52 ` Frederic Weisbecker
2021-11-09 17:24 ` [PATCH 3/6] sched/preempt: simplify irqentry_exit_cond_resched() callers Mark Rutland
2021-11-09 17:24 ` Mark Rutland
2021-11-09 17:24 ` [PATCH 4/6] sched/preempt: decouple HAVE_PREEMPT_DYNAMIC from GENERIC_ENTRY Mark Rutland
2021-11-09 17:24 ` Mark Rutland
2021-11-09 17:24 ` [PATCH 5/6] sched/preempt: add PREEMPT_DYNAMIC using static keys Mark Rutland
2021-11-09 17:24 ` Mark Rutland
2021-12-13 22:05 ` Frederic Weisbecker
2021-12-13 22:05 ` Frederic Weisbecker
2022-02-02 15:29 ` Mark Rutland
2022-02-02 15:29 ` Mark Rutland
2022-02-03 22:40 ` Peter Zijlstra
2022-02-03 22:40 ` Peter Zijlstra
2022-02-02 23:21 ` Frederic Weisbecker
2022-02-02 23:21 ` Frederic Weisbecker
2022-02-03 9:51 ` Mark Rutland [this message]
2022-02-03 9:51 ` Mark Rutland
2022-02-03 11:34 ` Frederic Weisbecker
2022-02-03 11:34 ` Frederic Weisbecker
2022-02-03 12:27 ` Mark Rutland
2022-02-03 12:27 ` Mark Rutland
2021-11-09 17:24 ` [PATCH 6/6] arm64: support PREEMPT_DYNAMIC Mark Rutland
2021-11-09 17:24 ` Mark Rutland
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=YfulsiWkphburRNX@FVFF77S0Q05N \
--to=mark.rutland@arm.com \
--cc=ardb@kernel.org \
--cc=catalin.marinas@arm.com \
--cc=frederic@kernel.org \
--cc=juri.lelli@redhat.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=will@kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.