lkml.org 
[lkml]   [2022]   [Nov]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 1/3] rcu-tasks: Improve comments explaining tasks_rcu_exit_srcu purpose
    Date
    Make sure we don't need to look again into the depths of git blame in
    order not to miss a subtle part about how rcu-tasks is dealing with
    exiting tasks.

    Suggested-by: Boqun Feng <boqun.feng@gmail.com>
    Suggested-by: Neeraj Upadhyay <quic_neeraju@quicinc.com>
    Suggested-by: Paul E. McKenney <paulmck@kernel.org>
    Cc: Oleg Nesterov <oleg@redhat.com>
    Cc: Lai Jiangshan <jiangshanlai@gmail.com>
    Cc: Eric W. Biederman <ebiederm@xmission.com>
    Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
    ---
    kernel/rcu/tasks.h | 37 +++++++++++++++++++++++++++++--------
    1 file changed, 29 insertions(+), 8 deletions(-)

    diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h
    index 4a991311be9b..7deed6135f73 100644
    --- a/kernel/rcu/tasks.h
    +++ b/kernel/rcu/tasks.h
    @@ -827,11 +827,21 @@ static void rcu_tasks_pertask(struct task_struct *t, struct list_head *hop)
    static void rcu_tasks_postscan(struct list_head *hop)
    {
    /*
    - * Wait for tasks that are in the process of exiting. This
    - * does only part of the job, ensuring that all tasks that were
    - * previously exiting reach the point where they have disabled
    - * preemption, allowing the later synchronize_rcu() to finish
    - * the job.
    + * Exiting tasks may escape the tasklist scan. Those are vulnerable
    + * until their final schedule() with TASK_DEAD state. To cope with
    + * this, divide the fragile exit path part in two intersecting
    + * read side critical sections:
    + *
    + * 1) An _SRCU_ read side starting before calling exit_notify(),
    + * which may remove the task from the tasklist, and ending after
    + * the final preempt_disable() call in do_exit().
    + *
    + * 2) An _RCU_ read side starting with the final preempt_disable()
    + * call in do_exit() and ending with the final call to schedule()
    + * with TASK_DEAD state.
    + *
    + * This handles the part 1). And postgp will handle part 2) with a
    + * call to synchronize_rcu().
    */
    synchronize_srcu(&tasks_rcu_exit_srcu);
    }
    @@ -898,7 +908,10 @@ static void rcu_tasks_postgp(struct rcu_tasks *rtp)
    *
    * In addition, this synchronize_rcu() waits for exiting tasks
    * to complete their final preempt_disable() region of execution,
    - * cleaning up after the synchronize_srcu() above.
    + * cleaning up after synchronize_srcu(&tasks_rcu_exit_srcu),
    + * enforcing the whole region before tasklist removal until
    + * the final schedule() with TASK_DEAD state to be an RCU TASKS
    + * read side critical section.
    */
    synchronize_rcu();
    }
    @@ -988,7 +1001,11 @@ void show_rcu_tasks_classic_gp_kthread(void)
    EXPORT_SYMBOL_GPL(show_rcu_tasks_classic_gp_kthread);
    #endif // !defined(CONFIG_TINY_RCU)

    -/* Do the srcu_read_lock() for the above synchronize_srcu(). */
    +/*
    + * Contribute to protect against tasklist scan blind spot while the
    + * task is exiting and may be removed from the tasklist. See
    + * corresponding synchronize_srcu() for further details.
    + */
    void exit_tasks_rcu_start(void) __acquires(&tasks_rcu_exit_srcu)
    {
    preempt_disable();
    @@ -996,7 +1013,11 @@ void exit_tasks_rcu_start(void) __acquires(&tasks_rcu_exit_srcu)
    preempt_enable();
    }

    -/* Do the srcu_read_unlock() for the above synchronize_srcu(). */
    +/*
    + * Contribute to protect against tasklist scan blind spot while the
    + * task is exiting and may be removed from the tasklist. See
    + * corresponding synchronize_srcu() for further details.
    + */
    void exit_tasks_rcu_finish(void) __releases(&tasks_rcu_exit_srcu)
    {
    struct task_struct *t = current;
    --
    2.25.1
    \
     
     \ /
      Last update: 2022-11-25 14:55    [W:2.335 / U:0.216 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site