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: Paul E. McKenney <paulmck@kernel.org>
This commit is contained in:
parent
e4fe5dd6f2
commit
d01aa2633b
|
@ -211,6 +211,69 @@ static void __init rcu_tasks_bootup_oddness(void)
|
||||||
|
|
||||||
#ifdef CONFIG_TASKS_RCU
|
#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
|
// Simple variant of RCU whose quiescent states are voluntary context
|
||||||
|
@ -333,65 +396,6 @@ static void rcu_tasks_postgp(void)
|
||||||
synchronize_rcu();
|
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);
|
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");
|
DEFINE_RCU_TASKS(rcu_tasks, rcu_tasks_wait_gp, call_rcu_tasks, "RCU Tasks");
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue