Commit d01aa263 authored by Paul E. McKenney's avatar Paul E. McKenney

rcu-tasks: Code movement to allow more Tasks RCU variants

This commit does nothing but move rcu_tasks_wait_gp() up to a new section
for common code.
Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
parent e4fe5dd6
......@@ -211,6 +211,69 @@ static void __init rcu_tasks_bootup_oddness(void)
#ifdef CONFIG_TASKS_RCU
////////////////////////////////////////////////////////////////////////
//
// Shared code between task-list-scanning variants of Tasks RCU.
/* Wait for one RCU-tasks grace period. */
static void rcu_tasks_wait_gp(struct rcu_tasks *rtp)
{
struct task_struct *g, *t;
unsigned long lastreport;
LIST_HEAD(holdouts);
int fract;
rtp->pregp_func();
/*
* There were callbacks, so we need to wait for an RCU-tasks
* grace period. Start off by scanning the task list for tasks
* that are not already voluntarily blocked. Mark these tasks
* and make a list of them in holdouts.
*/
rcu_read_lock();
for_each_process_thread(g, t)
rtp->pertask_func(t, &holdouts);
rcu_read_unlock();
rtp->postscan_func();
/*
* Each pass through the following loop scans the list of holdout
* tasks, removing any that are no longer holdouts. When the list
* is empty, we are done.
*/
lastreport = jiffies;
/* Start off with HZ/10 wait and slowly back off to 1 HZ wait. */
fract = 10;
for (;;) {
bool firstreport;
bool needreport;
int rtst;
if (list_empty(&holdouts))
break;
/* Slowly back off waiting for holdouts */
schedule_timeout_interruptible(HZ/fract);
if (fract > 1)
fract--;
rtst = READ_ONCE(rcu_task_stall_timeout);
needreport = rtst > 0 && time_after(jiffies, lastreport + rtst);
if (needreport)
lastreport = jiffies;
firstreport = true;
WARN_ON(signal_pending(current));
rtp->holdouts_func(&holdouts, needreport, &firstreport);
}
rtp->postgp_func();
}
////////////////////////////////////////////////////////////////////////
//
// Simple variant of RCU whose quiescent states are voluntary context
......@@ -333,65 +396,6 @@ static void rcu_tasks_postgp(void)
synchronize_rcu();
}
/* Wait for one RCU-tasks grace period. */
static void rcu_tasks_wait_gp(struct rcu_tasks *rtp)
{
struct task_struct *g, *t;
unsigned long lastreport;
LIST_HEAD(holdouts);
int fract;
rtp->pregp_func();
/*
* There were callbacks, so we need to wait for an RCU-tasks
* grace period. Start off by scanning the task list for tasks
* that are not already voluntarily blocked. Mark these tasks
* and make a list of them in holdouts.
*/
rcu_read_lock();
for_each_process_thread(g, t)
rtp->pertask_func(t, &holdouts);
rcu_read_unlock();
rtp->postscan_func();
/*
* Each pass through the following loop scans the list of holdout
* tasks, removing any that are no longer holdouts. When the list
* is empty, we are done.
*/
lastreport = jiffies;
/* Start off with HZ/10 wait and slowly back off to 1 HZ wait. */
fract = 10;
for (;;) {
bool firstreport;
bool needreport;
int rtst;
if (list_empty(&holdouts))
break;
/* Slowly back off waiting for holdouts */
schedule_timeout_interruptible(HZ/fract);
if (fract > 1)
fract--;
rtst = READ_ONCE(rcu_task_stall_timeout);
needreport = rtst > 0 && time_after(jiffies, lastreport + rtst);
if (needreport)
lastreport = jiffies;
firstreport = true;
WARN_ON(signal_pending(current));
rtp->holdouts_func(&holdouts, needreport, &firstreport);
}
rtp->postgp_func();
}
void call_rcu_tasks(struct rcu_head *rhp, rcu_callback_t func);
DEFINE_RCU_TASKS(rcu_tasks, rcu_tasks_wait_gp, call_rcu_tasks, "RCU Tasks");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment