drm: Avoid client deadlocks when the master disappears.

This is done by
1) Wake up lock waiters when we close the master file descriptor.
   Not when the master structure is removed, since the latter
   requires the waiters themselves to release the refcount on the
   master structure -> Deadlock.
2) Send a SIGTERM to all clients waiting for the lock.
   Normally these clients will get a SIGPIPE when the X server dies,
   but clients may also spin trying to grab the DRM lock, without
   getting any sort of notification.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Signed-off-by: Dave Airlie <airlied@linux.ie>
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 6c020fe..f52663e 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -484,6 +484,7 @@
 	mutex_lock(&dev->struct_mutex);
 
 	if (file_priv->is_master) {
+		struct drm_master *master = file_priv->master;
 		struct drm_file *temp;
 		list_for_each_entry(temp, &dev->filelist, lhead) {
 			if ((temp->master == file_priv->master) &&
@@ -491,6 +492,19 @@
 				temp->authenticated = 0;
 		}
 
+		/**
+		 * Since the master is disappearing, so is the
+		 * possibility to lock.
+		 */
+
+		if (master->lock.hw_lock) {
+			if (dev->sigdata.lock == master->lock.hw_lock)
+				dev->sigdata.lock = NULL;
+			master->lock.hw_lock = NULL;
+			master->lock.file_priv = NULL;
+			wake_up_interruptible_all(&master->lock.lock_queue);
+		}
+
 		if (file_priv->minor->master == file_priv->master) {
 			/* drop the reference held my the minor */
 			drm_master_put(&file_priv->minor->master);