Commit 57f60202 authored by Paul E. McKenney's avatar Paul E. McKenney

rcutorture: Properly synchronize with OOM notifier

The current rcutorture forward-progress code assumes that it is the
only cause of out-of-memory (OOM) events.  For script-based rcutorture
testing, this assumption is in fact correct.  However, testing based
on modprobe/rmmod might well encounter external OOM events, which could
happen at any time.

This commit therefore properly synchronizes the interaction between
rcutorture's forward-progress testing and its OOM notifier by adding a
global mutex.
Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
parent c8fa6371
...@@ -1796,6 +1796,7 @@ struct rcu_fwd { ...@@ -1796,6 +1796,7 @@ struct rcu_fwd {
unsigned long rcu_launder_gp_seq_start; unsigned long rcu_launder_gp_seq_start;
}; };
static DEFINE_MUTEX(rcu_fwd_mutex);
static struct rcu_fwd *rcu_fwds; static struct rcu_fwd *rcu_fwds;
static bool rcu_fwd_emergency_stop; static bool rcu_fwd_emergency_stop;
...@@ -2062,8 +2063,14 @@ static void rcu_torture_fwd_prog_cr(struct rcu_fwd *rfp) ...@@ -2062,8 +2063,14 @@ static void rcu_torture_fwd_prog_cr(struct rcu_fwd *rfp)
static int rcutorture_oom_notify(struct notifier_block *self, static int rcutorture_oom_notify(struct notifier_block *self,
unsigned long notused, void *nfreed) unsigned long notused, void *nfreed)
{ {
struct rcu_fwd *rfp = rcu_fwds; struct rcu_fwd *rfp;
mutex_lock(&rcu_fwd_mutex);
rfp = rcu_fwds;
if (!rfp) {
mutex_unlock(&rcu_fwd_mutex);
return NOTIFY_OK;
}
WARN(1, "%s invoked upon OOM during forward-progress testing.\n", WARN(1, "%s invoked upon OOM during forward-progress testing.\n",
__func__); __func__);
rcu_torture_fwd_cb_hist(rfp); rcu_torture_fwd_cb_hist(rfp);
...@@ -2081,6 +2088,7 @@ static int rcutorture_oom_notify(struct notifier_block *self, ...@@ -2081,6 +2088,7 @@ static int rcutorture_oom_notify(struct notifier_block *self,
smp_mb(); /* Frees before return to avoid redoing OOM. */ smp_mb(); /* Frees before return to avoid redoing OOM. */
(*(unsigned long *)nfreed)++; /* Forward progress CBs freed! */ (*(unsigned long *)nfreed)++; /* Forward progress CBs freed! */
pr_info("%s returning after OOM processing.\n", __func__); pr_info("%s returning after OOM processing.\n", __func__);
mutex_unlock(&rcu_fwd_mutex);
return NOTIFY_OK; return NOTIFY_OK;
} }
...@@ -2148,7 +2156,9 @@ static int __init rcu_torture_fwd_prog_init(void) ...@@ -2148,7 +2156,9 @@ static int __init rcu_torture_fwd_prog_init(void)
return -ENOMEM; return -ENOMEM;
spin_lock_init(&rfp->rcu_fwd_lock); spin_lock_init(&rfp->rcu_fwd_lock);
rfp->rcu_fwd_cb_tail = &rfp->rcu_fwd_cb_head; rfp->rcu_fwd_cb_tail = &rfp->rcu_fwd_cb_head;
mutex_lock(&rcu_fwd_mutex);
rcu_fwds = rfp; rcu_fwds = rfp;
mutex_unlock(&rcu_fwd_mutex);
return torture_create_kthread(rcu_torture_fwd_prog, rfp, fwd_prog_task); return torture_create_kthread(rcu_torture_fwd_prog, rfp, fwd_prog_task);
} }
...@@ -2158,7 +2168,9 @@ static void rcu_torture_fwd_prog_cleanup(void) ...@@ -2158,7 +2168,9 @@ static void rcu_torture_fwd_prog_cleanup(void)
torture_stop_kthread(rcu_torture_fwd_prog, fwd_prog_task); torture_stop_kthread(rcu_torture_fwd_prog, fwd_prog_task);
rfp = rcu_fwds; rfp = rcu_fwds;
mutex_lock(&rcu_fwd_mutex);
rcu_fwds = NULL; rcu_fwds = NULL;
mutex_unlock(&rcu_fwd_mutex);
kfree(rfp); kfree(rfp);
} }
......
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