Messages in this thread | | | Date | Sat, 13 Jun 2015 20:00:56 +0200 | From | Oleg Nesterov <> | Subject | Re: [PATCH 07/12] x86/virt/guest/xen: Remove use of pgd_list from the Xen guest code |
| |
On 06/13, Ingo Molnar wrote: > > * Oleg Nesterov <oleg@redhat.com> wrote: > > > > So we could add tsk->mm_leader or so, > > > > No, no, please do not. Just do something like > > > > for_each_process(p) { > > > > for_each_thread(p, t) { > > So far that's what the for_each_process_thread() iterations I added do, right?
Not really,
> > if (t->mm) { > > do_something(t->mm); > > break; ^^^^^
Note this "break". We stop the inner loop right after we find a thread "t" with ->mm != NULL. In the likely case t == p (group leader) so the inner loop stops on the 1st iteration.
> > But either way I don't understand what protects this ->mm. Perhaps this needs > > find_lock_task_mm(). > > That's indeed a bug: I'll add task_lock()/unlock() before looking at ->mm.
Well, in this particular case we are safe. As Boris explained this is called from stop_machine(). But sync_global_pgds() is not safe.
> find_lock_task_mm() is not needed IMHO: we have a stable reference to 't', as > task can only go away via RCU expiry, and all the iterations I added are (supposed > to) be RCU safe.
Sure, you can do lock/unlock by hand. But find_lock_task_mm() can simplify the code because it checks subthreads if group_leader->mm == NULL. You can simply do
rcu_read_lock(); for_each_process(p) { t = find_lock_task_mm(p); if (!t) continue;
do_something(t->mm); task_unlock(t); } rcu_read_unlock();
Oleg.
| |