Re: [PATCH 3/3] locking/percpu-rwsem: Avoid unnecessary writer wakeups

From: Oleg Nesterov
Date: Mon Nov 21 2016 - 10:07:32 EST


On 11/21, Oleg Nesterov wrote:
>
> No, no, I meant that afaics both readers can see per_cpu_sum() != 0 and
> thus the writer won't be woken up. Till the next down_read/up_read.
>
> Suppose that we have 2 CPU's, both counters == 1, both readers decrement.
> its counter at the same time.
>
> READER_ON_CPU_0 READER_ON_CPU_1
>
> --ctr_0; --ctr_1;
>
> if (ctr_0 + ctr_1) if (ctr_0 + ctr_1)
> wakeup(); wakeup();
>
> Why we can't miss a wakeup?
>
> This patch doesn't even add a barrier, but I think wmb() won't be enough
> anyway.

And in fact I am not sure this optimization makes sense... But it would be
nice to avoid wake_up() when the writer sleeps in rcu_sync_enter(). Or this
is the "slow mode" sem (cgroup_threadgroup_rwsem).

I need to re-check, but what do you think about the change below?

Oleg.

--- x/kernel/locking/percpu-rwsem.c
+++ x/kernel/locking/percpu-rwsem.c
@@ -103,7 +103,9 @@ void __percpu_up_read(struct percpu_rw_s
__this_cpu_dec(*sem->read_count);

/* Prod writer to recheck readers_active */
- wake_up(&sem->writer);
+ smp_mb();
+ if (sem->readers_block)
+ wake_up(&sem->writer);
}
EXPORT_SYMBOL_GPL(__percpu_up_read);