aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Hellstrom <thomas-at-tungstengraphics-dot-com>2008-05-06 22:22:39 -0400
committerDave Airlie <airlied@linux.ie>2008-05-06 22:22:39 -0400
commitf116cc561eae0a426b8fa6b3e22e80ba0bcf7aee (patch)
tree4af813d3ccdfdeb261bc892409cf4ed59d136930
parentaf6061af0d9f84a4665f88186dc1ff9e4fb78330 (diff)
drm: disable tasklets not IRQs when taking the drm lock spinlock
Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--drivers/char/drm/drm_fops.c7
-rw-r--r--drivers/char/drm/drm_lock.c35
2 files changed, 17 insertions, 25 deletions
diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c
index 68f0da801ed8..d2e6da85f58a 100644
--- a/drivers/char/drm/drm_fops.c
+++ b/drivers/char/drm/drm_fops.c
@@ -323,7 +323,6 @@ int drm_release(struct inode *inode, struct file *filp)
323 struct drm_file *file_priv = filp->private_data; 323 struct drm_file *file_priv = filp->private_data;
324 struct drm_device *dev = file_priv->minor->dev; 324 struct drm_device *dev = file_priv->minor->dev;
325 int retcode = 0; 325 int retcode = 0;
326 unsigned long irqflags;
327 326
328 lock_kernel(); 327 lock_kernel();
329 328
@@ -355,11 +354,9 @@ int drm_release(struct inode *inode, struct file *filp)
355 */ 354 */
356 355
357 do{ 356 do{
358 spin_lock_irqsave(&dev->lock.spinlock, 357 spin_lock_bh(&dev->lock.spinlock);
359 irqflags);
360 locked = dev->lock.idle_has_lock; 358 locked = dev->lock.idle_has_lock;
361 spin_unlock_irqrestore(&dev->lock.spinlock, 359 spin_unlock_bh(&dev->lock.spinlock);
362 irqflags);
363 if (locked) 360 if (locked)
364 break; 361 break;
365 schedule(); 362 schedule();
diff --git a/drivers/char/drm/drm_lock.c b/drivers/char/drm/drm_lock.c
index 12dcdd1832f0..0998723cde79 100644
--- a/drivers/char/drm/drm_lock.c
+++ b/drivers/char/drm/drm_lock.c
@@ -53,7 +53,6 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv)
53 DECLARE_WAITQUEUE(entry, current); 53 DECLARE_WAITQUEUE(entry, current);
54 struct drm_lock *lock = data; 54 struct drm_lock *lock = data;
55 int ret = 0; 55 int ret = 0;
56 unsigned long irqflags;
57 56
58 ++file_priv->lock_count; 57 ++file_priv->lock_count;
59 58
@@ -72,9 +71,9 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv)
72 return -EINVAL; 71 return -EINVAL;
73 72
74 add_wait_queue(&dev->lock.lock_queue, &entry); 73 add_wait_queue(&dev->lock.lock_queue, &entry);
75 spin_lock_irqsave(&dev->lock.spinlock, irqflags); 74 spin_lock_bh(&dev->lock.spinlock);
76 dev->lock.user_waiters++; 75 dev->lock.user_waiters++;
77 spin_unlock_irqrestore(&dev->lock.spinlock, irqflags); 76 spin_unlock_bh(&dev->lock.spinlock);
78 for (;;) { 77 for (;;) {
79 __set_current_state(TASK_INTERRUPTIBLE); 78 __set_current_state(TASK_INTERRUPTIBLE);
80 if (!dev->lock.hw_lock) { 79 if (!dev->lock.hw_lock) {
@@ -96,9 +95,9 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv)
96 break; 95 break;
97 } 96 }
98 } 97 }
99 spin_lock_irqsave(&dev->lock.spinlock, irqflags); 98 spin_lock_bh(&dev->lock.spinlock);
100 dev->lock.user_waiters--; 99 dev->lock.user_waiters--;
101 spin_unlock_irqrestore(&dev->lock.spinlock, irqflags); 100 spin_unlock_bh(&dev->lock.spinlock);
102 __set_current_state(TASK_RUNNING); 101 __set_current_state(TASK_RUNNING);
103 remove_wait_queue(&dev->lock.lock_queue, &entry); 102 remove_wait_queue(&dev->lock.lock_queue, &entry);
104 103
@@ -199,9 +198,8 @@ int drm_lock_take(struct drm_lock_data *lock_data,
199{ 198{
200 unsigned int old, new, prev; 199 unsigned int old, new, prev;
201 volatile unsigned int *lock = &lock_data->hw_lock->lock; 200 volatile unsigned int *lock = &lock_data->hw_lock->lock;
202 unsigned long irqflags;
203 201
204 spin_lock_irqsave(&lock_data->spinlock, irqflags); 202 spin_lock_bh(&lock_data->spinlock);
205 do { 203 do {
206 old = *lock; 204 old = *lock;
207 if (old & _DRM_LOCK_HELD) 205 if (old & _DRM_LOCK_HELD)
@@ -213,7 +211,7 @@ int drm_lock_take(struct drm_lock_data *lock_data,
213 } 211 }
214 prev = cmpxchg(lock, old, new); 212 prev = cmpxchg(lock, old, new);
215 } while (prev != old); 213 } while (prev != old);
216 spin_unlock_irqrestore(&lock_data->spinlock, irqflags); 214 spin_unlock_bh(&lock_data->spinlock);
217 215
218 if (_DRM_LOCKING_CONTEXT(old) == context) { 216 if (_DRM_LOCKING_CONTEXT(old) == context) {
219 if (old & _DRM_LOCK_HELD) { 217 if (old & _DRM_LOCK_HELD) {
@@ -274,16 +272,15 @@ int drm_lock_free(struct drm_lock_data *lock_data, unsigned int context)
274{ 272{
275 unsigned int old, new, prev; 273 unsigned int old, new, prev;
276 volatile unsigned int *lock = &lock_data->hw_lock->lock; 274 volatile unsigned int *lock = &lock_data->hw_lock->lock;
277 unsigned long irqflags;
278 275
279 spin_lock_irqsave(&lock_data->spinlock, irqflags); 276 spin_lock_bh(&lock_data->spinlock);
280 if (lock_data->kernel_waiters != 0) { 277 if (lock_data->kernel_waiters != 0) {
281 drm_lock_transfer(lock_data, 0); 278 drm_lock_transfer(lock_data, 0);
282 lock_data->idle_has_lock = 1; 279 lock_data->idle_has_lock = 1;
283 spin_unlock_irqrestore(&lock_data->spinlock, irqflags); 280 spin_unlock_bh(&lock_data->spinlock);
284 return 1; 281 return 1;
285 } 282 }
286 spin_unlock_irqrestore(&lock_data->spinlock, irqflags); 283 spin_unlock_bh(&lock_data->spinlock);
287 284
288 do { 285 do {
289 old = *lock; 286 old = *lock;
@@ -347,20 +344,19 @@ static int drm_notifier(void *priv)
347void drm_idlelock_take(struct drm_lock_data *lock_data) 344void drm_idlelock_take(struct drm_lock_data *lock_data)
348{ 345{
349 int ret = 0; 346 int ret = 0;
350 unsigned long irqflags;
351 347
352 spin_lock_irqsave(&lock_data->spinlock, irqflags); 348 spin_lock_bh(&lock_data->spinlock);
353 lock_data->kernel_waiters++; 349 lock_data->kernel_waiters++;
354 if (!lock_data->idle_has_lock) { 350 if (!lock_data->idle_has_lock) {
355 351
356 spin_unlock_irqrestore(&lock_data->spinlock, irqflags); 352 spin_unlock_bh(&lock_data->spinlock);
357 ret = drm_lock_take(lock_data, DRM_KERNEL_CONTEXT); 353 ret = drm_lock_take(lock_data, DRM_KERNEL_CONTEXT);
358 spin_lock_irqsave(&lock_data->spinlock, irqflags); 354 spin_lock_bh(&lock_data->spinlock);
359 355
360 if (ret == 1) 356 if (ret == 1)
361 lock_data->idle_has_lock = 1; 357 lock_data->idle_has_lock = 1;
362 } 358 }
363 spin_unlock_irqrestore(&lock_data->spinlock, irqflags); 359 spin_unlock_bh(&lock_data->spinlock);
364} 360}
365EXPORT_SYMBOL(drm_idlelock_take); 361EXPORT_SYMBOL(drm_idlelock_take);
366 362
@@ -368,9 +364,8 @@ void drm_idlelock_release(struct drm_lock_data *lock_data)
368{ 364{
369 unsigned int old, prev; 365 unsigned int old, prev;
370 volatile unsigned int *lock = &lock_data->hw_lock->lock; 366 volatile unsigned int *lock = &lock_data->hw_lock->lock;
371 unsigned long irqflags;
372 367
373 spin_lock_irqsave(&lock_data->spinlock, irqflags); 368 spin_lock_bh(&lock_data->spinlock);
374 if (--lock_data->kernel_waiters == 0) { 369 if (--lock_data->kernel_waiters == 0) {
375 if (lock_data->idle_has_lock) { 370 if (lock_data->idle_has_lock) {
376 do { 371 do {
@@ -381,7 +376,7 @@ void drm_idlelock_release(struct drm_lock_data *lock_data)
381 lock_data->idle_has_lock = 0; 376 lock_data->idle_has_lock = 0;
382 } 377 }
383 } 378 }
384 spin_unlock_irqrestore(&lock_data->spinlock, irqflags); 379 spin_unlock_bh(&lock_data->spinlock);
385} 380}
386EXPORT_SYMBOL(drm_idlelock_release); 381EXPORT_SYMBOL(drm_idlelock_release);
387 382