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