On Mon, Sep 02, 2019 at 11:51:34PM -0500, Eric W. Biederman wrote:
> 
> Add a count of the number of rcu users (currently 1) of the task
> struct so that we can later add the scheduler case and get rid of the
> very subtle task_rcu_dereference, and just use rcu_dereference.
> 
> As suggested by Oleg have the count overlap rcu_head so that no
> additional space in task_struct is required.
> 
> Inspired-by: Linus Torvalds <torva...@linux-foundation.org>
> Inspired-by: Oleg Nesterov <o...@redhat.com>
> Signed-off-by: "Eric W. Biederman" <ebied...@xmission.com>
> ---
>  include/linux/sched.h      | 5 ++++-
>  include/linux/sched/task.h | 1 +
>  kernel/exit.c              | 7 ++++++-
>  kernel/fork.c              | 7 +++----
>  4 files changed, 14 insertions(+), 6 deletions(-)
> 
> diff --git a/include/linux/sched.h b/include/linux/sched.h
> index 9f51932bd543..99a4518b9b17 100644
> --- a/include/linux/sched.h
> +++ b/include/linux/sched.h
> @@ -1142,7 +1142,10 @@ struct task_struct {
>  
>       struct tlbflush_unmap_batch     tlb_ubc;
>  
> -     struct rcu_head                 rcu;
> +     union {
> +             refcount_t              rcu_users;
> +             struct rcu_head         rcu;

So what happens if, say:


           CPU 1                         CPU 2
   --------------------------------------------------------------
   rcu_read_lock()
   p = rcu_dereference(rq->task)
   if (refcount_inc_not_zero(p->rcu_users)) {
       .....
                                         release_task() {
                                             put_task_struct_rcu_user() {
                                                 call_rcu() {
                                                     queue rcu_head
                                                 }
                                             }
                                         }
       put_task_struct_rcu_user(); //here rcu_users has been overwritten


Thanks.

Reply via email to