Deadlock in nonmoving GC
I'm surprised I didn't see this one earlier. A deadlock on the storage manager lock:
Thread 25 (LWP 8097):
#0 0x00007fedc61781bc in __lll_lock_wait () from /nix/store/wx1vk75bpdr65g6xwxbj4rw0pk04v5j3-glibc-2.27/lib/libpthread.so.0
#1 0x00007fedc61714b5 in pthread_mutex_lock () from /nix/store/wx1vk75bpdr65g6xwxbj4rw0pk04v5j3-glibc-2.27/lib/libpthread.so.0
#2 0x0000000005bc6415 in markQueuePop_ (q=0x7fed78005f90) at rts/sm/NonMovingMark.c:813
#3 0x0000000005bc64e0 in markQueuePop (q=0x7fed78005f90) at rts/sm/NonMovingMark.c:832
#4 0x0000000005bc8456 in nonmovingMark (queue=0x7fed78005f90) at rts/sm/NonMovingMark.c:1684
#5 0x0000000005bc36d6 in nonmovingMarkThreadsWeaks (mark_queue=0x7fed78005f90) at rts/sm/NonMoving.c:948
#6 0x0000000005bc3891 in nonmovingMark_ (mark_queue=0x7fed78005f90, dead_weaks=0x7fed6899fee0, resurrected_threads=0x7fed6899fee8) at rts/sm/NonMoving.c:1008
#7 0x0000000005bc373d in nonmovingConcurrentMark (data=0x7fed78005f90) at rts/sm/NonMoving.c:964
#8 0x00007fedc616eef7 in start_thread () from /nix/store/wx1vk75bpdr65g6xwxbj4rw0pk04v5j3-glibc-2.27/lib/libpthread.so.0
#9 0x00007fedc5deb22f in clone () from /nix/store/wx1vk75bpdr65g6xwxbj4rw0pk04v5j3-glibc-2.27/lib/libc.so.6
Thread 15 (LWP 28256):
#0 0x00007fedc61781bc in __lll_lock_wait () from /nix/store/wx1vk75bpdr65g6xwxbj4rw0pk04v5j3-glibc-2.27/lib/libpthread.so.0
#1 0x00007fedc61714b5 in pthread_mutex_lock () from /nix/store/wx1vk75bpdr65g6xwxbj4rw0pk04v5j3-glibc-2.27/lib/libpthread.so.0
#2 0x0000000005bc5543 in nonmovingAddUpdRemSetBlocks (rset=0x67ef708 <MainCapability+1032>) at rts/sm/NonMovingMark.c:288
#3 0x0000000005bc5844 in push (q=0x67ef708 <MainCapability+1032>, ent=0x7fed9cff8b80) at rts/sm/NonMovingMark.c:428
#4 0x0000000005bc5af8 in push_closure (q=0x67ef708 <MainCapability+1032>, p=0x67ea6e0, origin=0x0) at rts/sm/NonMovingMark.c:508
#5 0x0000000005bc5efe in updateRemembSetPushClosure (cap=0x67ef300 <MainCapability>, p=0x67ea6e0) at rts/sm/NonMovingMark.c:656
#6 0x0000000005bf8b08 in nonmovingScavengeOne (q=0x4210fbf878) at rts/sm/NonMovingScav.c:98
#7 0x0000000005bf9562 in scavengeNonmovingSegment (seg=0x4210fb8000) at rts/sm/NonMovingScav.c:458
#8 0x0000000005bd454b in scavenge_find_work () at rts/sm/Scav.c:2068
#9 0x0000000005bd46c2 in scavenge_loop () at rts/sm/Scav.c:2155
#10 0x0000000005bbe180 in scavenge_until_all_done () at rts/sm/GC.c:1172
#11 0x0000000005bbe2f0 in gcWorkerThread (cap=0x67ef300 <MainCapability>) at rts/sm/GC.c:1246
#12 0x0000000005b8b951 in yieldCapability (pCap=0x7fed9cff8e20, task=0x7feda0000b90, gcAllowed=true) at rts/Capability.c:876
#13 0x0000000005ba1202 in scheduleYield (pcap=0x7fed9cff8e68, task=0x7feda0000b90) at rts/Schedule.c:694
#14 0x0000000005ba0614 in schedule (initialCapability=0x67ef300 <MainCapability>, task=0x7feda0000b90) at rts/Schedule.c:308
#15 0x0000000005ba403c in scheduleWorker (cap=0x67ef300 <MainCapability>, task=0x7feda0000b90) at rts/Schedule.c:2617
#16 0x0000000005baae16 in workerStart (task=0x7feda0000b90) at rts/Task.c:445
#17 0x00007fedc616eef7 in start_thread () from /nix/store/wx1vk75bpdr65g6xwxbj4rw0pk04v5j3-glibc-2.27/lib/libpthread.so.0
#18 0x00007fedc5deb22f in clone () from /nix/store/wx1vk75bpdr65g6xwxbj4rw0pk04v5j3-glibc-2.27/lib/libc.so.6
Thread 19 (LWP 28635):
#0 0x00007fedc5dd3be7 in sched_yield () from /nix/store/wx1vk75bpdr65g6xwxbj4rw0pk04v5j3-glibc-2.27/lib/libc.so.6
#1 0x0000000005bd9339 in yieldThread () at rts/posix/OSThreads.c:123
#2 0x0000000005bbe161 in any_work () at rts/sm/GC.c:1157
#3 0x0000000005bbe1cc in scavenge_until_all_done () at rts/sm/GC.c:1198
#4 0x0000000005bbe2f0 in gcWorkerThread (cap=0x7fedac001350) at rts/sm/GC.c:1246
#5 0x0000000005b8b951 in yieldCapability (pCap=0x7fed7effce20, task=0x7fed80000bd0, gcAllowed=true) at rts/Capability.c:876
#6 0x0000000005ba1202 in scheduleYield (pcap=0x7fed7effce68, task=0x7fed80000bd0) at rts/Schedule.c:694
#7 0x0000000005ba0614 in schedule (initialCapability=0x7fedac001350, task=0x7fed80000bd0) at rts/Schedule.c:308
#8 0x0000000005ba403c in scheduleWorker (cap=0x7fedac001350, task=0x7fed80000bd0) at rts/Schedule.c:2617
#9 0x0000000005baae16 in workerStart (task=0x7fed80000bd0) at rts/Task.c:445
#10 0x00007fedc616eef7 in start_thread () from /nix/store/wx1vk75bpdr65g6xwxbj4rw0pk04v5j3-glibc-2.27/lib/libpthread.so.0
#11 0x00007fedc5deb22f in clone () from /nix/store/wx1vk75bpdr65g6xwxbj4rw0pk04v5j3-glibc-2.27/lib/libc.so.6
In short, we do a minor GC. If a GC thread fill's its update remembered set it will need to allocate a new block. However, this requires that it takes the SM block, which we already hold.