diff options
Diffstat (limited to 'linux-core')
| -rw-r--r-- | linux-core/drm_fops.c | 7 | ||||
| -rw-r--r-- | linux-core/drm_lock.c | 35 | 
2 files changed, 25 insertions, 17 deletions
diff --git a/linux-core/drm_fops.c b/linux-core/drm_fops.c index 7fe274a2..a4c76f75 100644 --- a/linux-core/drm_fops.c +++ b/linux-core/drm_fops.c @@ -373,6 +373,7 @@ int drm_release(struct inode *inode, struct file *filp)  	struct drm_file *file_priv = filp->private_data;  	struct drm_device *dev = file_priv->minor->dev;  	int retcode = 0; +	unsigned long irqflags;  	lock_kernel(); @@ -403,9 +404,11 @@ int drm_release(struct inode *inode, struct file *filp)  			 */  			do{ -				spin_lock(&dev->lock.spinlock); +				spin_lock_irqsave(&dev->lock.spinlock, +						  irqflags);  				locked = dev->lock.idle_has_lock; -				spin_unlock(&dev->lock.spinlock); +				spin_unlock_irqrestore(&dev->lock.spinlock, +						       irqflags);  				if (locked)  					break;  				schedule(); diff --git a/linux-core/drm_lock.c b/linux-core/drm_lock.c index b8e4a5d9..39e1261c 100644 --- a/linux-core/drm_lock.c +++ b/linux-core/drm_lock.c @@ -53,6 +53,7 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv)  	DECLARE_WAITQUEUE(entry, current);  	struct drm_lock *lock = data;  	int ret = 0; +	unsigned long irqflags;  	++file_priv->lock_count; @@ -71,9 +72,9 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv)  			return -EINVAL;  	add_wait_queue(&dev->lock.lock_queue, &entry); -	spin_lock(&dev->lock.spinlock); +	spin_lock_irqsave(&dev->lock.spinlock, irqflags);  	dev->lock.user_waiters++; -	spin_unlock(&dev->lock.spinlock); +	spin_unlock_irqsave(&dev->lock.spinlock, irqflags);  	for (;;) {  		__set_current_state(TASK_INTERRUPTIBLE);  		if (!dev->lock.hw_lock) { @@ -95,9 +96,9 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv)  			break;  		}  	} -	spin_lock(&dev->lock.spinlock); +	spin_lock_irqsave(&dev->lock.spinlock, irqflags);  	dev->lock.user_waiters--; -	spin_unlock(&dev->lock.spinlock); +	spin_unlock_irqrestore(&dev->lock.spinlock, irqflags);  	__set_current_state(TASK_RUNNING);  	remove_wait_queue(&dev->lock.lock_queue, &entry); @@ -198,8 +199,9 @@ int drm_lock_take(struct drm_lock_data *lock_data,  {  	unsigned int old, new, prev;  	volatile unsigned int *lock = &lock_data->hw_lock->lock; +	unsigned long irqflags; -	spin_lock(&lock_data->spinlock); +	spin_lock_irqsave(&lock_data->spinlock, irqflags);  	do {  		old = *lock;  		if (old & _DRM_LOCK_HELD) @@ -211,7 +213,7 @@ int drm_lock_take(struct drm_lock_data *lock_data,  		}  		prev = cmpxchg(lock, old, new);  	} while (prev != old); -	spin_unlock(&lock_data->spinlock); +	spin_unlock_irqrestore(&lock_data->spinlock, irqflags);  	if (_DRM_LOCKING_CONTEXT(old) == context) {  		if (old & _DRM_LOCK_HELD) { @@ -273,15 +275,16 @@ int drm_lock_free(struct drm_lock_data *lock_data, unsigned int context)  {  	unsigned int old, new, prev;  	volatile unsigned int *lock = &lock_data->hw_lock->lock; +	unsigned long irqflags; -	spin_lock(&lock_data->spinlock); +	spin_lock_irqsave(&lock_data->spinlock, irqflags);  	if (lock_data->kernel_waiters != 0) {  		drm_lock_transfer(lock_data, 0);  		lock_data->idle_has_lock = 1; -		spin_unlock(&lock_data->spinlock); +		spin_unlock_irqrestore(&lock_data->spinlock, irqflags);  		return 1;  	} -	spin_unlock(&lock_data->spinlock); +	spin_unlock_irqrestore(&lock_data->spinlock, irqflags);  	do {  		old = *lock; @@ -345,19 +348,20 @@ static int drm_notifier(void *priv)  void drm_idlelock_take(struct drm_lock_data *lock_data)  {  	int ret = 0; +	unsigned long irqflags; -	spin_lock(&lock_data->spinlock); +	spin_lock_irqsave(&lock_data->spinlock, irqflags);  	lock_data->kernel_waiters++;  	if (!lock_data->idle_has_lock) { -		spin_unlock(&lock_data->spinlock); +		spin_unlock_irqrestore(&lock_data->spinlock, irqflags);  		ret = drm_lock_take(lock_data, DRM_KERNEL_CONTEXT); -		spin_lock(&lock_data->spinlock); +		spin_lock_irqsave(&lock_data->spinlock, irqflags);  		if (ret == 1)  			lock_data->idle_has_lock = 1;  	} -	spin_unlock(&lock_data->spinlock); +	spin_unlock_irqrestore(&lock_data->spinlock, irq_flags);  }  EXPORT_SYMBOL(drm_idlelock_take); @@ -365,8 +369,9 @@ void drm_idlelock_release(struct drm_lock_data *lock_data)  {  	unsigned int old, prev;  	volatile unsigned int *lock = &lock_data->hw_lock->lock; +	unsigned long irqflags; -	spin_lock(&lock_data->spinlock); +	spin_lock_irqsave(&lock_data->spinlock, irqflags);  	if (--lock_data->kernel_waiters == 0) {  		if (lock_data->idle_has_lock) {  			do { @@ -377,7 +382,7 @@ void drm_idlelock_release(struct drm_lock_data *lock_data)  			lock_data->idle_has_lock = 0;  		}  	} -	spin_unlock(&lock_data->spinlock); +	spin_unlock_irqrestore(&lock_data->spinlock, irqflags);  }  EXPORT_SYMBOL(drm_idlelock_release);  | 
