drm: Use lockmgr locks with Linux wait queues
authorFrançois Tigeot <ftigeot@wolfpond.org>
Tue, 18 Nov 2014 21:18:03 +0000 (22:18 +0100)
committerFrançois Tigeot <ftigeot@wolfpond.org>
Tue, 18 Nov 2014 21:33:15 +0000 (22:33 +0100)
commit88c5318ef0b15bc6f23c6ddfe09d2226a2720d8e
tree04609a8d6b825aa5ab7ef025d9cad444986adff0
parentd4ef66945aed8476e02f05a7261843a95e5f12bd
drm: Use lockmgr locks with Linux wait queues

* On Linux, it is possible to grab a second spinlock in an already
  spinlock-protected code section.

* The wait_event() macro is used in such a situation in the i915 driver.
  One of the event checks itself tries to grab a second lock. What's more,
  this second lock is a lockmgr lock in the DragonFly kernel. This results
  in the following situation:

    spinlock
    lockmgr LK_EXCLUSIVE
    spinunlock

* Unfortunately if the lockmgr lock can't be acquired, the thread is put
  to sleep and a thread sleeping with a spinlock held leads to a general
  system freeze or a kernel panic.

* For that reason, we can't use a spinlock in Linux wait queues. Change
  the internal wait_queue_head_t lock to a lockmgr lock.

Thanks go to Imre Vadász for spotting this horrible issue.
sys/dev/drm/i915/i915_gem.c
sys/dev/drm/include/linux/completion.h
sys/dev/drm/include/linux/wait.h