Loading kernel/rcu/tasks.h +63 −59 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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"); Loading Loading
kernel/rcu/tasks.h +63 −59 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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"); Loading