aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/rcu/tree.h
diff options
context:
space:
mode:
authorPaul Gortmaker <paul.gortmaker@windriver.com>2016-02-19 03:46:41 -0500
committerThomas Gleixner <tglx@linutronix.de>2016-02-25 05:27:16 -0500
commitabedf8e2419fb873d919dd74de2e84b510259339 (patch)
treef3844e71c29bef8dbb9031171c26574cb9087769 /kernel/rcu/tree.h
parent065bb78c5b09df54d1c32e03227deb777ddff57b (diff)
rcu: Use simple wait queues where possible in rcutree
As of commit dae6e64d2bcfd ("rcu: Introduce proper blocking to no-CBs kthreads GP waits") the RCU subsystem started making use of wait queues. Here we convert all additions of RCU wait queues to use simple wait queues, since they don't need the extra overhead of the full wait queue features. Originally this was done for RT kernels[1], since we would get things like... BUG: sleeping function called from invalid context at kernel/rtmutex.c:659 in_atomic(): 1, irqs_disabled(): 1, pid: 8, name: rcu_preempt Pid: 8, comm: rcu_preempt Not tainted Call Trace: [<ffffffff8106c8d0>] __might_sleep+0xd0/0xf0 [<ffffffff817d77b4>] rt_spin_lock+0x24/0x50 [<ffffffff8106fcf6>] __wake_up+0x36/0x70 [<ffffffff810c4542>] rcu_gp_kthread+0x4d2/0x680 [<ffffffff8105f910>] ? __init_waitqueue_head+0x50/0x50 [<ffffffff810c4070>] ? rcu_gp_fqs+0x80/0x80 [<ffffffff8105eabb>] kthread+0xdb/0xe0 [<ffffffff8106b912>] ? finish_task_switch+0x52/0x100 [<ffffffff817e0754>] kernel_thread_helper+0x4/0x10 [<ffffffff8105e9e0>] ? __init_kthread_worker+0x60/0x60 [<ffffffff817e0750>] ? gs_change+0xb/0xb ...and hence simple wait queues were deployed on RT out of necessity (as simple wait uses a raw lock), but mainline might as well take advantage of the more streamline support as well. [1] This is a carry forward of work from v3.10-rt; the original conversion was by Thomas on an earlier -rt version, and Sebastian extended it to additional post-3.10 added RCU waiters; here I've added a commit log and unified the RCU changes into one, and uprev'd it to match mainline RCU. Signed-off-by: Daniel Wagner <daniel.wagner@bmw-carit.de> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: linux-rt-users@vger.kernel.org Cc: Boqun Feng <boqun.feng@gmail.com> Cc: Marcelo Tosatti <mtosatti@redhat.com> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Paul Gortmaker <paul.gortmaker@windriver.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> Link: http://lkml.kernel.org/r/1455871601-27484-6-git-send-email-wagi@monom.org Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel/rcu/tree.h')
-rw-r--r--kernel/rcu/tree.h13
1 files changed, 7 insertions, 6 deletions
diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h
index 10dedfbef09d..bbd235d0e71f 100644
--- a/kernel/rcu/tree.h
+++ b/kernel/rcu/tree.h
@@ -27,6 +27,7 @@
27#include <linux/threads.h> 27#include <linux/threads.h>
28#include <linux/cpumask.h> 28#include <linux/cpumask.h>
29#include <linux/seqlock.h> 29#include <linux/seqlock.h>
30#include <linux/swait.h>
30#include <linux/stop_machine.h> 31#include <linux/stop_machine.h>
31 32
32/* 33/*
@@ -243,7 +244,7 @@ struct rcu_node {
243 /* Refused to boost: not sure why, though. */ 244 /* Refused to boost: not sure why, though. */
244 /* This can happen due to race conditions. */ 245 /* This can happen due to race conditions. */
245#ifdef CONFIG_RCU_NOCB_CPU 246#ifdef CONFIG_RCU_NOCB_CPU
246 wait_queue_head_t nocb_gp_wq[2]; 247 struct swait_queue_head nocb_gp_wq[2];
247 /* Place for rcu_nocb_kthread() to wait GP. */ 248 /* Place for rcu_nocb_kthread() to wait GP. */
248#endif /* #ifdef CONFIG_RCU_NOCB_CPU */ 249#endif /* #ifdef CONFIG_RCU_NOCB_CPU */
249 int need_future_gp[2]; 250 int need_future_gp[2];
@@ -399,7 +400,7 @@ struct rcu_data {
399 atomic_long_t nocb_q_count_lazy; /* invocation (all stages). */ 400 atomic_long_t nocb_q_count_lazy; /* invocation (all stages). */
400 struct rcu_head *nocb_follower_head; /* CBs ready to invoke. */ 401 struct rcu_head *nocb_follower_head; /* CBs ready to invoke. */
401 struct rcu_head **nocb_follower_tail; 402 struct rcu_head **nocb_follower_tail;
402 wait_queue_head_t nocb_wq; /* For nocb kthreads to sleep on. */ 403 struct swait_queue_head nocb_wq; /* For nocb kthreads to sleep on. */
403 struct task_struct *nocb_kthread; 404 struct task_struct *nocb_kthread;
404 int nocb_defer_wakeup; /* Defer wakeup of nocb_kthread. */ 405 int nocb_defer_wakeup; /* Defer wakeup of nocb_kthread. */
405 406
@@ -478,7 +479,7 @@ struct rcu_state {
478 unsigned long gpnum; /* Current gp number. */ 479 unsigned long gpnum; /* Current gp number. */
479 unsigned long completed; /* # of last completed gp. */ 480 unsigned long completed; /* # of last completed gp. */
480 struct task_struct *gp_kthread; /* Task for grace periods. */ 481 struct task_struct *gp_kthread; /* Task for grace periods. */
481 wait_queue_head_t gp_wq; /* Where GP task waits. */ 482 struct swait_queue_head gp_wq; /* Where GP task waits. */
482 short gp_flags; /* Commands for GP task. */ 483 short gp_flags; /* Commands for GP task. */
483 short gp_state; /* GP kthread sleep state. */ 484 short gp_state; /* GP kthread sleep state. */
484 485
@@ -506,7 +507,7 @@ struct rcu_state {
506 unsigned long expedited_sequence; /* Take a ticket. */ 507 unsigned long expedited_sequence; /* Take a ticket. */
507 atomic_long_t expedited_normal; /* # fallbacks to normal. */ 508 atomic_long_t expedited_normal; /* # fallbacks to normal. */
508 atomic_t expedited_need_qs; /* # CPUs left to check in. */ 509 atomic_t expedited_need_qs; /* # CPUs left to check in. */
509 wait_queue_head_t expedited_wq; /* Wait for check-ins. */ 510 struct swait_queue_head expedited_wq; /* Wait for check-ins. */
510 int ncpus_snap; /* # CPUs seen last time. */ 511 int ncpus_snap; /* # CPUs seen last time. */
511 512
512 unsigned long jiffies_force_qs; /* Time at which to invoke */ 513 unsigned long jiffies_force_qs; /* Time at which to invoke */
@@ -621,8 +622,8 @@ static void zero_cpu_stall_ticks(struct rcu_data *rdp);
621static void increment_cpu_stall_ticks(void); 622static void increment_cpu_stall_ticks(void);
622static bool rcu_nocb_cpu_needs_barrier(struct rcu_state *rsp, int cpu); 623static bool rcu_nocb_cpu_needs_barrier(struct rcu_state *rsp, int cpu);
623static void rcu_nocb_gp_set(struct rcu_node *rnp, int nrq); 624static void rcu_nocb_gp_set(struct rcu_node *rnp, int nrq);
624static wait_queue_head_t *rcu_nocb_gp_get(struct rcu_node *rnp); 625static struct swait_queue_head *rcu_nocb_gp_get(struct rcu_node *rnp);
625static void rcu_nocb_gp_cleanup(wait_queue_head_t *sq); 626static void rcu_nocb_gp_cleanup(struct swait_queue_head *sq);
626static void rcu_init_one_nocb(struct rcu_node *rnp); 627static void rcu_init_one_nocb(struct rcu_node *rnp);
627static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp, 628static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp,
628 bool lazy, unsigned long flags); 629 bool lazy, unsigned long flags);