On 09/04, Peter Zijlstra wrote: > > On Wed, Sep 04, 2019 at 02:03:37PM +0200, Oleg Nesterov wrote: > > On 09/04, Peter Zijlstra wrote: > > > > > > + struct task_struct *g, *t; > > > + > > > + read_lock(&tasklist_lock); > > > + do_each_thread(g, t) { > > > > for_each_process_thread() looks better > > Argh, I always get confused. Why do we have multiple version of this > again?
Because I am lazy ;) but actually for_each_process_thread() is suboptimal, I think you need for_each_process(p) { if (p->flags & PF_KTHREAD) continue; if (p->mm != mm) continue; for_each_thread(p, t) atomic_or(t->membarrier_state, ...); } to avoid unnecessary each-thread when group leader has another ->mm. Unfortunately a zombie leader has ->mm == NULL, so perhaps something like for_each_process(p) { if (p->flags & PF_KTHREAD) continue; for_each_thread(p, t) { if (unlikely(!t->mm)) continue; if (t->mm != mm) break; atomic_or(t->membarrier_state, ...); } } and to we really need the new atomic_t member? can we use t->atomic_flags and add PFA_MEMBARRIER_EXPEDITED ? Oleg.