Skip to content

Commit fcb7381

Browse files
committed
rcu-tasks: *_ONCE() for rcu_tasks_cbs_head
The RCU tasks list of callbacks, rcu_tasks_cbs_head, is sampled locklessly by rcu_tasks_kthread() when waiting for work to do. This commit therefore applies READ_ONCE() to that lockless sampling and WRITE_ONCE() to the single potential store outside of rcu_tasks_kthread. This data race was reported by KCSAN. Not appropriate for backporting due to failure being unlikely. Signed-off-by: Paul E. McKenney <[email protected]>
1 parent bb6d3fb commit fcb7381

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

kernel/rcu/update.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ void call_rcu_tasks(struct rcu_head *rhp, rcu_callback_t func)
528528
rhp->func = func;
529529
raw_spin_lock_irqsave(&rcu_tasks_cbs_lock, flags);
530530
needwake = !rcu_tasks_cbs_head;
531-
*rcu_tasks_cbs_tail = rhp;
531+
WRITE_ONCE(*rcu_tasks_cbs_tail, rhp);
532532
rcu_tasks_cbs_tail = &rhp->next;
533533
raw_spin_unlock_irqrestore(&rcu_tasks_cbs_lock, flags);
534534
/* We can't create the thread unless interrupts are enabled. */
@@ -658,7 +658,7 @@ static int __noreturn rcu_tasks_kthread(void *arg)
658658
/* If there were none, wait a bit and start over. */
659659
if (!list) {
660660
wait_event_interruptible(rcu_tasks_cbs_wq,
661-
rcu_tasks_cbs_head);
661+
READ_ONCE(rcu_tasks_cbs_head));
662662
if (!rcu_tasks_cbs_head) {
663663
WARN_ON(signal_pending(current));
664664
schedule_timeout_interruptible(HZ/10);

0 commit comments

Comments
 (0)