[PATCH 16/17] powerpc/qspinlock: allow indefinite spinning on a preempted owner
Nicholas Piggin
npiggin at gmail.com
Thu Nov 10 22:38:02 AEDT 2022
On Thu Nov 10, 2022 at 10:44 AM AEST, Jordan Niethe wrote:
> On Thu, 2022-07-28 at 16:31 +1000, Nicholas Piggin wrote:
> [resend as utf-8, not utf-7]
> > Provide an option that holds off queueing indefinitely while the lock
> > owner is preempted. This could reduce queueing latencies for very
> > overcommitted vcpu situations.
> >
> > This is disabled by default.
> > ---
> > arch/powerpc/lib/qspinlock.c | 91 +++++++++++++++++++++++++++++++-----
> > 1 file changed, 79 insertions(+), 12 deletions(-)
> >
> > diff --git a/arch/powerpc/lib/qspinlock.c b/arch/powerpc/lib/qspinlock.c
> > index 24f68bd71e2b..5cfd69931e31 100644
> > --- a/arch/powerpc/lib/qspinlock.c
> > +++ b/arch/powerpc/lib/qspinlock.c
> > @@ -35,6 +35,7 @@ static int HEAD_SPINS __read_mostly = (1<<8);
> >
> > static bool pv_yield_owner __read_mostly = true;
> > static bool pv_yield_allow_steal __read_mostly = false;
> > +static bool pv_spin_on_preempted_owner __read_mostly = false;
> > static bool pv_yield_prev __read_mostly = true;
> > static bool pv_yield_propagate_owner __read_mostly = true;
> > static bool pv_prod_head __read_mostly = false;
> > @@ -220,13 +221,15 @@ static struct qnode *get_tail_qnode(struct qspinlock *lock, u32 val)
> > BUG();
> > }
> >
> > -static __always_inline void __yield_to_locked_owner(struct qspinlock *lock, u32 val, bool paravirt, bool clear_mustq)
> > +static __always_inline void __yield_to_locked_owner(struct qspinlock *lock, u32 val, bool paravirt, bool clear_mustq, bool *preempted)
> > {
> > int owner;
> > u32 yield_count;
> >
> > BUG_ON(!(val & _Q_LOCKED_VAL));
> >
> > + *preempted = false;
> > +
> > if (!paravirt)
> > goto relax;
> >
> > @@ -241,6 +244,8 @@ static __always_inline void __yield_to_locked_owner(struct qspinlock *lock, u32
> >
> > spin_end();
> >
> > + *preempted = true;
> > +
> > /*
> > * Read the lock word after sampling the yield count. On the other side
> > * there may a wmb because the yield count update is done by the
> > @@ -265,14 +270,14 @@ static __always_inline void __yield_to_locked_owner(struct qspinlock *lock, u32
> > spin_cpu_relax();
> > }
> >
> > -static __always_inline void yield_to_locked_owner(struct qspinlock *lock, u32 val, bool paravirt)
> > +static __always_inline void yield_to_locked_owner(struct qspinlock *lock, u32 val, bool paravirt, bool *preempted)
>
> It seems like preempted parameter could be the return value of
> yield_to_locked_owner(). Then callers that don't use the value returned in
> preempted don't need to create an unnecessary variable to pass in.
That works.
Thanks,
Nick
More information about the Linuxppc-dev
mailing list