提交 0f11ad32 编写于 作者: P Paul E. McKenney

rcu: Mark rcu_state.gp_seq to detect concurrent writes

The rcu_state structure's gp_seq field is only to be modified by the RCU
grace-period kthread, which is single-threaded.  This commit therefore
enlists KCSAN's help in enforcing this restriction.
Signed-off-by: NPaul E. McKenney <paulmck@kernel.org>
上级 3d05031a
...@@ -1209,7 +1209,7 @@ static bool rcu_start_this_gp(struct rcu_node *rnp_start, struct rcu_data *rdp, ...@@ -1209,7 +1209,7 @@ static bool rcu_start_this_gp(struct rcu_node *rnp_start, struct rcu_data *rdp,
trace_rcu_this_gp(rnp, rdp, gp_seq_req, TPS("NoGPkthread")); trace_rcu_this_gp(rnp, rdp, gp_seq_req, TPS("NoGPkthread"));
goto unlock_out; goto unlock_out;
} }
trace_rcu_grace_period(rcu_state.name, READ_ONCE(rcu_state.gp_seq), TPS("newreq")); trace_rcu_grace_period(rcu_state.name, rcu_state.gp_seq, TPS("newreq"));
ret = true; /* Caller must wake GP kthread. */ ret = true; /* Caller must wake GP kthread. */
unlock_out: unlock_out:
/* Push furthest requested GP to leaf node and rcu_data structure. */ /* Push furthest requested GP to leaf node and rcu_data structure. */
...@@ -1657,8 +1657,7 @@ static void rcu_gp_fqs_loop(void) ...@@ -1657,8 +1657,7 @@ static void rcu_gp_fqs_loop(void)
WRITE_ONCE(rcu_state.jiffies_kick_kthreads, WRITE_ONCE(rcu_state.jiffies_kick_kthreads,
jiffies + (j ? 3 * j : 2)); jiffies + (j ? 3 * j : 2));
} }
trace_rcu_grace_period(rcu_state.name, trace_rcu_grace_period(rcu_state.name, rcu_state.gp_seq,
READ_ONCE(rcu_state.gp_seq),
TPS("fqswait")); TPS("fqswait"));
rcu_state.gp_state = RCU_GP_WAIT_FQS; rcu_state.gp_state = RCU_GP_WAIT_FQS;
ret = swait_event_idle_timeout_exclusive( ret = swait_event_idle_timeout_exclusive(
...@@ -1672,13 +1671,11 @@ static void rcu_gp_fqs_loop(void) ...@@ -1672,13 +1671,11 @@ static void rcu_gp_fqs_loop(void)
/* If time for quiescent-state forcing, do it. */ /* If time for quiescent-state forcing, do it. */
if (ULONG_CMP_GE(jiffies, rcu_state.jiffies_force_qs) || if (ULONG_CMP_GE(jiffies, rcu_state.jiffies_force_qs) ||
(gf & RCU_GP_FLAG_FQS)) { (gf & RCU_GP_FLAG_FQS)) {
trace_rcu_grace_period(rcu_state.name, trace_rcu_grace_period(rcu_state.name, rcu_state.gp_seq,
READ_ONCE(rcu_state.gp_seq),
TPS("fqsstart")); TPS("fqsstart"));
rcu_gp_fqs(first_gp_fqs); rcu_gp_fqs(first_gp_fqs);
first_gp_fqs = false; first_gp_fqs = false;
trace_rcu_grace_period(rcu_state.name, trace_rcu_grace_period(rcu_state.name, rcu_state.gp_seq,
READ_ONCE(rcu_state.gp_seq),
TPS("fqsend")); TPS("fqsend"));
cond_resched_tasks_rcu_qs(); cond_resched_tasks_rcu_qs();
WRITE_ONCE(rcu_state.gp_activity, jiffies); WRITE_ONCE(rcu_state.gp_activity, jiffies);
...@@ -1689,8 +1686,7 @@ static void rcu_gp_fqs_loop(void) ...@@ -1689,8 +1686,7 @@ static void rcu_gp_fqs_loop(void)
cond_resched_tasks_rcu_qs(); cond_resched_tasks_rcu_qs();
WRITE_ONCE(rcu_state.gp_activity, jiffies); WRITE_ONCE(rcu_state.gp_activity, jiffies);
WARN_ON(signal_pending(current)); WARN_ON(signal_pending(current));
trace_rcu_grace_period(rcu_state.name, trace_rcu_grace_period(rcu_state.name, rcu_state.gp_seq,
READ_ONCE(rcu_state.gp_seq),
TPS("fqswaitsig")); TPS("fqswaitsig"));
ret = 1; /* Keep old FQS timing. */ ret = 1; /* Keep old FQS timing. */
j = jiffies; j = jiffies;
...@@ -1782,7 +1778,7 @@ static void rcu_gp_cleanup(void) ...@@ -1782,7 +1778,7 @@ static void rcu_gp_cleanup(void)
WRITE_ONCE(rcu_state.gp_flags, RCU_GP_FLAG_INIT); WRITE_ONCE(rcu_state.gp_flags, RCU_GP_FLAG_INIT);
WRITE_ONCE(rcu_state.gp_req_activity, jiffies); WRITE_ONCE(rcu_state.gp_req_activity, jiffies);
trace_rcu_grace_period(rcu_state.name, trace_rcu_grace_period(rcu_state.name,
READ_ONCE(rcu_state.gp_seq), rcu_state.gp_seq,
TPS("newreq")); TPS("newreq"));
} else { } else {
WRITE_ONCE(rcu_state.gp_flags, WRITE_ONCE(rcu_state.gp_flags,
...@@ -1801,8 +1797,7 @@ static int __noreturn rcu_gp_kthread(void *unused) ...@@ -1801,8 +1797,7 @@ static int __noreturn rcu_gp_kthread(void *unused)
/* Handle grace-period start. */ /* Handle grace-period start. */
for (;;) { for (;;) {
trace_rcu_grace_period(rcu_state.name, trace_rcu_grace_period(rcu_state.name, rcu_state.gp_seq,
READ_ONCE(rcu_state.gp_seq),
TPS("reqwait")); TPS("reqwait"));
rcu_state.gp_state = RCU_GP_WAIT_GPS; rcu_state.gp_state = RCU_GP_WAIT_GPS;
swait_event_idle_exclusive(rcu_state.gp_wq, swait_event_idle_exclusive(rcu_state.gp_wq,
...@@ -1815,8 +1810,7 @@ static int __noreturn rcu_gp_kthread(void *unused) ...@@ -1815,8 +1810,7 @@ static int __noreturn rcu_gp_kthread(void *unused)
cond_resched_tasks_rcu_qs(); cond_resched_tasks_rcu_qs();
WRITE_ONCE(rcu_state.gp_activity, jiffies); WRITE_ONCE(rcu_state.gp_activity, jiffies);
WARN_ON(signal_pending(current)); WARN_ON(signal_pending(current));
trace_rcu_grace_period(rcu_state.name, trace_rcu_grace_period(rcu_state.name, rcu_state.gp_seq,
READ_ONCE(rcu_state.gp_seq),
TPS("reqwaitsig")); TPS("reqwaitsig"));
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册