From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
To: Joel Fernandes <joelaf@google.com>
Cc: linux-kernel@vger.kernel.org,
Joel Fernandes <joel@joelfernandes.org>,
Josh Triplett <josh@joshtriplett.org>,
Steven Rostedt <rostedt@goodmis.org>,
Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
Lai Jiangshan <jiangshanlai@gmail.com>,
byungchul.park@lge.com, kernel-team@android.com
Subject: Re: [PATCH v3 3/4] rcu: Use better variable names in funnel locking loop
Date: Mon, 21 May 2018 16:13:57 -0700 [thread overview]
Message-ID: <20180521231357.GI3803@linux.vnet.ibm.com> (raw)
In-Reply-To: <20180521044220.123933-4-joel@joelfernandes.org>
On Sun, May 20, 2018 at 09:42:19PM -0700, Joel Fernandes wrote:
> The funnel locking loop in rcu_start_this_gp uses rcu_root as a
> temporary variable while walking the combining tree. This causes a
> tiresome exercise of a code reader reminding themselves that rcu_root
> may not be root. Lets just call it rnp, and rename other variables as
> well to be more appropriate.
>
> Original patch: https://patchwork.kernel.org/patch/10396577/
>
> Signed-off-by: Joel Fernandes <joel@joelfernandes.org>
Nice!
Please see feedback interspersed below.
Thanx, Paul
> ---
> kernel/rcu/tree.c | 48 ++++++++++++++++++++++++-----------------------
> 1 file changed, 25 insertions(+), 23 deletions(-)
>
> diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
> index 0ffd41ba304f..879c67a31116 100644
> --- a/kernel/rcu/tree.c
> +++ b/kernel/rcu/tree.c
> @@ -1526,7 +1526,7 @@ static void trace_rcu_this_gp(struct rcu_node *rnp, struct rcu_data *rdp,
>
> /*
> * rcu_start_this_gp - Request the start of a particular grace period
> - * @rnp: The leaf node of the CPU from which to start.
> + * @rnp_start: The leaf node of the CPU from which to start.
> * @rdp: The rcu_data corresponding to the CPU from which to start.
> * @gp_seq_req: The gp_seq of the grace period to start.
> *
> @@ -1540,12 +1540,12 @@ static void trace_rcu_this_gp(struct rcu_node *rnp, struct rcu_data *rdp,
> *
> * Returns true if the GP thread needs to be awakened else false.
> */
> -static bool rcu_start_this_gp(struct rcu_node *rnp, struct rcu_data *rdp,
> +static bool rcu_start_this_gp(struct rcu_node *rnp_start, struct rcu_data *rdp,
> unsigned long gp_seq_req)
> {
> bool ret = false;
> struct rcu_state *rsp = rdp->rsp;
> - struct rcu_node *rnp_root;
> + struct rcu_node *rnp, *rnp_root = NULL;
Unless I am going blind, this patch really isn't using rnp_root. It
could be removed.
>
> /*
> * Use funnel locking to either acquire the root rcu_node
> @@ -1556,34 +1556,36 @@ static bool rcu_start_this_gp(struct rcu_node *rnp, struct rcu_data *rdp,
> * scan the leaf rcu_node structures. Note that rnp->lock must
> * not be released.
> */
> - raw_lockdep_assert_held_rcu_node(rnp);
> - trace_rcu_this_gp(rnp, rdp, gp_seq_req, TPS("Startleaf"));
> - for (rnp_root = rnp; 1; rnp_root = rnp_root->parent) {
> - if (rnp_root != rnp)
> - raw_spin_lock_rcu_node(rnp_root);
> - if (ULONG_CMP_GE(rnp_root->gp_seq_needed, gp_seq_req) ||
> - rcu_seq_started(&rnp_root->gp_seq, gp_seq_req) ||
> - (rnp != rnp_root &&
> - rcu_seq_state(rcu_seq_current(&rnp_root->gp_seq)))) {
> - trace_rcu_this_gp(rnp_root, rdp, gp_seq_req,
> + raw_lockdep_assert_held_rcu_node(rnp_start);
> + trace_rcu_this_gp(rnp_start, rdp, gp_seq_req, TPS("Startleaf"));
> + for (rnp = rnp_start; 1; rnp = rnp->parent) {
> + if (rnp != rnp_start)
> + raw_spin_lock_rcu_node(rnp);
> + if (ULONG_CMP_GE(rnp->gp_seq_needed, gp_seq_req) ||
> + rcu_seq_started(&rnp->gp_seq, gp_seq_req) ||
> + (rnp != rnp_start &&
> + rcu_seq_state(rcu_seq_current(&rnp->gp_seq)))) {
> + trace_rcu_this_gp(rnp, rdp, gp_seq_req,
> TPS("Prestarted"));
> goto unlock_out;
> }
> - rnp_root->gp_seq_needed = gp_seq_req;
> - if (rcu_seq_state(rcu_seq_current(&rnp->gp_seq))) {
> + rnp->gp_seq_needed = gp_seq_req;
> + if (rcu_seq_state(rcu_seq_current(&rnp_start->gp_seq))) {
The original had a performance bug, which is quite a bit more obvious
given the new names, so thank you for that! The above statement should
instead be as follows:
if (rcu_seq_state(rcu_seq_current(&rnp->gp_seq))) {
It does not make sense to keep checking the starting rcu_node because
changes to ->gp_seq happen first at the top of the tree. So we might
take an earlier exit by checking the current rnp instead of rechecking
rnp_start over and over.
Please feel free to make this change, which is probably best as a separate
patch. That way this rename patch can remain a straightforward rename patch.
> /*
> * We just marked the leaf, and a grace period
> * is in progress, which means that rcu_gp_cleanup()
> * will see the marking. Bail to reduce contention.
> */
> - trace_rcu_this_gp(rnp, rdp, gp_seq_req,
> + trace_rcu_this_gp(rnp_start, rdp, gp_seq_req,
> TPS("Startedleaf"));
> goto unlock_out;
> }
> - if (rnp_root != rnp && rnp_root->parent != NULL)
> - raw_spin_unlock_rcu_node(rnp_root);
> - if (!rnp_root->parent)
> + if (rnp != rnp_start && rnp->parent != NULL)
> + raw_spin_unlock_rcu_node(rnp);
> + if (!rnp->parent) {
> + rnp_root = rnp;
Since rnp_root is otherwise unused in the new version, the above statement
can be dropped along with the "if" statement's braces and the declaration.
> break; /* At root, and perhaps also leaf. */
> + }
> }
>
> /* If GP already in progress, just leave, otherwise start one. */
> @@ -1601,11 +1603,11 @@ static bool rcu_start_this_gp(struct rcu_node *rnp, struct rcu_data *rdp,
> trace_rcu_grace_period(rsp->name, READ_ONCE(rsp->gp_seq), TPS("newreq"));
> ret = true; /* Caller must wake GP kthread. */
> unlock_out:
> - if (rnp != rnp_root)
> - raw_spin_unlock_rcu_node(rnp_root);
> + if (rnp != rnp_start)
> + raw_spin_unlock_rcu_node(rnp);
> /* Push furthest requested GP to leaf node and rcu_data structure. */
> - if (ULONG_CMP_GE(rnp_root->gp_seq_needed, gp_seq_req)) {
> - rnp->gp_seq_needed = gp_seq_req;
> + if (ULONG_CMP_GE(rnp->gp_seq_needed, gp_seq_req)) {
> + rnp_start->gp_seq_needed = gp_seq_req;
> rdp->gp_seq_needed = gp_seq_req;
> }
> return ret;
> --
> 2.17.0.441.gb46fe60e1d-goog
>
next prev parent reply other threads:[~2018-05-21 23:12 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-05-21 4:42 [PATCH v3 0/4] fixes, cleanups for rcu/dev Joel Fernandes
2018-05-21 4:42 ` [PATCH v3 1/4] rcu: Add comment documenting how rcu_seq_snap works Joel Fernandes
2018-05-21 4:50 ` Randy Dunlap
2018-05-21 5:48 ` Joel Fernandes
2018-05-21 6:18 ` Randy Dunlap
2018-05-21 9:35 ` Joe Perches
2018-05-21 23:42 ` Paul E. McKenney
2018-05-21 4:42 ` [PATCH v3 2/4] rcu: Cleanup the variables used to request a new grace period Joel Fernandes
2018-05-21 23:39 ` Paul E. McKenney
2018-05-21 23:41 ` Joel Fernandes
2018-05-21 4:42 ` [PATCH v3 3/4] rcu: Use better variable names in funnel locking loop Joel Fernandes
2018-05-21 23:13 ` Paul E. McKenney [this message]
2018-05-22 0:00 ` Joel Fernandes
2018-05-22 0:19 ` Paul E. McKenney
2018-05-22 0:19 ` Joel Fernandes
2018-05-22 0:29 ` Paul E. McKenney
2018-05-21 4:42 ` [PATCH v3 4/4] rcu: Unlock non-start node only after accessing its gp_seq_needed Joel Fernandes
2018-05-21 23:25 ` Paul E. McKenney
2018-05-22 0:07 ` Joel Fernandes
2018-05-22 0:28 ` Paul E. McKenney
2018-05-22 4:16 ` Paul E. McKenney
2018-05-22 4:43 ` Joel Fernandes
2018-05-22 12:12 ` Paul E. McKenney
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=20180521231357.GI3803@linux.vnet.ibm.com \
--to=paulmck@linux.vnet.ibm.com \
--cc=byungchul.park@lge.com \
--cc=jiangshanlai@gmail.com \
--cc=joel@joelfernandes.org \
--cc=joelaf@google.com \
--cc=josh@joshtriplett.org \
--cc=kernel-team@android.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mathieu.desnoyers@efficios.com \
--cc=rostedt@goodmis.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.