lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Message-ID: <CAJhHMCAvzXUgCuiO5nDB0oZYkFsyJ1bdJmz5JML4jrLrC5F0qw@mail.gmail.com> Date: Thu, 14 Aug 2014 18:28:53 -0400 From: Pranith Kumar <bobby.prani@...il.com> To: "Paul E. McKenney" <paulmck@...ux.vnet.ibm.com> Cc: LKML <linux-kernel@...r.kernel.org>, Ingo Molnar <mingo@...nel.org>, Lai Jiangshan <laijs@...fujitsu.com>, Dipankar Sarma <dipankar@...ibm.com>, Andrew Morton <akpm@...ux-foundation.org>, Mathieu Desnoyers <mathieu.desnoyers@...icios.com>, Josh Triplett <josh@...htriplett.org>, Thomas Gleixner <tglx@...utronix.de>, Peter Zijlstra <peterz@...radead.org>, Steven Rostedt <rostedt@...dmis.org>, David Howells <dhowells@...hat.com>, Eric Dumazet <edumazet@...gle.com>, dvhart@...ux.intel.com, Frédéric Weisbecker <fweisbec@...il.com>, Oleg Nesterov <oleg@...hat.com> Subject: Re: [PATCH v5 tip/core/rcu 11/16] rcu: Defer rcu_tasks_kthread() creation till first call_rcu_tasks() On Mon, Aug 11, 2014 at 6:49 PM, Paul E. McKenney <paulmck@...ux.vnet.ibm.com> wrote: > From: "Paul E. McKenney" <paulmck@...ux.vnet.ibm.com> > > It is expected that many sites will have CONFIG_TASKS_RCU=y, but > will never actually invoke call_rcu_tasks(). For such sites, creating > rcu_tasks_kthread() at boot is wasteful. This commit therefore defers > creation of this kthread until the time of the first call_rcu_tasks(). > > This of course means that the first call_rcu_tasks() must be invoked > from process context after the scheduler is fully operational. > > Signed-off-by: Paul E. McKenney <paulmck@...ux.vnet.ibm.com> > --- > kernel/rcu/update.c | 33 ++++++++++++++++++++++++++------- > 1 file changed, 26 insertions(+), 7 deletions(-) > > diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c > index 1256a900cd01..d997163c7e92 100644 > --- a/kernel/rcu/update.c > +++ b/kernel/rcu/update.c > @@ -378,7 +378,12 @@ DEFINE_SRCU(tasks_rcu_exit_srcu); > static int rcu_task_stall_timeout __read_mostly = HZ * 60 * 10; > module_param(rcu_task_stall_timeout, int, 0644); > > -/* Post an RCU-tasks callback. */ > +static void rcu_spawn_tasks_kthread(void); > + > +/* > + * Post an RCU-tasks callback. First call must be from process context > + * after the scheduler if fully operational. > + */ > void call_rcu_tasks(struct rcu_head *rhp, void (*func)(struct rcu_head *rhp)) > { > unsigned long flags; > @@ -391,8 +396,10 @@ void call_rcu_tasks(struct rcu_head *rhp, void (*func)(struct rcu_head *rhp)) > *rcu_tasks_cbs_tail = rhp; > rcu_tasks_cbs_tail = &rhp->next; > raw_spin_unlock_irqrestore(&rcu_tasks_cbs_lock, flags); > - if (needwake) > + if (needwake) { > + rcu_spawn_tasks_kthread(); > wake_up(&rcu_tasks_cbs_wq); > + } > } > EXPORT_SYMBOL_GPL(call_rcu_tasks); > > @@ -618,15 +625,27 @@ static int __noreturn rcu_tasks_kthread(void *arg) > } > } > > -/* Spawn rcu_tasks_kthread() at boot time. */ > -static int __init rcu_spawn_tasks_kthread(void) > +/* Spawn rcu_tasks_kthread() at first call to call_rcu_tasks(). */ > +static void rcu_spawn_tasks_kthread(void) > { > - struct task_struct __maybe_unused *t; > + static DEFINE_MUTEX(rcu_tasks_kthread_mutex); > + static struct task_struct *rcu_tasks_kthread_ptr; > + struct task_struct *t; > > + if (ACCESS_ONCE(rcu_tasks_kthread_ptr)) { > + smp_mb(); /* Ensure caller sees full kthread. */ > + return; > + } I don't see the need for this smp_mb(). The caller has already seen that rcu_tasks_kthread_ptr is assigned. What are we ensuring with this barrier again? an smp_rmb() before this ACCESS_ONCE() and an smp_wmb() after assigning to rcu_tasks_kthread_ptr should be enough, right? > + mutex_lock(&rcu_tasks_kthread_mutex); > + if (rcu_tasks_kthread_ptr) { > + mutex_unlock(&rcu_tasks_kthread_mutex); > + return; > + } > t = kthread_run(rcu_tasks_kthread, NULL, "rcu_tasks_kthread"); > BUG_ON(IS_ERR(t)); > - return 0; > + smp_mb(); /* Ensure others see full kthread. */ > + ACCESS_ONCE(rcu_tasks_kthread_ptr) = t; Isn't it better to reverse these two statements and change as follows? ACCESS_ONCE(rcu_tasks_kthread_ptr) = t; smp_wmb(); or smp_store_release(rcu_tasks_kthread_ptr, t); will ensure that this write to rcu_task_kthread_ptr is ordered with the previous read. I recently read memory-barriers.txt, so please excuse me if I am totally wrong. But I am confused! :( > + mutex_unlock(&rcu_tasks_kthread_mutex); > } > -early_initcall(rcu_spawn_tasks_kthread); > > #endif /* #ifdef CONFIG_TASKS_RCU */ > -- > 1.8.1.5 > -- Pranith -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@...r.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists