diff options
| author | Thomas Hellstrom <unichrome@shipmail.org> | 2005-04-20 18:50:49 +0000 | 
|---|---|---|
| committer | Thomas Hellstrom <unichrome@shipmail.org> | 2005-04-20 18:50:49 +0000 | 
| commit | 699d4ad53a62e46344b672365dda0be4001edd99 (patch) | |
| tree | 1ac0e9023041d9962ad16debe48afdc0f64935b3 /linux-core/drm_lock.c | |
| parent | 2b8dc25dc549533f1567093fb7dffc06d6f55268 (diff) | |
A fix for a locking bug which is triggered when a client tries to lock with
    flag DMA_QUIESCENT (typically the X server), but gets interrupted by a
    signal. The locking IOCTL should then return an error, but if
    DMA_QUIESCENT succeeds it returns 0, and the client falsely thinks it
    has the lock. In addition The client waits for DMA_QUISCENT and
    possibly DMA_READY without having the lock.
Diffstat (limited to 'linux-core/drm_lock.c')
| -rw-r--r-- | linux-core/drm_lock.c | 15 | 
1 files changed, 10 insertions, 5 deletions
| diff --git a/linux-core/drm_lock.c b/linux-core/drm_lock.c index b9833724..048f084f 100644 --- a/linux-core/drm_lock.c +++ b/linux-core/drm_lock.c @@ -99,6 +99,9 @@ int drm_lock(struct inode *inode, struct file *filp,  	current->state = TASK_RUNNING;  	remove_wait_queue(&dev->lock.lock_queue, &entry); +        DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" ); +	if (ret) return ret; +  	sigemptyset(&dev->sigmask);  	sigaddset(&dev->sigmask, SIGSTOP);  	sigaddset(&dev->sigmask, SIGTSTP); @@ -111,8 +114,12 @@ int drm_lock(struct inode *inode, struct file *filp,  	if (dev->driver->dma_ready && (lock.flags & _DRM_LOCK_READY))  		dev->driver->dma_ready(dev); -	if (dev->driver->dma_quiescent && (lock.flags & _DRM_LOCK_QUIESCENT)) -		return dev->driver->dma_quiescent(dev); +	if (dev->driver->dma_quiescent && (lock.flags & _DRM_LOCK_QUIESCENT)) { +		if (dev->driver->dma_quiescent(dev)) { +			DRM_DEBUG( "%d waiting for DMA quiescent\n", lock.context); +			return DRM_ERR(EBUSY); +		} +	}  	if (dev->driver->kernel_context_switch  	    && dev->last_context != lock.context) { @@ -120,9 +127,7 @@ int drm_lock(struct inode *inode, struct file *filp,  						   lock.context);  	} -	DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock"); - -	return ret; +	return 0;  }  /** | 
