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.c96
1 files changed, 48 insertions, 48 deletions
diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c
index 898f47dafec0..3b159cab3bc8 100644
--- a/drivers/char/drm/drm_fops.c
+++ b/drivers/char/drm/drm_fops.c
@@ -46,6 +46,7 @@ static int drm_setup(drm_device_t * dev)
46 drm_local_map_t *map; 46 drm_local_map_t *map;
47 int i; 47 int i;
48 int ret; 48 int ret;
49 u32 sareapage;
49 50
50 if (dev->driver->firstopen) { 51 if (dev->driver->firstopen) {
51 ret = dev->driver->firstopen(dev); 52 ret = dev->driver->firstopen(dev);
@@ -56,7 +57,8 @@ static int drm_setup(drm_device_t * dev)
56 dev->magicfree.next = NULL; 57 dev->magicfree.next = NULL;
57 58
58 /* prebuild the SAREA */ 59 /* prebuild the SAREA */
59 i = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM, _DRM_CONTAINS_LOCK, &map); 60 sareapage = max_t(unsigned, SAREA_MAX, PAGE_SIZE);
61 i = drm_addmap(dev, 0, sareapage, _DRM_SHM, _DRM_CONTAINS_LOCK, &map);
60 if (i != 0) 62 if (i != 0)
61 return i; 63 return i;
62 64
@@ -84,7 +86,7 @@ static int drm_setup(drm_device_t * dev)
84 INIT_LIST_HEAD(&dev->ctxlist->head); 86 INIT_LIST_HEAD(&dev->ctxlist->head);
85 87
86 dev->vmalist = NULL; 88 dev->vmalist = NULL;
87 dev->sigdata.lock = dev->lock.hw_lock = NULL; 89 dev->sigdata.lock = NULL;
88 init_waitqueue_head(&dev->lock.lock_queue); 90 init_waitqueue_head(&dev->lock.lock_queue);
89 dev->queue_count = 0; 91 dev->queue_count = 0;
90 dev->queue_reserved = 0; 92 dev->queue_reserved = 0;
@@ -354,58 +356,56 @@ int drm_release(struct inode *inode, struct file *filp)
354 current->pid, (long)old_encode_dev(priv->head->device), 356 current->pid, (long)old_encode_dev(priv->head->device),
355 dev->open_count); 357 dev->open_count);
356 358
357 if (priv->lock_count && dev->lock.hw_lock && 359 if (dev->driver->reclaim_buffers_locked && dev->lock.hw_lock) {
358 _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) && 360 if (drm_i_have_hw_lock(filp)) {
359 dev->lock.filp == filp) {
360 DRM_DEBUG("File %p released, freeing lock for context %d\n",
361 filp, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
362
363 if (dev->driver->reclaim_buffers_locked)
364 dev->driver->reclaim_buffers_locked(dev, filp); 361 dev->driver->reclaim_buffers_locked(dev, filp);
365 362 } else {
366 drm_lock_free(dev, &dev->lock.hw_lock->lock, 363 unsigned long _end=jiffies + 3*DRM_HZ;
367 _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); 364 int locked = 0;
368 365
369 /* FIXME: may require heavy-handed reset of 366 drm_idlelock_take(&dev->lock);
370 hardware at this point, possibly 367
371 processed via a callback to the X 368 /*
372 server. */ 369 * Wait for a while.
373 } else if (dev->driver->reclaim_buffers_locked && priv->lock_count 370 */
374 && dev->lock.hw_lock) { 371
375 /* The lock is required to reclaim buffers */ 372 do{
376 DECLARE_WAITQUEUE(entry, current); 373 spin_lock(&dev->lock.spinlock);
377 374 locked = dev->lock.idle_has_lock;
378 add_wait_queue(&dev->lock.lock_queue, &entry); 375 spin_unlock(&dev->lock.spinlock);
379 for (;;) { 376 if (locked)
380 __set_current_state(TASK_INTERRUPTIBLE); 377 break;
381 if (!dev->lock.hw_lock) { 378 schedule();
382 /* Device has been unregistered */ 379 } while (!time_after_eq(jiffies, _end));
383 retcode = -EINTR; 380
384 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");
385 } 385 }
386 if (drm_lock_take(&dev->lock.hw_lock->lock, 386
387 DRM_KERNEL_CONTEXT)) {
388 dev->lock.filp = filp;
389 dev->lock.lock_time = jiffies;
390 atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
391 break; /* Got lock */
392 }
393 /* Contention */
394 schedule();
395 if (signal_pending(current)) {
396 retcode = -ERESTARTSYS;
397 break;
398 }
399 }
400 __set_current_state(TASK_RUNNING);
401 remove_wait_queue(&dev->lock.lock_queue, &entry);
402 if (!retcode) {
403 dev->driver->reclaim_buffers_locked(dev, filp); 387 dev->driver->reclaim_buffers_locked(dev, filp);
404 drm_lock_free(dev, &dev->lock.hw_lock->lock, 388 drm_idlelock_release(&dev->lock);
405 DRM_KERNEL_CONTEXT);
406 } 389 }
407 } 390 }
408 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
409 if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) && 409 if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) &&
410 !dev->driver->reclaim_buffers_locked) { 410 !dev->driver->reclaim_buffers_locked) {
411 dev->driver->reclaim_buffers(dev, filp); 411 dev->driver->reclaim_buffers(dev, filp);