diff options
Diffstat (limited to 'drivers/char/drm/drm_fops.c')
-rw-r--r-- | drivers/char/drm/drm_fops.c | 96 |
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); |