Re: [PATCH 22/32] rcu: Restart tick if we enqueue a callback in a nohz/cpuset CPU

Paul E. McKenney
2011-08-16T20:20:16Z

On Mon, Aug 15, 2011 at 05:52:19PM +0200, Frederic Weisbecker wrote:
> If we enqueue an rcu callback, we need the CPU tick to stay
> alive until we take care of those by completing the appropriate
> grace period.
>
> Thus, when we call_rcu(), send a self IPI that checks rcu_needs_cpu()
> so that we restore a periodic tick behaviour that can take care of
> everything.

One question below.

Thanx, Paul

> Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Anton Blanchard <anton@au1.ibm.com>
> Cc: Avi Kivity <avi@redhat.com>
> Cc: Ingo Molnar <mingo@elte.hu>
> Cc: Lai Jiangshan <laijs@cn.fujitsu.com>
> Cc: Paul E . McKenney <paulmck@linux.vnet.ibm.com>
> Cc: Paul Menage <menage@google.com>
> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Cc: Stephen Hemminger <shemminger@vyatta.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Tim Pepper <lnxninja@linux.vnet.ibm.com>
> ---
> kernel/rcutree.c | 8 ++++++++
> 1 files changed, 8 insertions(+), 0 deletions(-)
>
> diff --git a/kernel/rcutree.c b/kernel/rcutree.c
> index d496c70..b5643ce2 100644
> --- a/kernel/rcutree.c
> +++ b/kernel/rcutree.c
> @@ -51,6 +51,7 @@
> #include <linux/kthread.h>
> #include <linux/prefetch.h>
> #include <linux/cpuset.h>
> +#include <linux/tick.h>
>
> #include "rcutree.h"
>
> @@ -1546,6 +1547,13 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu),
> rdp->nxttail[RCU_NEXT_TAIL] = &head->next;
> rdp->qlen++;
>
> + /* Restart the timer if needed to handle the callbacks */
> + if (tick_nohz_adaptive_mode()) {
> + /* Make updates on nxtlist visible to self IPI */
> + barrier();
> + smp_cpuset_update_nohz(smp_processor_id());
> + }
> +

But this must be happening in a system call or interrupt handler, right?
If so, won't we get a chance to check things on exit from the system call
or interrupt? Or are you hooking only into syscall entry?

> /* If interrupts were disabled, don't dive into RCU core. */
> if (irqs_disabled_flags(flags)) {
> local_irq_restore(flags);
> --
> 1.7.5.4
>