On Fri, Aug 07, 2020 at 12:16:35PM -0700, Sultan Alsawaf wrote:
> From: Sultan Alsawaf <[email protected]>
> 
> There's no reason to hold an RCU read lock the entire time while
> optimistically spinning for a mutex lock. This can needlessly lengthen
> RCU grace periods and slow down synchronize_rcu() when it doesn't brute
> force the RCU grace period via rcupdate.rcu_expedited=1.

Would be good to demonstrate this with numbers if you can.

> Signed-off-by: Sultan Alsawaf <[email protected]>
> ---
>  kernel/locking/mutex.c | 25 +++++++++++++++++--------
>  1 file changed, 17 insertions(+), 8 deletions(-)
> 
> diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c
> index 5352ce50a97e..cc5676712458 100644
> --- a/kernel/locking/mutex.c
> +++ b/kernel/locking/mutex.c
> @@ -552,21 +552,31 @@ bool mutex_spin_on_owner(struct mutex *lock, struct 
> task_struct *owner,
>  {
>       bool ret = true;
>  
> -     rcu_read_lock();
> -     while (__mutex_owner(lock) == owner) {
> +     for (;;) {
> +             unsigned int cpu;
> +             bool same_owner;
> +
>               /*
> -              * Ensure we emit the owner->on_cpu, dereference _after_
> -              * checking lock->owner still matches owner. If that fails,
> +              * Ensure lock->owner still matches owner. If that fails,
>                * owner might point to freed memory. If it still matches,
>                * the rcu_read_lock() ensures the memory stays valid.
>                */
> -             barrier();
> +             rcu_read_lock();
> +             same_owner = __mutex_owner(lock) == owner;
> +             if (same_owner) {
> +                     ret = owner->on_cpu;
> +                     if (ret)
> +                             cpu = task_cpu(owner);
> +             }
> +             rcu_read_unlock();

Are you sure this doesn't break the ww mutex spinning? That thing also goes
and looks at the owner, but now it's called outside of the read-side
critical section.

Will

Reply via email to