Skip to content

Commit 18f08e7

Browse files
committed
rcu-tasks: Add trc_inspect_reader() checks for exiting critical section
Currently, trc_inspect_reader() treats a task exiting its RCU Tasks Trace read-side critical section the same as being within that critical section. However, this can fail because that task might have already checked its .need_qs field, which means that it might never decrement the all-important trc_n_readers_need_end counter. Of course, for that to happen, the task would need to never again execute an RCU Tasks Trace read-side critical section, but this really could happen if the system's last trampoline was removed. Note that exit from such a critical section cannot be treated as a quiescent state due to the possibility of nested critical sections. This means that if trc_inspect_reader() sees a negative nesting value, it must set up to try again later. This commit therefore ignores tasks that are exiting their RCU Tasks Trace read-side critical sections so that they will be rechecked later. [ paulmck: Apply feedback from Neeraj Upadhyay and Boqun Feng. ] Signed-off-by: Paul E. McKenney <[email protected]>
1 parent 96017bf commit 18f08e7

File tree

1 file changed

+9
-9
lines changed

1 file changed

+9
-9
lines changed

kernel/rcu/tasks.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -923,7 +923,7 @@ static void trc_read_check_handler(void *t_in)
923923
static bool trc_inspect_reader(struct task_struct *t, void *arg)
924924
{
925925
int cpu = task_cpu(t);
926-
bool in_qs = false;
926+
int nesting;
927927
bool ofl = cpu_is_offline(cpu);
928928

929929
if (task_curr(t)) {
@@ -943,18 +943,18 @@ static bool trc_inspect_reader(struct task_struct *t, void *arg)
943943
n_heavy_reader_updates++;
944944
if (ofl)
945945
n_heavy_reader_ofl_updates++;
946-
in_qs = true;
946+
nesting = 0;
947947
} else {
948948
// The task is not running, so C-language access is safe.
949-
in_qs = likely(!t->trc_reader_nesting);
949+
nesting = t->trc_reader_nesting;
950950
}
951951

952-
// Mark as checked so that the grace-period kthread will
953-
// remove it from the holdout list.
954-
t->trc_reader_checked = true;
955-
956-
if (in_qs)
957-
return true; // Already in quiescent state, done!!!
952+
// If not exiting a read-side critical section, mark as checked
953+
// so that the grace-period kthread will remove it from the
954+
// holdout list.
955+
t->trc_reader_checked = nesting >= 0;
956+
if (nesting <= 0)
957+
return !nesting; // If in QS, done, otherwise try again later.
958958

959959
// The task is in a read-side critical section, so set up its
960960
// state so that it will awaken the grace-period kthread upon exit

0 commit comments

Comments
 (0)