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.

Reply via email to