mirror of https://lore.kernel.org/lkml/
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome