linux-user: In fork_end(), remove correct CPUs from CPU list
authorPeter Maydell <peter.maydell@linaro.org>
Tue, 7 Jun 2016 16:31:04 +0000 (17:31 +0100)
committerRiku Voipio <riku.voipio@linaro.org>
Wed, 8 Jun 2016 09:06:57 +0000 (12:06 +0300)
In fork_end(), we must fix the list of current CPUs to match the fact
that the child of the fork has only one thread. Unfortunately we were
removing the wrong CPUs from the list, which meant that if the child
subsequently did an exclusive operation it would deadlock in
start_exclusive() waiting for a sibling CPU which didn't exist.

In particular this could cause hangs doing git submodule init
operations, as reported in https://bugs.launchpad.net/qemu/+bug/955379
comment #47.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
linux-user/main.c

index b6da0ba1e2b34eb5c18cd3295bf93801d3f0c1a6..150a356e8d1b7f583d625d10a9c633ec5a2a91b2 100644 (file)
@@ -130,7 +130,7 @@ void fork_end(int child)
            Discard information about the parent threads.  */
         CPU_FOREACH_SAFE(cpu, next_cpu) {
             if (cpu != thread_cpu) {
-                QTAILQ_REMOVE(&cpus, thread_cpu, node);
+                QTAILQ_REMOVE(&cpus, cpu, node);
             }
         }
         pending_cpus = 0;