aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/drm/drm_fops.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/drm/drm_fops.c')
-rw-r--r--drivers/char/drm/drm_fops.c90
1 files changed, 44 insertions, 46 deletions
diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c
index 314abd9d6510..3b159cab3bc8 100644
--- a/drivers/char/drm/drm_fops.c
+++ b/drivers/char/drm/drm_fops.c
@@ -356,58 +356,56 @@ int drm_release(struct inode *inode, struct file *filp)
356 current->pid, (long)old_encode_dev(priv->head->device), 356 current->pid, (long)old_encode_dev(priv->head->device),
357 dev->open_count); 357 dev->open_count);
358 358
359 if (priv->lock_count && dev->lock.hw_lock && 359 if (dev->driver->reclaim_buffers_locked && dev->lock.hw_lock) {
360 _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) && 360 if (drm_i_have_hw_lock(filp)) {
361 dev->lock.filp == filp) {
362 DRM_DEBUG("File %p released, freeing lock for context %d\n",
363 filp, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
364
365 if (dev->driver->reclaim_buffers_locked)
366 dev->driver->reclaim_buffers_locked(dev, filp); 361 dev->driver->reclaim_buffers_locked(dev, filp);
367 362 } else {
368 drm_lock_free(dev, &dev->lock.hw_lock->lock, 363 unsigned long _end=jiffies + 3*DRM_HZ;
369 _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); 364 int locked = 0;
370 365
371 /* FIXME: may require heavy-handed reset of 366 drm_idlelock_take(&dev->lock);
372 hardware at this point, possibly 367
373 processed via a callback to the X 368 /*
374 server. */ 369 * Wait for a while.
375 } else if (dev->driver->reclaim_buffers_locked && priv->lock_count 370 */
376 && dev->lock.hw_lock) { 371
377 /* The lock is required to reclaim buffers */ 372 do{
378 DECLARE_WAITQUEUE(entry, current); 373 spin_lock(&dev->lock.spinlock);
379 374 locked = dev->lock.idle_has_lock;
380 add_wait_queue(&dev->lock.lock_queue, &entry); 375 spin_unlock(&dev->lock.spinlock);
381 for (;;) { 376 if (locked)
382 __set_current_state(TASK_INTERRUPTIBLE); 377 break;
383 if (!dev->lock.hw_lock) { 378 schedule();
384 /* Device has been unregistered */ 379 } while (!time_after_eq(jiffies, _end));
385 retcode = -EINTR; 380
386 break; 381 if (!locked) {
382 DRM_ERROR("reclaim_buffers_locked() deadlock. Please rework this\n"
383 "\tdriver to use reclaim_buffers_idlelocked() instead.\n"
384 "\tI will go on reclaiming the buffers anyway.\n");
387 } 385 }
388 if (drm_lock_take(&dev->lock.hw_lock->lock, 386
389 DRM_KERNEL_CONTEXT)) {
390 dev->lock.filp = filp;
391 dev->lock.lock_time = jiffies;
392 atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
393 break; /* Got lock */
394 }
395 /* Contention */
396 schedule();
397 if (signal_pending(current)) {
398 retcode = -ERESTARTSYS;
399 break;
400 }
401 }
402 __set_current_state(TASK_RUNNING);
403 remove_wait_queue(&dev->lock.lock_queue, &entry);
404 if (!retcode) {
405 dev->driver->reclaim_buffers_locked(dev, filp); 387 dev->driver->reclaim_buffers_locked(dev, filp);
406 drm_lock_free(dev, &dev->lock.hw_lock->lock, 388 drm_idlelock_release(&dev->lock);
407 DRM_KERNEL_CONTEXT);
408 } 389 }
409 } 390 }
410 391
392 if (dev->driver->reclaim_buffers_idlelocked && dev->lock.hw_lock) {
393
394 drm_idlelock_take(&dev->lock);
395 dev->driver->reclaim_buffers_idlelocked(dev, filp);
396 drm_idlelock_release(&dev->lock);
397
398 }
399
400 if (drm_i_have_hw_lock(filp)) {
401 DRM_DEBUG("File %p released, freeing lock for context %d\n",
402 filp, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
403
404 drm_lock_free(&dev->lock,
405 _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
406 }
407
408
411 if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) && 409 if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) &&
412 !dev->driver->reclaim_buffers_locked) { 410 !dev->driver->reclaim_buffers_locked) {
413 dev->driver->reclaim_buffers(dev, filp); 411 dev->driver->reclaim_buffers(dev, filp);