From: Oleg Nesterov <oleg@redhat.com>
To: Peter Zijlstra <peterz@infradead.org>
Cc: Paul McKenney <paulmck@linux.vnet.ibm.com>,
Mel Gorman <mgorman@suse.de>, Rik van Riel <riel@redhat.com>,
Srikar Dronamraju <srikar@linux.vnet.ibm.com>,
Ingo Molnar <mingo@kernel.org>,
Andrea Arcangeli <aarcange@redhat.com>,
Johannes Weiner <hannes@cmpxchg.org>,
Thomas Gleixner <tglx@linutronix.de>,
Steven Rostedt <rostedt@goodmis.org>,
Linus Torvalds <torvalds@linux-foundation.org>,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH 4/5] rcusync: introduce rcu_sync_struct->exclusive mode
Date: Sun, 6 Oct 2013 15:22:40 +0200 [thread overview]
Message-ID: <20131006132240.GA21357@redhat.com> (raw)
In-Reply-To: <20131004204159.GT3081@twins.programming.kicks-ass.net>
On 10/04, Peter Zijlstra wrote:
>
> On Fri, Oct 04, 2013 at 09:56:23PM +0200, Oleg Nesterov wrote:
>
> But yes, slightly more complex code :/
Yes. rcu_sync_busy() adds more obscurity and we need to implement
the logic which wait_for_completion already does.
> That would yield something like so I suppose:
>
> void rcu_sync_enter(struct rcu_sync_struct *rss)
> {
> bool need_wait, need_sync;
>
> spin_lock_irq(&rss->rss_lock);
> if (rss->exclusive && rss->gp_count) {
> __wait_event_locked(rss->gp_wait, rss->gp_count);
^^^^^^^^^^^^^
I guess you meant !rss->gp_count.
> rss->gp_count++;
> need_wait = need_sync = false;
> } else {
> need_wait = rss->gp_count++;
> need_sync = rss->gp_state == GP_IDLE;
> if (need_sync)
> rss->gp_state = GP_PENDING;
> }
> spin_unlock_irq(&rss->lock);
>
> if (need_sync) {
> rss->sync();
> rss->gp_state = GP_PASSED;
> wake_up_all(&rss->gp_wait);
> } else if (need_wait) {
> wait_event(rss->gp_wait, rss->gp_state == GP_PASSED);
> } else {
> BUG_ON(rss->gp_state != GP_PASSED);
> }
> }
I am obviously biased, but imho the code looks worse this way.
I like the current simple "need_wait" and "gp_count != 0" logic.
And afaics this is racy,
> static bool rcu_sync_busy(struct rcu_sync_struct *rss)
> {
> return rss->gp_count ||
> (rss->exclusive && waitqueue_active(&rss->gp_wait));
> }
>
> static void rcu_sync_func(struct rcu_head *rcu)
> {
> struct rcu_sync_struct *rss =
> container_of(rcu, struct rcu_sync_struct, cb_head);
> unsigned long flags;
>
> BUG_ON(rss->gp_state != GP_PASSED);
> BUG_ON(rss->cb_state == CB_IDLE);
>
> spin_lock_irqsave(&rss->rss_lock, flags);
> if (rcu_sync_busy(rss)) {
> /*
> * A new rcu_sync_begin() has happened; drop the callback.
> */
> rss->cb_state = CB_IDLE;
Yes, but if rcu_sync_exit() does __wake_up_locked(), then
autoremove_wake_function() makes waitqueue_active() == F. If the pending
rcu_sync_func() takes ->rss_lock first we have a problem.
Easy to fix, but needs more complications.
Or we can simply ignore the fact that rcu_sync_func() can race with
wakeup. This can lead to unnecessary sched_sync() but this case is
unlikely. IOW,
spin_lock_irq(&rss->rss_lock);
if (rss->exclusive)
wait_event_locked(rss->gp_wait, !rss->gp_count);
need_wait = rss->gp_count++;
need_sync = rss->gp_state == GP_IDLE;
if (need_sync)
rss->gp_state = GP_PENDING;
spin_unlock_irq(&rss->lock);
But still I don't like the (imho) unnecessary complications. And the
fact we can race with rcu_sync_func() even if this is very unlikely,
this just doesn't look good.
Oleg.
next prev parent reply other threads:[~2013-10-06 13:29 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-10-04 18:46 [PATCH 0/5] rcusync: validations + dtor + exclusive Oleg Nesterov
2013-10-04 18:46 ` [PATCH 1/5] rcusync: introduce struct rcu_sync_ops Oleg Nesterov
2013-10-04 19:12 ` Linus Torvalds
2013-10-04 19:22 ` Oleg Nesterov
2013-10-04 19:30 ` Steven Rostedt
2013-10-04 19:38 ` Linus Torvalds
2013-10-04 19:42 ` Peter Zijlstra
2013-10-05 17:21 ` Oleg Nesterov
2013-10-05 17:17 ` Oleg Nesterov
2013-10-08 9:13 ` Peter Zijlstra
2013-10-08 15:33 ` Oleg Nesterov
2013-10-08 16:34 ` Paul E. McKenney
2013-10-04 18:46 ` [PATCH 2/5] rcusync: add the CONFIG_PROVE_RCU checks Oleg Nesterov
2013-10-04 18:46 ` [PATCH 3/5] rcusync: introduce rcu_sync_dtor() Oleg Nesterov
2013-10-04 18:46 ` [PATCH 4/5] rcusync: introduce rcu_sync_struct->exclusive mode Oleg Nesterov
2013-10-04 19:29 ` Peter Zijlstra
2013-10-04 19:56 ` Oleg Nesterov
2013-10-04 20:41 ` Peter Zijlstra
2013-10-06 13:22 ` Oleg Nesterov [this message]
2013-10-07 10:49 ` Peter Zijlstra
2013-10-04 18:46 ` [PATCH 5/5] rcusync: make rcu_sync_enter() return "bool" Oleg Nesterov
2013-10-04 19:32 ` [PATCH 0/5] rcusync: validations + dtor + exclusive Peter Zijlstra
2013-10-04 21:28 ` Paul E. McKenney
2013-10-05 17:22 ` Oleg Nesterov
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=20131006132240.GA21357@redhat.com \
--to=oleg@redhat.com \
--cc=aarcange@redhat.com \
--cc=hannes@cmpxchg.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mgorman@suse.de \
--cc=mingo@kernel.org \
--cc=paulmck@linux.vnet.ibm.com \
--cc=peterz@infradead.org \
--cc=riel@redhat.com \
--cc=rostedt@goodmis.org \
--cc=srikar@linux.vnet.ibm.com \
--cc=tglx@linutronix.de \
--cc=torvalds@linux-foundation.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.