All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
To: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>,
	yong.zhang0@gmail.com, oleg@redhat.com,
	linux-kernel@vger.kernel.org, akpm@linux-foundation.org,
	mingo@elte.hu, lizf@cn.fujitsu.com, miaox@cn.fujitsu.com
Subject: Re: [PATCH v2 1/2] rcu: don't bind offline cpu
Date: Fri, 20 May 2011 15:46:53 -0700	[thread overview]
Message-ID: <20110520224653.GM2366@linux.vnet.ibm.com> (raw)
In-Reply-To: <1305798113.2466.7216.camel@twins>

On Thu, May 19, 2011 at 11:41:53AM +0200, Peter Zijlstra wrote:
> On Thu, 2011-05-19 at 17:50 +0900, KOSAKI Motohiro wrote:
> > I'm sorry. Please give me a bit time.
> 
> N/P, as I've already found out CPU_STARTING isn't a suitable location
> either.
> 
> How about something like the below...
> 
> 
> ---
> Subject: rcu: Remove waitqueue usage for cpu,node and boost kthreads
> From: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Date: Thu May 19 11:27:39 CEST 2011
> 
> Since wait-queue usage is inconsistent (node) and generally not needed
> since we know exactly which thread to wake, rip it out.
> 
> The problem is that wake_up() only issues an actual wake-up when there's
> a thread waiting on the queue which means we need an extra, explicit,
> wakeup to kick-start the kthread itself (they're born sleeping).
> 
> Now, since we already know which exact thread we want to wake up,
> there's not point really in enqueing it on a waitqueue. So provide Paul
> with a nice rcu_wait() macro to replace wait_event_interruptible() with
> and rip out all the waitqueue stuff.
> 
> This moves us to an explicit, unconditional, wake_up_process() which can
> be used to wake us from both conditions.

Hello, Peter,

Thank you!  I have queued this and will test it.

I am having some difficulty understanding the synchronization in the
rcu_node_kthread() case, where I want to hold the rcu_node structure's
->lock over the "if (cond) break;" in rcu_wait(), but cannot prove that
it is really necessary.

Will look it over again after the jetlag has worn off a bit.

							Thanx, Paul

> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
> ---
> Index: linux-2.6/kernel/rcutree.c
> ===================================================================
> --- linux-2.6.orig/kernel/rcutree.c
> +++ linux-2.6/kernel/rcutree.c
> @@ -94,7 +94,6 @@ static DEFINE_PER_CPU(struct task_struct
>  DEFINE_PER_CPU(unsigned int, rcu_cpu_kthread_status);
>  DEFINE_PER_CPU(int, rcu_cpu_kthread_cpu);
>  DEFINE_PER_CPU(unsigned int, rcu_cpu_kthread_loops);
> -static DEFINE_PER_CPU(wait_queue_head_t, rcu_cpu_wq);
>  DEFINE_PER_CPU(char, rcu_cpu_has_work);
>  static char rcu_kthreads_spawnable;
>  
> @@ -1475,7 +1474,7 @@ static void invoke_rcu_cpu_kthread(void)
>  		local_irq_restore(flags);
>  		return;
>  	}
> -	wake_up(&__get_cpu_var(rcu_cpu_wq));
> +	wake_up_process(__this_cpu_read(rcu_cpu_kthread_task));
>  	local_irq_restore(flags);
>  }
>  
> @@ -1598,14 +1597,12 @@ static int rcu_cpu_kthread(void *arg)
>  	unsigned long flags;
>  	int spincnt = 0;
>  	unsigned int *statusp = &per_cpu(rcu_cpu_kthread_status, cpu);
> -	wait_queue_head_t *wqp = &per_cpu(rcu_cpu_wq, cpu);
>  	char work;
>  	char *workp = &per_cpu(rcu_cpu_has_work, cpu);
>  
>  	for (;;) {
>  		*statusp = RCU_KTHREAD_WAITING;
> -		wait_event_interruptible(*wqp,
> -					 *workp != 0 || kthread_should_stop());
> +		rcu_wait(*workp != 0 || kthread_should_stop());
>  		local_bh_disable();
>  		if (rcu_cpu_kthread_should_stop(cpu)) {
>  			local_bh_enable();
> @@ -1656,7 +1653,6 @@ static int __cpuinit rcu_spawn_one_cpu_k
>  	per_cpu(rcu_cpu_kthread_cpu, cpu) = cpu;
>  	WARN_ON_ONCE(per_cpu(rcu_cpu_kthread_task, cpu) != NULL);
>  	per_cpu(rcu_cpu_kthread_task, cpu) = t;
> -	wake_up_process(t);
>  	sp.sched_priority = RCU_KTHREAD_PRIO;
>  	sched_setscheduler_nocheck(t, SCHED_FIFO, &sp);
>  	return 0;
> @@ -1679,7 +1675,7 @@ static int rcu_node_kthread(void *arg)
>  
>  	for (;;) {
>  		rnp->node_kthread_status = RCU_KTHREAD_WAITING;
> -		wait_event_interruptible(rnp->node_wq, rnp->wakemask != 0);
> +		rcu_wait(rnp->wakemask != 0);
>  		rnp->node_kthread_status = RCU_KTHREAD_RUNNING;
>  		raw_spin_lock_irqsave(&rnp->lock, flags);
>  		mask = rnp->wakemask;
> @@ -1764,7 +1760,6 @@ static int __cpuinit rcu_spawn_one_node_
>  		raw_spin_lock_irqsave(&rnp->lock, flags);
>  		rnp->node_kthread_task = t;
>  		raw_spin_unlock_irqrestore(&rnp->lock, flags);
> -		wake_up_process(t);
>  		sp.sched_priority = 99;
>  		sched_setscheduler_nocheck(t, SCHED_FIFO, &sp);
>  	}
> @@ -1781,21 +1776,16 @@ static int __init rcu_spawn_kthreads(voi
>  
>  	rcu_kthreads_spawnable = 1;
>  	for_each_possible_cpu(cpu) {
> -		init_waitqueue_head(&per_cpu(rcu_cpu_wq, cpu));
>  		per_cpu(rcu_cpu_has_work, cpu) = 0;
>  		if (cpu_online(cpu))
>  			(void)rcu_spawn_one_cpu_kthread(cpu);
>  	}
>  	rnp = rcu_get_root(rcu_state);
> -	init_waitqueue_head(&rnp->node_wq);
> -	rcu_init_boost_waitqueue(rnp);
>  	(void)rcu_spawn_one_node_kthread(rcu_state, rnp);
> -	if (NUM_RCU_NODES > 1)
> -		rcu_for_each_leaf_node(rcu_state, rnp) {
> -			init_waitqueue_head(&rnp->node_wq);
> -			rcu_init_boost_waitqueue(rnp);
> +	if (NUM_RCU_NODES > 1) {
> +		rcu_for_each_leaf_node(rcu_state, rnp)
>  			(void)rcu_spawn_one_node_kthread(rcu_state, rnp);
> -		}
> +	}
>  	return 0;
>  }
>  early_initcall(rcu_spawn_kthreads);
> Index: linux-2.6/kernel/rcutree.h
> ===================================================================
> --- linux-2.6.orig/kernel/rcutree.h
> +++ linux-2.6/kernel/rcutree.h
> @@ -28,6 +28,17 @@
>  #include <linux/cpumask.h>
>  #include <linux/seqlock.h>
>  
> +#define rcu_wait(cond)						\
> +do {								\
> +	for (;;) {						\
> +		set_current_state(TASK_INTERRUPTIBLE);		\
> +		if (cond)					\
> +			break;					\
> +		schedule();					\
> +	}							\
> +	__set_current_state(TASK_RUNNING);			\
> +} while (0)
> +
>  /*
>   * Define shape of hierarchy based on NR_CPUS and CONFIG_RCU_FANOUT.
>   * In theory, it should be possible to add more levels straightforwardly.
> @@ -157,9 +168,6 @@ struct rcu_node {
>  	struct task_struct *boost_kthread_task;
>  				/* kthread that takes care of priority */
>  				/*  boosting for this rcu_node structure. */
> -	wait_queue_head_t boost_wq;
> -				/* Wait queue on which to park the boost */
> -				/*  kthread. */
>  	unsigned int boost_kthread_status;
>  				/* State of boost_kthread_task for tracing. */
>  	unsigned long n_tasks_boosted;
> @@ -186,9 +194,6 @@ struct rcu_node {
>  				/* kthread that takes care of this rcu_node */
>  				/*  structure, for example, awakening the */
>  				/*  per-CPU kthreads as needed. */
> -	wait_queue_head_t node_wq;
> -				/* Wait queue on which to park the per-node */
> -				/*  kthread. */
>  	unsigned int node_kthread_status;
>  				/* State of node_kthread_task for tracing. */
>  } ____cacheline_internodealigned_in_smp;
> @@ -443,7 +448,6 @@ static void __cpuinit rcu_preempt_init_p
>  static void rcu_preempt_send_cbs_to_online(void);
>  static void __init __rcu_init_preempt(void);
>  static void rcu_needs_cpu_flush(void);
> -static void __init rcu_init_boost_waitqueue(struct rcu_node *rnp);
>  static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags);
>  static void rcu_boost_kthread_setaffinity(struct rcu_node *rnp,
>  					  cpumask_var_t cm);
> Index: linux-2.6/kernel/rcutree_plugin.h
> ===================================================================
> --- linux-2.6.orig/kernel/rcutree_plugin.h
> +++ linux-2.6/kernel/rcutree_plugin.h
> @@ -1196,8 +1196,7 @@ static int rcu_boost_kthread(void *arg)
>  
>  	for (;;) {
>  		rnp->boost_kthread_status = RCU_KTHREAD_WAITING;
> -		wait_event_interruptible(rnp->boost_wq, rnp->boost_tasks ||
> -							rnp->exp_tasks);
> +		rcu_wait(rnp->boost_tasks || rnp->exp_tasks);
>  		rnp->boost_kthread_status = RCU_KTHREAD_RUNNING;
>  		more2boost = rcu_boost(rnp);
>  		if (more2boost)
> @@ -1275,14 +1274,6 @@ static void rcu_preempt_boost_start_gp(s
>  }
>  
>  /*
> - * Initialize the RCU-boost waitqueue.
> - */
> -static void __init rcu_init_boost_waitqueue(struct rcu_node *rnp)
> -{
> -	init_waitqueue_head(&rnp->boost_wq);
> -}
> -
> -/*
>   * Create an RCU-boost kthread for the specified node if one does not
>   * already exist.  We only create this kthread for preemptible RCU.
>   * Returns zero if all is well, a negated errno otherwise.
> @@ -1306,7 +1297,6 @@ static int __cpuinit rcu_spawn_one_boost
>  	raw_spin_lock_irqsave(&rnp->lock, flags);
>  	rnp->boost_kthread_task = t;
>  	raw_spin_unlock_irqrestore(&rnp->lock, flags);
> -	wake_up_process(t);
>  	sp.sched_priority = RCU_KTHREAD_PRIO;
>  	sched_setscheduler_nocheck(t, SCHED_FIFO, &sp);
>  	return 0;
> @@ -1328,10 +1318,6 @@ static void rcu_preempt_boost_start_gp(s
>  {
>  }
>  
> -static void __init rcu_init_boost_waitqueue(struct rcu_node *rnp)
> -{
> -}
> -
>  static int __cpuinit rcu_spawn_one_boost_kthread(struct rcu_state *rsp,
>  						 struct rcu_node *rnp,
>  						 int rnp_index)
> 

  parent reply	other threads:[~2011-05-20 22:47 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-04-28 14:20 [RFC PATCH] cpuset: fix cpuset_cpus_allowed_fallback() don't update tsk->rt.nr_cpus_allowed KOSAKI Motohiro
2011-04-28 16:11 ` Oleg Nesterov
2011-05-02 10:42   ` KOSAKI Motohiro
2011-05-02 10:55     ` [PATCH 1/2] " KOSAKI Motohiro
2011-05-11 16:05       ` Peter Zijlstra
2011-05-13  5:48         ` KOSAKI Motohiro
2011-05-13  6:42           ` Yong Zhang
2011-05-13  7:33             ` KOSAKI Motohiro
2011-05-13  7:43               ` Yong Zhang
2011-05-13  9:34                 ` KOSAKI Motohiro
2011-05-13 17:02             ` Peter Zijlstra
2011-05-14 11:17               ` KOSAKI Motohiro
2011-05-16 13:37               ` Yong Zhang
2011-05-19  8:45                 ` Peter Zijlstra
2011-05-19  8:54                   ` Yong Zhang
2011-05-15 18:55             ` Paul E. McKenney
2011-05-16 13:26               ` Yong Zhang
2011-05-19  6:06                 ` [PATCH v2 1/2] rcu: don't bind offline cpu KOSAKI Motohiro
2011-05-19  6:08                   ` [PATCH v2 2/2] cpuset: fix cpuset_cpus_allowed_fallback() don't update tsk->rt.nr_cpus_allowed KOSAKI Motohiro
2011-05-28 16:35                     ` [tip:sched/urgent] cpuset: Fix cpuset_cpus_allowed_fallback(), " tip-bot for KOSAKI Motohiro
2011-06-20 10:20                       ` Peter Zijlstra
2011-06-21  9:54                         ` KOSAKI Motohiro
2011-05-19  8:34                   ` [PATCH v2 1/2] rcu: don't bind offline cpu Peter Zijlstra
2011-05-19  8:50                     ` KOSAKI Motohiro
2011-05-19  9:41                       ` Peter Zijlstra
2011-05-19 10:12                         ` KOSAKI Motohiro
2011-05-19 11:41                           ` Peter Zijlstra
2011-05-20 22:46                         ` Paul E. McKenney [this message]
2011-05-19  8:55                     ` Peter Zijlstra
2011-05-02 10:56     ` [PATCH 2/2] sched, cpuset: introduce do_set_cpus_allowed() helper function KOSAKI Motohiro
2011-05-02 12:58     ` [RFC PATCH] cpuset: fix cpuset_cpus_allowed_fallback() don't update tsk->rt.nr_cpus_allowed 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=20110520224653.GM2366@linux.vnet.ibm.com \
    --to=paulmck@linux.vnet.ibm.com \
    --cc=a.p.zijlstra@chello.nl \
    --cc=akpm@linux-foundation.org \
    --cc=kosaki.motohiro@jp.fujitsu.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lizf@cn.fujitsu.com \
    --cc=miaox@cn.fujitsu.com \
    --cc=mingo@elte.hu \
    --cc=oleg@redhat.com \
    --cc=yong.zhang0@gmail.com \
    /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.