mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 12:42:02 +00:00
Merge branch 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6
* 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6: drm/i915: Fix use-before-null-check in i915_irq_emit(). drm: Avoid client deadlocks when the master disappears. drm: Wake up all lock waiters when the master disappears. drm: Don't return ERESTARTSYS to user-space.
This commit is contained in:
commit
43e407071d
@ -420,7 +420,7 @@ int drm_rmmap_locked(struct drm_device *dev, drm_local_map_t *map)
|
||||
dev->sigdata.lock = NULL;
|
||||
master->lock.hw_lock = NULL; /* SHM removed */
|
||||
master->lock.file_priv = NULL;
|
||||
wake_up_interruptible(&master->lock.lock_queue);
|
||||
wake_up_interruptible_all(&master->lock.lock_queue);
|
||||
}
|
||||
break;
|
||||
case _DRM_AGP:
|
||||
|
@ -484,6 +484,7 @@ int drm_release(struct inode *inode, struct file *filp)
|
||||
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 @@ int drm_release(struct inode *inode, struct file *filp)
|
||||
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);
|
||||
|
@ -80,6 +80,7 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv)
|
||||
__set_current_state(TASK_INTERRUPTIBLE);
|
||||
if (!master->lock.hw_lock) {
|
||||
/* Device has been unregistered */
|
||||
send_sig(SIGTERM, current, 0);
|
||||
ret = -EINTR;
|
||||
break;
|
||||
}
|
||||
@ -93,7 +94,7 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv)
|
||||
/* Contention */
|
||||
schedule();
|
||||
if (signal_pending(current)) {
|
||||
ret = -ERESTARTSYS;
|
||||
ret = -EINTR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -146,14 +146,6 @@ static void drm_master_destroy(struct kref *kref)
|
||||
|
||||
drm_ht_remove(&master->magiclist);
|
||||
|
||||
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(&master->lock.lock_queue);
|
||||
}
|
||||
|
||||
drm_free(master, sizeof(*master), DRM_MEM_DRIVER);
|
||||
}
|
||||
|
||||
|
@ -383,12 +383,13 @@ int i915_irq_emit(struct drm_device *dev, void *data,
|
||||
drm_i915_irq_emit_t *emit = data;
|
||||
int result;
|
||||
|
||||
RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
|
||||
|
||||
if (!dev_priv) {
|
||||
DRM_ERROR("called with no initialization\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
result = i915_emit_irq(dev);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
|
Loading…
Reference in New Issue
Block a user