From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
To: Oleg Nesterov <oleg@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>,
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 2/3] rcu: Create rcu_sync infrastructure
Date: Thu, 3 Oct 2013 15:00:57 -0700 [thread overview]
Message-ID: <20131003220057.GY5790@linux.vnet.ibm.com> (raw)
In-Reply-To: <20131003211009.GA4127@redhat.com>
On Thu, Oct 03, 2013 at 11:10:09PM +0200, Oleg Nesterov wrote:
> On 10/03, Oleg Nesterov wrote:
> >
> > So unless Peter objects I'll write the changelogs (always nontrivial task),
> > test, and send these 2 patches + "add ops->barr() / rcu_sync_wait_for_cb"
> > tomorrow.
>
> And, can't resist, probably another patch below (incomplete, needs the
> obvious change in cpu.c and the new trivial __complete_locked() helper).
>
> Hmm. But when I look at wait_for_completion() I think it is buggy. Will
> try to send the fix tomorrow.
>
> Oleg.
>
> rcusync: introduce rcu_sync_struct->exclusive mode
>
> CHANGELOG.
Should the changelog really be in all caps? (Sorry, couldn't resist...)
One confusion below (mine), otherwise cannot see any obvious problems
with it. Not that this should count for much, getting a bit punch-drunk
reviewing this sort of code. ;-)
Thanx, Paul
> ---
>
> diff --git a/include/linux/rcusync.h b/include/linux/rcusync.h
> index ab787c1..265875c 100644
> --- a/include/linux/rcusync.h
> +++ b/include/linux/rcusync.h
> @@ -1,8 +1,8 @@
> #ifndef _LINUX_RCUSYNC_H_
> #define _LINUX_RCUSYNC_H_
>
> -#include <linux/wait.h>
> #include <linux/rcupdate.h>
> +#include <linux/completion.h>
>
> struct rcu_sync_ops {
> void (*sync)(void);
> @@ -15,11 +15,12 @@ struct rcu_sync_ops {
> struct rcu_sync_struct {
> int gp_state;
> int gp_count;
> - wait_queue_head_t gp_wait;
> + struct completion gp_comp;
>
> int cb_state;
> struct rcu_head cb_head;
>
> + bool exclusive;
> struct rcu_sync_ops *ops;
> };
>
> @@ -33,31 +34,33 @@ static inline bool rcu_sync_is_idle(struct rcu_sync_struct *rss)
>
> enum rcu_sync_type { RCU_SYNC, RCU_SCHED_SYNC, RCU_BH_SYNC };
>
> -extern void rcu_sync_init(struct rcu_sync_struct *, enum rcu_sync_type);
> +extern void rcu_sync_init(struct rcu_sync_struct *,
> + enum rcu_sync_type, bool excl);
> extern void rcu_sync_enter(struct rcu_sync_struct *);
> extern void rcu_sync_exit(struct rcu_sync_struct *);
>
> extern struct rcu_sync_ops rcu_sync_ops_array[];
>
> -#define __RCU_SYNC_INITIALIZER(name, type) { \
> +#define __RCU_SYNC_INITIALIZER(name, type, excl) { \
> .gp_state = 0, \
> .gp_count = 0, \
> - .gp_wait = __WAIT_QUEUE_HEAD_INITIALIZER(name.gp_wait), \
> + .gp_comp = COMPLETION_INITIALIZER(name.gp_comp), \
> .cb_state = 0, \
> + .exclusive = excl, \
> .ops = rcu_sync_ops_array + (type), \
> }
>
> -#define __DEFINE_RCU_SYNC(name, type) \
> - struct rcu_sync_struct name = __RCU_SYNC_INITIALIZER(name, type)
> +#define __DEFINE_RCU_SYNC(name, type, excl) \
> + struct rcu_sync_struct name = __RCU_SYNC_INITIALIZER(name, type, excl)
>
> -#define DEFINE_RCU_SYNC(name) \
> - __DEFINE_RCU_SYNC(name, RCU_SYNC)
> +#define DEFINE_RCU_SYNC(name, excl) \
> + __DEFINE_RCU_SYNC(name, RCU_SYNC, excl)
>
> -#define DEFINE_RCU_SCHED_SYNC(name) \
> - __DEFINE_RCU_SYNC(name, RCU_SCHED_SYNC)
> +#define DEFINE_RCU_SCHED_SYNC(name, excl) \
> + __DEFINE_RCU_SYNC(name, RCU_SCHED_SYNC, excl)
>
> -#define DEFINE_RCU_BH_SYNC(name) \
> - __DEFINE_RCU_SYNC(name, RCU_BH_SYNC)
> +#define DEFINE_RCU_BH_SYNC(name, excl) \
> + __DEFINE_RCU_SYNC(name, RCU_BH_SYNC, excl)
>
> #endif /* _LINUX_RCUSYNC_H_ */
>
> diff --git a/kernel/rcusync.c b/kernel/rcusync.c
> index 21cde9b..d8068df 100644
> --- a/kernel/rcusync.c
> +++ b/kernel/rcusync.c
> @@ -4,7 +4,7 @@
> enum { GP_IDLE = 0, GP_PENDING, GP_PASSED };
> enum { CB_IDLE = 0, CB_PENDING, CB_REPLAY };
>
> -#define rss_lock gp_wait.lock
> +#define rss_lock gp_comp.wait.lock
>
> #ifdef CONFIG_PROVE_RCU
> #define __INIT_HELD(func) .held = func,
> @@ -30,11 +30,13 @@ struct rcu_sync_ops rcu_sync_ops_array[] = {
> },
> };
>
> -void rcu_sync_init(struct rcu_sync_struct *rss, enum rcu_sync_type type)
> +void rcu_sync_init(struct rcu_sync_struct *rss,
> + enum rcu_sync_type type, bool excl)
> {
> memset(rss, 0, sizeof(*rss));
> - init_waitqueue_head(&rss->gp_wait);
> + init_completion(&rss->gp_comp);
> rss->ops = rcu_sync_ops_array + type;
> + rss->exclusive = excl;
> }
>
> void rcu_sync_enter(struct rcu_sync_struct *rss)
> @@ -53,9 +55,13 @@ void rcu_sync_enter(struct rcu_sync_struct *rss)
> if (need_sync) {
> rss->ops->sync();
> rss->gp_state = GP_PASSED;
> - wake_up_all(&rss->gp_wait);
> + if (!rss->exclusive)
> + wake_up_all(&rss->gp_comp.wait);
Not sure about the wake_up_all() on a completion, but if we are exclusive,
don't we need to complete() the completion here?
Oh, I guess gp_comp.wait is exactly a wait_queue_head_t, so I guess
you can do wake_up_all() on it... And the thing we would wake up
is ourselves, and we are already awake.
Never mind!!!
> } else if (need_wait) {
> - wait_event(rss->gp_wait, rss->gp_state == GP_PASSED);
> + if (!rss->exclusive)
> + wait_event(rss->gp_comp.wait, rss->gp_state == GP_PASSED);
> + else
> + wait_for_completion(&rss->gp_comp);
> } else {
> /*
> * Possible when there's a pending CB from a rcu_sync_exit().
> @@ -110,6 +116,8 @@ void rcu_sync_exit(struct rcu_sync_struct *rss)
> } else if (rss->cb_state == CB_PENDING) {
> rss->cb_state = CB_REPLAY;
> }
> + } else if (rss->exclusive) {
> + __complete_locked(&rss->gp_comp);
> }
> spin_unlock_irq(&rss->rss_lock);
> }
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
next prev parent reply other threads:[~2013-10-03 22:01 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-10-02 14:56 [PATCH 0/3] Optimize the cpu hotplug locking Peter Zijlstra
2013-10-02 14:56 ` [PATCH 1/3] hotplug: Optimize {get,put}_online_cpus() Peter Zijlstra
2013-10-03 14:01 ` Peter Zijlstra
2013-10-03 16:27 ` Paul E. McKenney
2013-10-03 16:26 ` Paul E. McKenney
2013-10-02 14:56 ` [PATCH 2/3] rcu: Create rcu_sync infrastructure Peter Zijlstra
2013-10-02 15:49 ` Oleg Nesterov
2013-10-03 16:42 ` Paul E. McKenney
2013-10-08 8:18 ` Peter Zijlstra
2013-10-03 16:41 ` Paul E. McKenney
2013-10-03 17:00 ` Oleg Nesterov
2013-10-03 17:15 ` Paul E. McKenney
2013-10-03 18:40 ` Peter Zijlstra
2013-10-03 18:45 ` Paul E. McKenney
2013-10-03 18:47 ` Oleg Nesterov
2013-10-03 19:21 ` Paul E. McKenney
2013-10-03 19:32 ` Oleg Nesterov
2013-10-03 19:33 ` Oleg Nesterov
2013-10-03 19:50 ` Paul E. McKenney
2013-10-03 20:00 ` Oleg Nesterov
2013-10-03 21:10 ` Oleg Nesterov
2013-10-03 22:00 ` Paul E. McKenney [this message]
2013-10-04 11:29 ` Oleg Nesterov
2013-10-04 16:22 ` Paul E. McKenney
2013-10-04 7:18 ` Peter Zijlstra
2013-10-04 11:15 ` Oleg Nesterov
2013-10-04 11:36 ` Peter Zijlstra
2013-10-04 11:50 ` Oleg Nesterov
2013-10-04 11:44 ` Peter Zijlstra
2013-10-04 12:13 ` Oleg Nesterov
2013-10-04 12:38 ` Peter Zijlstra
2013-10-04 13:31 ` Oleg Nesterov
2013-10-04 14:43 ` Peter Zijlstra
2013-10-04 15:13 ` Oleg Nesterov
2013-10-04 16:25 ` Peter Zijlstra
2013-10-04 19:06 ` Oleg Nesterov
2013-10-04 19:41 ` Peter Zijlstra
2013-10-05 17:31 ` Oleg Nesterov
2013-10-04 7:00 ` Peter Zijlstra
2013-10-03 20:14 ` Paolo Bonzini
2013-10-04 7:01 ` Peter Zijlstra
2013-10-02 14:56 ` [PATCH 3/3] hotplug: Optimize cpu_hotplug_{begin,done}() using rcu_sync Peter Zijlstra
2013-10-03 16:48 ` Paul E. McKenney
2013-10-03 18:41 ` Peter Zijlstra
2013-10-03 18:46 ` Paul E. McKenney
2013-10-03 19:05 ` 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=20131003220057.GY5790@linux.vnet.ibm.com \
--to=paulmck@linux.vnet.ibm.com \
--cc=aarcange@redhat.com \
--cc=hannes@cmpxchg.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mgorman@suse.de \
--cc=mingo@kernel.org \
--cc=oleg@redhat.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).