From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
To: NeilBrown <neilb@suse.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>,
Thomas Graf <tgraf@suug.ch>,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH 2/5] rhashtable: don't hold lock on first table throughout insertion.
Date: Fri, 27 Jul 2018 07:57:31 -0700 [thread overview]
Message-ID: <20180727145731.GA2780@linux.vnet.ibm.com> (raw)
In-Reply-To: <20180727031815.GW24813@linux.vnet.ibm.com>
On Thu, Jul 26, 2018 at 08:18:15PM -0700, Paul E. McKenney wrote:
> On Fri, Jul 27, 2018 at 11:04:37AM +1000, NeilBrown wrote:
> > On Wed, Jul 25 2018, Paul E. McKenney wrote:
> > >>
> > >> Looks good ... except ... naming is hard.
> > >>
> > >> is_after_call_rcu_init() asserts where in the lifecycle we are,
> > >> is_after_call_rcu() tests where in the lifecycle we are.
> > >>
> > >> The names are similar but the purpose is quite different.
> > >> Maybe s/is_after_call_rcu_init/call_rcu_init/ ??
> > >
> > > How about rcu_head_init() and rcu_head_after_call_rcu()?
>
> Very well, I will pull this change in on my next rebase.
Like this?
Thanx, Paul
------------------------------------------------------------------------
commit 45dfdcaee39bf6dd1785253c78e4805122ee8d93
Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Date: Tue Jul 24 15:28:09 2018 -0700
rcu: Provide functions for determining if call_rcu() has been invoked
This commit adds rcu_head_init() and rcu_head_after_call_rcu()
functions to help RCU users detect when another CPU has passed
the specified rcu_head structure and function to call_rcu().
The rcu_head_init() should be invoked before making the structure
visible to RCU readers, and then the rcu_head_after_call_rcu()
may be invoked from within an RCU read-side critical section on an
rcu_head structure that was obtained during a traversal of the data
structure in question. The rcu_head_after_call_rcu() function will
return true if the rcu_head structure has already been passed (with
the specified function) to call_rcu(), otherwise it will return false.
If rcu_head_init() has not been invoked on the rcu_head structure
or if the rcu_head (AKA callback) has already been invoked, then
rcu_head_after_call_rcu() will do WARN_ON_ONCE().
Reported-by: NeilBrown <neilb@suse.com> Signed-off-by: Paul
E. McKenney <paulmck@linux.vnet.ibm.com> [ paulmck: Apply neilb
feedback on naming. ]
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index
e4f821165d0b..4db8bcacc51a 100644 --- a/include/linux/rcupdate.h +++
b/include/linux/rcupdate.h @@ -857,6 +857,46 @@ static inline notrace
void rcu_read_unlock_sched_notrace(void)
#endif /* #else #ifdef CONFIG_ARCH_WEAK_RELEASE_ACQUIRE */
+/* Has the specified rcu_head structure been handed to call_rcu()? */ +
+/* + * rcu_head_init - Initialize rcu_head for rcu_head_after_call_rcu()
+ * @rhp: The rcu_head structure to initialize. + * + * If you intend
to invoke rcu_head_after_call_rcu() to test whether a + * given rcu_head
structure has already been passed to call_rcu(), then + * you must also
invoke this rcu_head_init() function on it just after + * allocating
that structure. Calls to this function must not race with + * calls
to call_rcu(), rcu_head_after_call_rcu(), or callback invocation.
+ */ +static inline void rcu_head_init(struct rcu_head *rhp) +{ +
rhp->func = (rcu_callback_t)~0L; +} + +/* + * rcu_head_after_call_rcu -
Has this rcu_head been passed to call_rcu()? + * @rhp: The rcu_head
structure to test. + * @func: The function passed to call_rcu()
along with @rhp. + * + * Returns @true if the @rhp has been passed to
call_rcu() with @func, + * and @false otherwise. Emits a warning in any
other case, including + * the case where @rhp has already been invoked
after a grace period. + * Calls to this function must not race with
callback invocation. One way + * to avoid such races is to enclose the
call to rcu_head_after_call_rcu() + * in an RCU read-side critical section
that includes a read-side fetch + * of the pointer to the structure
containing @rhp. + */ +static inline bool +rcu_head_after_call_rcu(struct
rcu_head *rhp, rcu_callback_t f) +{ + if (READ_ONCE(rhp->func) == f)
+ return true; + WARN_ON_ONCE(READ_ONCE(rhp->func) !=
(rcu_callback_t)~0L); + return false; +} + +
/* Transitional pre-consolidation compatibility definitions. */
static inline void synchronize_rcu_bh(void)
diff --git a/kernel/rcu/rcu.h b/kernel/rcu/rcu.h index
5dec94509a7e..4c56c1d98fb3 100644 --- a/kernel/rcu/rcu.h +++
b/kernel/rcu/rcu.h @@ -224,6 +224,7 @@ void kfree(const void *);
*/
static inline bool __rcu_reclaim(const char *rn, struct rcu_head *head) {
+ rcu_callback_t f;
unsigned long offset = (unsigned long)head->func;
rcu_lock_acquire(&rcu_callback_map);
@@ -234,7 +235,9 @@ static inline bool __rcu_reclaim(const char *rn,
struct rcu_head *head)
return true;
} else {
RCU_TRACE(trace_rcu_invoke_callback(rn, head);)
- head->func(head); + f = head->func; +
WRITE_ONCE(head->func, (rcu_callback_t)0L); + f(head);
rcu_lock_release(&rcu_callback_map); return false;
}
next prev parent reply other threads:[~2018-07-27 14:57 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-07-06 7:22 [PATCH 0/5] Rhashtable: convert to bit-spin locks NeilBrown
2018-07-06 7:22 ` [PATCH 2/5] rhashtable: don't hold lock on first table throughout insertion NeilBrown
2018-07-20 7:54 ` Herbert Xu
2018-07-20 14:41 ` Paul E. McKenney
2018-07-21 2:25 ` NeilBrown
2018-07-22 21:54 ` Paul E. McKenney
2018-07-22 23:13 ` NeilBrown
2018-07-23 20:56 ` Paul E. McKenney
2018-07-23 21:52 ` NeilBrown
2018-07-24 22:58 ` Paul E. McKenney
2018-07-25 4:53 ` NeilBrown
2018-07-25 15:22 ` Paul E. McKenney
2018-07-27 1:04 ` NeilBrown
2018-07-27 3:18 ` Paul E. McKenney
2018-07-27 14:57 ` Paul E. McKenney [this message]
2018-07-31 0:45 ` NeilBrown
2018-07-31 4:14 ` Paul E. McKenney
2018-07-31 5:04 ` NeilBrown
2018-07-31 14:44 ` Paul E. McKenney
2019-03-11 15:27 ` Paul E. McKenney
2019-03-11 21:50 ` NeilBrown
2019-03-11 22:10 ` Paul E. McKenney
2018-07-06 7:22 ` [PATCH 4/5] rhashtable: use bit_spin_locks to protect hash bucket NeilBrown
2018-07-06 7:22 ` [PATCH 5/5] rhashtable: add lockdep tracking to bucket bit-spin-locks NeilBrown
2018-07-06 7:22 ` [PATCH 3/5] rhashtable: allow rht_bucket_var to return NULL NeilBrown
2018-07-06 7:22 ` [PATCH 1/5] rhashtable: use cmpxchg() in nested_table_alloc() NeilBrown
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=20180727145731.GA2780@linux.vnet.ibm.com \
--to=paulmck@linux.vnet.ibm.com \
--cc=herbert@gondor.apana.org.au \
--cc=linux-kernel@vger.kernel.org \
--cc=neilb@suse.com \
--cc=netdev@vger.kernel.org \
--cc=tgraf@suug.ch \
/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.