Skip to content

Commit e7539ff

Browse files
Frederic Weisbeckerfbq
authored andcommitted
rcu/exp: Handle RCU expedited grace period kworker allocation failure
Just like is done for the kworker performing nodes initialization, gracefully handle the possible allocation failure of the RCU expedited grace period main kworker. While at it perform a rename of the related checking functions to better reflect the expedited specifics. Reviewed-by: Kalesh Singh <kaleshsingh@google.com> Fixes: 9621fbe ("rcu: Move expedited grace period (GP) work to RT kthread_worker") Signed-off-by: Frederic Weisbecker <frederic@kernel.org> Reviewed-by: Paul E. McKenney <paulmck@kernel.org> Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
1 parent a636c5e commit e7539ff

File tree

2 files changed

+21
-6
lines changed

2 files changed

+21
-6
lines changed

kernel/rcu/tree.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4743,6 +4743,7 @@ static void __init rcu_start_exp_gp_kworkers(void)
47434743
rcu_exp_gp_kworker = kthread_create_worker(0, gp_kworker_name);
47444744
if (IS_ERR_OR_NULL(rcu_exp_gp_kworker)) {
47454745
pr_err("Failed to create %s!\n", gp_kworker_name);
4746+
rcu_exp_gp_kworker = NULL;
47464747
return;
47474748
}
47484749

@@ -4751,6 +4752,7 @@ static void __init rcu_start_exp_gp_kworkers(void)
47514752
pr_err("Failed to create %s!\n", par_gp_kworker_name);
47524753
rcu_exp_par_gp_kworker = NULL;
47534754
kthread_destroy_worker(rcu_exp_gp_kworker);
4755+
rcu_exp_gp_kworker = NULL;
47544756
return;
47554757
}
47564758

kernel/rcu/tree_exp.h

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,12 @@ static void sync_rcu_exp_select_node_cpus(struct kthread_work *wp)
427427
__sync_rcu_exp_select_node_cpus(rewp);
428428
}
429429

430-
static inline bool rcu_gp_par_worker_started(void)
430+
static inline bool rcu_exp_worker_started(void)
431+
{
432+
return !!READ_ONCE(rcu_exp_gp_kworker);
433+
}
434+
435+
static inline bool rcu_exp_par_worker_started(void)
431436
{
432437
return !!READ_ONCE(rcu_exp_par_gp_kworker);
433438
}
@@ -477,7 +482,12 @@ static void sync_rcu_exp_select_node_cpus(struct work_struct *wp)
477482
__sync_rcu_exp_select_node_cpus(rewp);
478483
}
479484

480-
static inline bool rcu_gp_par_worker_started(void)
485+
static inline bool rcu_exp_worker_started(void)
486+
{
487+
return !!READ_ONCE(rcu_gp_wq);
488+
}
489+
490+
static inline bool rcu_exp_par_worker_started(void)
481491
{
482492
return !!READ_ONCE(rcu_par_gp_wq);
483493
}
@@ -540,7 +550,7 @@ static void sync_rcu_exp_select_cpus(void)
540550
rnp->exp_need_flush = false;
541551
if (!READ_ONCE(rnp->expmask))
542552
continue; /* Avoid early boot non-existent wq. */
543-
if (!rcu_gp_par_worker_started() ||
553+
if (!rcu_exp_par_worker_started() ||
544554
rcu_scheduler_active != RCU_SCHEDULER_RUNNING ||
545555
rcu_is_last_leaf_node(rnp)) {
546556
/* No worker started yet or last leaf, do direct call. */
@@ -955,7 +965,7 @@ static void rcu_exp_print_detail_task_stall_rnp(struct rcu_node *rnp)
955965
*/
956966
void synchronize_rcu_expedited(void)
957967
{
958-
bool boottime = (rcu_scheduler_active == RCU_SCHEDULER_INIT);
968+
bool use_worker;
959969
unsigned long flags;
960970
struct rcu_exp_work rew;
961971
struct rcu_node *rnp;
@@ -966,6 +976,9 @@ void synchronize_rcu_expedited(void)
966976
lock_is_held(&rcu_sched_lock_map),
967977
"Illegal synchronize_rcu_expedited() in RCU read-side critical section");
968978

979+
use_worker = (rcu_scheduler_active != RCU_SCHEDULER_INIT) &&
980+
rcu_exp_worker_started();
981+
969982
/* Is the state is such that the call is a grace period? */
970983
if (rcu_blocking_is_gp()) {
971984
// Note well that this code runs with !PREEMPT && !SMP.
@@ -995,7 +1008,7 @@ void synchronize_rcu_expedited(void)
9951008
return; /* Someone else did our work for us. */
9961009

9971010
/* Ensure that load happens before action based on it. */
998-
if (unlikely(boottime)) {
1011+
if (unlikely(!use_worker)) {
9991012
/* Direct call during scheduler init and early_initcalls(). */
10001013
rcu_exp_sel_wait_wake(s);
10011014
} else {
@@ -1013,7 +1026,7 @@ void synchronize_rcu_expedited(void)
10131026
/* Let the next expedited grace period start. */
10141027
mutex_unlock(&rcu_state.exp_mutex);
10151028

1016-
if (likely(!boottime))
1029+
if (likely(use_worker))
10171030
synchronize_rcu_expedited_destroy_work(&rew);
10181031
}
10191032
EXPORT_SYMBOL_GPL(synchronize_rcu_expedited);

0 commit comments

Comments
 (0)