On 14 July 2016 at 08:57, David Gibson <da...@gibson.dropbear.id.au> wrote: > Currently linux-user does not correctly clean up CPU instances properly > when running a threaded binary. > > On thread exit, do_syscall() removes the thread's CPU from the cpus list > and calls object_unref(). However, the CPU still is still referenced from > the QOM tree. To correctly clean up we need to object_unparent() to remove > the CPU from the QOM tree, then object_unref() to release the final > reference we're holding. > > Once this is done, the explicit remove from the cpus list is no longer > necessary, since that's done automatically in the CPU unrealize path. > > Signed-off-by: David Gibson <da...@gibson.dropbear.id.au> > --- > linux-user/syscall.c | 7 ++----- > 1 file changed, 2 insertions(+), 5 deletions(-) > > I believe most full system targets also "leak" cpus in the same way, > except that since they don't support cpu hot unplug the cpus never > would have been disposed anyway. I'll look into fixing that another > time. > > diff --git a/linux-user/syscall.c b/linux-user/syscall.c > index 8bf6205..dd91791 100644 > --- a/linux-user/syscall.c > +++ b/linux-user/syscall.c > @@ -6823,10 +6823,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long > arg1, > if (CPU_NEXT(first_cpu)) { > TaskState *ts; > > - cpu_list_lock(); > - /* Remove the CPU from the list. */ > - QTAILQ_REMOVE(&cpus, cpu, node); > - cpu_list_unlock(); > + object_unparent(OBJECT(cpu)); /* Remove from QOM */ > ts = cpu->opaque; > if (ts->child_tidptr) { > put_user_u32(0, ts->child_tidptr); > @@ -6834,7 +6831,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long > arg1, > NULL, NULL, 0); > } > thread_cpu = NULL; > - object_unref(OBJECT(cpu)); > + object_unref(OBJECT(cpu)); /* Remove the last ref we're holding > */
Is it OK to now be removing the CPU from the list after we've done the futex to signal the child task rather than before? > g_free(ts); > rcu_unregister_thread(); > pthread_exit(NULL); > -- > 2.7.4 thanks -- PMM