On 09/02, Peter Zijlstra wrote: > > On Mon, Sep 02, 2019 at 03:40:03PM +0200, Oleg Nesterov wrote: > > diff --git a/include/linux/sched.h b/include/linux/sched.h > > index 8dc1811..1f9b021 100644 > > --- a/include/linux/sched.h > > +++ b/include/linux/sched.h > > @@ -1134,7 +1134,10 @@ struct task_struct { > > > > struct tlbflush_unmap_batch tlb_ubc; > > > > - struct rcu_head rcu; > > + union { > > + bool xxx; > > + struct rcu_head rcu; > > + }; > > > > /* Cache last used pipe for splice(): */ > > struct pipe_inode_info *splice_pipe; > > diff --git a/kernel/exit.c b/kernel/exit.c > > index a75b6a7..baacfce 100644 > > --- a/kernel/exit.c > > +++ b/kernel/exit.c > > @@ -182,6 +182,11 @@ static void delayed_put_task_struct(struct rcu_head > > *rhp) > > put_task_struct(tsk); > > } > > > > +void call_delayed_put_task_struct(struct task_struct *p) > > +{ > > + if (xchg(&p->xxx, 1)) > > + call_rcu(&p->rcu, delayed_put_task_struct); > > +} > > I think this is the first usage of xchg() on _Bool, also not all archs > implement xchg8()
I didn't even notice I used "bool" ;) speaking of the users of task_rcu_dereference(), membarrier_global_expedited() does rcu_read_lock(); p = task_rcu_dereference(&cpu_rq(cpu)->curr); if (p && p->mm && (atomic_read(&p->mm->membarrier_state) & MEMBARRIER_STATE_GLOBAL_EXPEDITED)) { This asks for READ_ONCE, but this is minor. Why can't p->mm be freed? I guess it is fine to read the garbage from &p->mm->membarrier_state if we race with the exiting task, but in theory this looks unsafe if CONFIG_DEBUG_PAGEALLOC. Another possible user of probe_slab_address() or I am totally confused? Oleg.