From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
To: lianglihao@huawei.com
Cc: guohanjun@huawei.com, heng.z@huawei.com, hb.chen@huawei.com,
lihao.liang@gmail.com, linux-kernel@vger.kernel.org
Subject: Re: [PATCH RFC 09/16] prcu: Implement prcu_barrier() API
Date: Wed, 24 Jan 2018 22:24:57 -0800 [thread overview]
Message-ID: <20180125062457.GX3741@linux.vnet.ibm.com> (raw)
In-Reply-To: <1516694381-20333-10-git-send-email-lianglihao@huawei.com>
On Tue, Jan 23, 2018 at 03:59:34PM +0800, lianglihao@huawei.com wrote:
> From: Lihao Liang <lianglihao@huawei.com>
>
> This is PRCU's counterpart of RCU's rcu_barrier() API.
>
> Reviewed-by: Heng Zhang <heng.z@huawei.com>
> Signed-off-by: Lihao Liang <lianglihao@huawei.com>
> ---
> include/linux/prcu.h | 7 ++++++
> kernel/rcu/prcu.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 70 insertions(+)
>
> diff --git a/include/linux/prcu.h b/include/linux/prcu.h
> index 4e7d5d65..cce967fd 100644
> --- a/include/linux/prcu.h
> +++ b/include/linux/prcu.h
> @@ -5,6 +5,7 @@
> #include <linux/types.h>
> #include <linux/mutex.h>
> #include <linux/wait.h>
> +#include <linux/completion.h>
>
> #define CONFIG_PRCU
>
> @@ -32,6 +33,7 @@ struct prcu_local_struct {
> unsigned int online;
> unsigned long long version;
> unsigned long long cb_version;
> + struct rcu_head barrier_head;
> struct prcu_cblist cblist;
> };
>
> @@ -39,8 +41,11 @@ struct prcu_struct {
> atomic64_t global_version;
> atomic64_t cb_version;
> atomic_t active_ctr;
> + atomic_t barrier_cpu_count;
> struct mutex mtx;
> + struct mutex barrier_mtx;
> wait_queue_head_t wait_q;
> + struct completion barrier_completion;
> };
>
> #ifdef CONFIG_PRCU
> @@ -48,6 +53,7 @@ void prcu_read_lock(void);
> void prcu_read_unlock(void);
> void synchronize_prcu(void);
> void call_prcu(struct rcu_head *head, rcu_callback_t func);
> +void prcu_barrier(void);
> void prcu_init(void);
> void prcu_note_context_switch(void);
> int prcu_pending(void);
> @@ -60,6 +66,7 @@ void prcu_check_callbacks(void);
> #define prcu_read_unlock() do {} while (0)
> #define synchronize_prcu() do {} while (0)
> #define call_prcu() do {} while (0)
> +#define prcu_barrier() do {} while (0)
> #define prcu_init() do {} while (0)
> #define prcu_note_context_switch() do {} while (0)
> #define prcu_pending() 0
> diff --git a/kernel/rcu/prcu.c b/kernel/rcu/prcu.c
> index 373039c5..2664d091 100644
> --- a/kernel/rcu/prcu.c
> +++ b/kernel/rcu/prcu.c
> @@ -15,6 +15,7 @@ struct prcu_struct global_prcu = {
> .cb_version = ATOMIC64_INIT(0),
> .active_ctr = ATOMIC_INIT(0),
> .mtx = __MUTEX_INITIALIZER(global_prcu.mtx),
> + .barrier_mtx = __MUTEX_INITIALIZER(global_prcu.barrier_mtx),
> .wait_q = __WAIT_QUEUE_HEAD_INITIALIZER(global_prcu.wait_q)
> };
> struct prcu_struct *prcu = &global_prcu;
> @@ -250,6 +251,68 @@ static __latent_entropy void prcu_process_callbacks(struct softirq_action *unuse
> local_irq_restore(flags);
> }
>
> +/*
> + * PRCU callback function for prcu_barrier().
> + * If we are last, wake up the task executing prcu_barrier().
> + */
> +static void prcu_barrier_callback(struct rcu_head *rhp)
> +{
> + if (atomic_dec_and_test(&prcu->barrier_cpu_count))
> + complete(&prcu->barrier_completion);
> +}
> +
> +/*
> + * Called with preemption disabled, and from cross-cpu IRQ context.
> + */
> +static void prcu_barrier_func(void *info)
> +{
> + struct prcu_local_struct *local = this_cpu_ptr(&prcu_local);
> +
> + atomic_inc(&prcu->barrier_cpu_count);
> + call_prcu(&local->barrier_head, prcu_barrier_callback);
> +}
> +
> +/* Waiting for all PRCU callbacks to complete. */
> +void prcu_barrier(void)
> +{
> + int cpu;
> +
> + /* Take mutex to serialize concurrent prcu_barrier() requests. */
> + mutex_lock(&prcu->barrier_mtx);
> +
> + /*
> + * Initialize the count to one rather than to zero in order to
> + * avoid a too-soon return to zero in case of a short grace period
> + * (or preemption of this task).
> + */
> + init_completion(&prcu->barrier_completion);
> + atomic_set(&prcu->barrier_cpu_count, 1);
> +
> + /*
> + * Register a new callback on each CPU using IPI to prevent races
> + * with call_prcu(). When that callback is invoked, we will know
> + * that all of the corresponding CPU's preceding callbacks have
> + * been invoked.
> + */
> + for_each_possible_cpu(cpu)
> + smp_call_function_single(cpu, prcu_barrier_func, NULL, 1);
This code seems to be assuming CONFIG_HOTPLUG_CPU=n. This might explain
your rcutorture failure.
> + /* Decrement the count as we initialize it to one. */
> + if (atomic_dec_and_test(&prcu->barrier_cpu_count))
> + complete(&prcu->barrier_completion);
> +
> + /*
> + * Now that we have an prcu_barrier_callback() callback on each
> + * CPU, and thus each counted, remove the initial count.
> + * Wait for all prcu_barrier_callback() callbacks to be invoked.
> + */
> + wait_for_completion(&prcu->barrier_completion);
> +
> + /* Other rcu_barrier() invocations can now safely proceed. */
> + mutex_unlock(&prcu->barrier_mtx);
> +}
> +EXPORT_SYMBOL(prcu_barrier);
> +
> void prcu_init_local_struct(int cpu)
> {
> struct prcu_local_struct *local;
> --
> 2.14.1.729.g59c0ea183
>
next prev parent reply other threads:[~2018-01-25 6:30 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-01-23 7:59 [PATCH RFC 00/16] A new RCU implementation based on a fast consensus protocol lianglihao
2018-01-23 7:59 ` [PATCH RFC 01/16] prcu: Add PRCU implementation lianglihao
2018-01-24 11:26 ` Peter Zijlstra
2018-01-24 17:15 ` Lihao Liang
2018-01-24 20:19 ` Peter Zijlstra
2018-01-25 6:16 ` Paul E. McKenney
2018-01-25 7:30 ` Boqun Feng
2018-01-30 5:34 ` zhangheng (AC)
2018-01-30 6:40 ` Boqun Feng
2018-01-30 10:42 ` zhangheng (AC)
2018-01-27 7:35 ` Lihao Liang
2018-01-30 3:58 ` zhangheng (AC)
2018-01-29 9:10 ` Lai Jiangshan
2018-01-30 6:21 ` zhangheng (AC)
2018-01-23 7:59 ` [PATCH RFC 02/16] rcutorture: Add PRCU rcu_torture_ops lianglihao
2018-01-23 7:59 ` [PATCH RFC 03/16] rcutorture: Add PRCU test config files lianglihao
2018-01-25 6:27 ` Paul E. McKenney
2018-01-23 7:59 ` [PATCH RFC 04/16] rcuperf: Add PRCU rcu_perf_ops lianglihao
2018-01-23 7:59 ` [PATCH RFC 05/16] rcuperf: Add PRCU test config files lianglihao
2018-01-23 7:59 ` [PATCH RFC 06/16] rcuperf: Set gp_exp to true for tests to run lianglihao
2018-01-25 6:18 ` Paul E. McKenney
2018-01-26 8:33 ` Lihao Liang
2018-01-23 7:59 ` [PATCH RFC 07/16] prcu: Implement call_prcu() API lianglihao
2018-01-25 6:20 ` Paul E. McKenney
2018-01-26 8:44 ` Lihao Liang
2018-01-26 22:22 ` Paul E. McKenney
2018-01-23 7:59 ` [PATCH RFC 08/16] prcu: Implement PRCU callback processing lianglihao
2018-01-23 7:59 ` [PATCH RFC 09/16] prcu: Implement prcu_barrier() API lianglihao
2018-01-25 6:24 ` Paul E. McKenney [this message]
2018-01-23 7:59 ` [PATCH RFC 10/16] rcutorture: Test call_prcu() and prcu_barrier() lianglihao
2018-01-23 7:59 ` [PATCH RFC 11/16] rcutorture: Add basic ARM64 support to run scripts lianglihao
2018-01-23 7:59 ` [PATCH RFC 12/16] prcu: Add PRCU Kconfig parameter lianglihao
2018-01-23 7:59 ` [PATCH RFC 13/16] prcu: Comment source code lianglihao
2018-01-23 7:59 ` [PATCH RFC 14/16] rcuperf: Add config files with various CONFIG_NR_CPUS lianglihao
2018-01-23 7:59 ` [PATCH RFC 15/16] rcutorture: Add scripts to run experiments lianglihao
2018-01-25 6:28 ` Paul E. McKenney
2018-01-23 7:59 ` [PATCH RFC 16/16] Add GPLv2 license lianglihao
2018-01-25 5:53 ` [PATCH RFC 00/16] A new RCU implementation based on a fast consensus protocol Paul E. McKenney
2018-01-27 7:22 ` Lihao Liang
2018-01-27 7:57 ` Paul E. McKenney
2018-01-27 9:57 ` Lihao Liang
2018-01-27 23:46 ` Paul E. McKenney
2018-01-27 23:41 ` 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=20180125062457.GX3741@linux.vnet.ibm.com \
--to=paulmck@linux.vnet.ibm.com \
--cc=guohanjun@huawei.com \
--cc=hb.chen@huawei.com \
--cc=heng.z@huawei.com \
--cc=lianglihao@huawei.com \
--cc=lihao.liang@gmail.com \
--cc=linux-kernel@vger.kernel.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.