aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/rcu
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2014-08-05 08:10:24 -0400
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2014-09-07 19:27:31 -0400
commit8f20a5e83d2c5d0e126a2fc9bca67f7430dac907 (patch)
tree48333b2fd0773d384e5e907401812645fc9575b2 /kernel/rcu
parent176f8f7a52cc6d09d686f0d900abda6942a52fbb (diff)
rcu: Make rcu_tasks_kthread()'s GP-wait loop allow preemption
The grace-period-wait loop in rcu_tasks_kthread() is under (unnecessary) RCU protection, and therefore has no preemption points in a PREEMPT=n kernel. This commit therefore removes the RCU protection and inserts cond_resched(). Reported-by: Frederic Weisbecker <fweisbec@gmail.com> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Diffstat (limited to 'kernel/rcu')
-rw-r--r--kernel/rcu/update.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c
index 2658de4a5975..f86d1ae50005 100644
--- a/kernel/rcu/update.c
+++ b/kernel/rcu/update.c
@@ -467,7 +467,7 @@ static void check_holdout_task(struct task_struct *t,
467 (IS_ENABLED(CONFIG_NO_HZ_FULL) && 467 (IS_ENABLED(CONFIG_NO_HZ_FULL) &&
468 !is_idle_task(t) && t->rcu_tasks_idle_cpu >= 0)) { 468 !is_idle_task(t) && t->rcu_tasks_idle_cpu >= 0)) {
469 ACCESS_ONCE(t->rcu_tasks_holdout) = false; 469 ACCESS_ONCE(t->rcu_tasks_holdout) = false;
470 list_del_rcu(&t->rcu_tasks_holdout_list); 470 list_del_init(&t->rcu_tasks_holdout_list);
471 put_task_struct(t); 471 put_task_struct(t);
472 return; 472 return;
473 } 473 }
@@ -573,6 +573,7 @@ static int __noreturn rcu_tasks_kthread(void *arg)
573 bool firstreport; 573 bool firstreport;
574 bool needreport; 574 bool needreport;
575 int rtst; 575 int rtst;
576 struct task_struct *t1;
576 577
577 schedule_timeout_interruptible(HZ); 578 schedule_timeout_interruptible(HZ);
578 rtst = ACCESS_ONCE(rcu_task_stall_timeout); 579 rtst = ACCESS_ONCE(rcu_task_stall_timeout);
@@ -582,11 +583,11 @@ static int __noreturn rcu_tasks_kthread(void *arg)
582 lastreport = jiffies; 583 lastreport = jiffies;
583 firstreport = true; 584 firstreport = true;
584 WARN_ON(signal_pending(current)); 585 WARN_ON(signal_pending(current));
585 rcu_read_lock(); 586 list_for_each_entry_safe(t, t1, &rcu_tasks_holdouts,
586 list_for_each_entry_rcu(t, &rcu_tasks_holdouts, 587 rcu_tasks_holdout_list) {
587 rcu_tasks_holdout_list)
588 check_holdout_task(t, needreport, &firstreport); 588 check_holdout_task(t, needreport, &firstreport);
589 rcu_read_unlock(); 589 cond_resched();
590 }
590 } 591 }
591 592
592 /* 593 /*