Fix lock ordering with CONFIG_SEMAPHORE_DEBUG
authorBarret Rhoden <brho@cs.berkeley.edu>
Wed, 6 Jul 2016 20:42:18 +0000 (16:42 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 7 Jul 2016 16:39:01 +0000 (12:39 -0400)
commitbcab4ec6bf0a1c8621542870a2a4e788ae866c74
treed968d1acbdefeda26401feef5fe5f39ee180ffbb
parent21f8d953d5ff417452b5b974a976a4b1429093d1
Fix lock ordering with CONFIG_SEMAPHORE_DEBUG

This has been broken forever.  If a kthread was sleeping at the same time
as we did a "db sem", then we could deadlock.  print_all_sem_info() would
grab the list lock, then each sem lock.  The sleepers would grab their own
lock, then the list lock.

This fixes the ordering problem, but at the expense of greater overhead on
every semaphore sleep operation.  If you care about perf, you probably
shouldn't be running with SEMAPHORE_DEBUG anyways, though I always do.

For those curious, here's how I found this brutal bug.  I had an app that
was WAITING.  I did a db sem, and Core 0 locked up.  I repeated it in qemu,
and saw other cores were locked up and where.  Core 0 was in
print_sem_info.  The others were in debug_downed_sem.  The interesting bit
was that the app was making short, blocking calls very quickly - enough so
that the process was WAITING whenever I looked, but blocks would happen
frequently on the timescale of a printk (msec).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/src/kthread.c