mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2025-12-24 17:10:13 +01:00
Fix up buffer manager locking.
This commit is contained in:
parent
b986d7d2c9
commit
65dd0e68ff
6 changed files with 41 additions and 21 deletions
|
|
@ -1938,7 +1938,7 @@ int drm_bo_setstatus_ioctl(struct drm_device *dev,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = drm_bo_read_lock(&dev->bm.bm_lock);
|
||||
ret = drm_bo_read_lock(&dev->bm.bm_lock, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -2449,7 +2449,7 @@ int drm_mm_init_ioctl(struct drm_device *dev, void *data, struct drm_file *file_
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = drm_bo_write_lock(&bm->bm_lock, file_priv);
|
||||
ret = drm_bo_write_lock(&bm->bm_lock, 1, file_priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -2500,7 +2500,7 @@ int drm_mm_takedown_ioctl(struct drm_device *dev, void *data, struct drm_file *f
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = drm_bo_write_lock(&bm->bm_lock, file_priv);
|
||||
ret = drm_bo_write_lock(&bm->bm_lock, 0, file_priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -2548,7 +2548,7 @@ int drm_mm_lock_ioctl(struct drm_device *dev, void *data, struct drm_file *file_
|
|||
}
|
||||
|
||||
if (arg->lock_flags & DRM_BO_LOCK_UNLOCK_BM) {
|
||||
ret = drm_bo_write_lock(&dev->bm.bm_lock, file_priv);
|
||||
ret = drm_bo_write_lock(&dev->bm.bm_lock, 1, file_priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
* unmappable regions to mappable. It's a bug to leave kernel space with the
|
||||
* read lock held.
|
||||
*
|
||||
* Both read- and write lock taking is interruptible for low signal-delivery
|
||||
* Both read- and write lock taking may be interruptible for low signal-delivery
|
||||
* latency. The locking functions will return -EAGAIN if interrupted by a
|
||||
* signal.
|
||||
*
|
||||
|
|
@ -71,14 +71,20 @@ void drm_bo_read_unlock(struct drm_bo_lock *lock)
|
|||
if (unlikely(atomic_add_negative(-1, &lock->readers)))
|
||||
BUG();
|
||||
if (atomic_read(&lock->readers) == 0)
|
||||
wake_up_interruptible(&lock->queue);
|
||||
wake_up_all(&lock->queue);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_bo_read_unlock);
|
||||
|
||||
int drm_bo_read_lock(struct drm_bo_lock *lock)
|
||||
int drm_bo_read_lock(struct drm_bo_lock *lock, int interruptible)
|
||||
{
|
||||
while (unlikely(atomic_read(&lock->write_lock_pending) != 0)) {
|
||||
int ret;
|
||||
|
||||
if (!interruptible) {
|
||||
wait_event(lock->queue,
|
||||
atomic_read(&lock->write_lock_pending) == 0);
|
||||
continue;
|
||||
}
|
||||
ret = wait_event_interruptible
|
||||
(lock->queue, atomic_read(&lock->write_lock_pending) == 0);
|
||||
if (ret)
|
||||
|
|
@ -87,8 +93,14 @@ int drm_bo_read_lock(struct drm_bo_lock *lock)
|
|||
|
||||
while (unlikely(!atomic_add_unless(&lock->readers, 1, -1))) {
|
||||
int ret;
|
||||
|
||||
if (!interruptible) {
|
||||
wait_event(lock->queue,
|
||||
atomic_read(&lock->readers) != -1);
|
||||
continue;
|
||||
}
|
||||
ret = wait_event_interruptible
|
||||
(lock->queue, atomic_add_unless(&lock->readers, 1, -1));
|
||||
(lock->queue, atomic_read(&lock->readers) != -1);
|
||||
if (ret)
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
|
@ -100,9 +112,7 @@ static int __drm_bo_write_unlock(struct drm_bo_lock *lock)
|
|||
{
|
||||
if (unlikely(atomic_cmpxchg(&lock->readers, -1, 0) != -1))
|
||||
return -EINVAL;
|
||||
if (unlikely(atomic_cmpxchg(&lock->write_lock_pending, 1, 0) != 1))
|
||||
return -EINVAL;
|
||||
wake_up_interruptible(&lock->queue);
|
||||
wake_up_all(&lock->queue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -116,21 +126,26 @@ static void drm_bo_write_lock_remove(struct drm_file *file_priv,
|
|||
BUG_ON(ret);
|
||||
}
|
||||
|
||||
int drm_bo_write_lock(struct drm_bo_lock *lock, struct drm_file *file_priv)
|
||||
int drm_bo_write_lock(struct drm_bo_lock *lock, int interruptible,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
struct drm_device *dev;
|
||||
|
||||
if (unlikely(atomic_cmpxchg(&lock->write_lock_pending, 0, 1) != 0))
|
||||
return -EINVAL;
|
||||
atomic_inc(&lock->write_lock_pending);
|
||||
|
||||
while (unlikely(atomic_cmpxchg(&lock->readers, 0, -1) != 0)) {
|
||||
if (!interruptible) {
|
||||
wait_event(lock->queue,
|
||||
atomic_read(&lock->readers) == 0);
|
||||
continue;
|
||||
}
|
||||
ret = wait_event_interruptible
|
||||
(lock->queue, atomic_cmpxchg(&lock->readers, 0, -1) == 0);
|
||||
(lock->queue, atomic_read(&lock->readers) == 0);
|
||||
|
||||
if (ret) {
|
||||
atomic_set(&lock->write_lock_pending, 0);
|
||||
wake_up_interruptible(&lock->queue);
|
||||
atomic_dec(&lock->write_lock_pending);
|
||||
wake_up_all(&lock->queue);
|
||||
return -EAGAIN;
|
||||
}
|
||||
}
|
||||
|
|
@ -141,6 +156,7 @@ int drm_bo_write_lock(struct drm_bo_lock *lock, struct drm_file *file_priv)
|
|||
* while holding it.
|
||||
*/
|
||||
|
||||
atomic_dec(&lock->write_lock_pending);
|
||||
dev = file_priv->minor->dev;
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
ret = drm_add_user_object(file_priv, &lock->base, 0);
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ static struct page *drm_bo_vm_fault(struct vm_area_struct *vma,
|
|||
unsigned long bus_size;
|
||||
|
||||
dev = bo->dev;
|
||||
while(drm_bo_read_lock(&dev->bm.bm_lock));
|
||||
drm_bo_read_lock(&dev->bm.bm_lock, 0);
|
||||
|
||||
mutex_lock(&bo->mutex);
|
||||
|
||||
|
|
|
|||
|
|
@ -320,6 +320,8 @@ struct drm_ttm {
|
|||
int destroy;
|
||||
uint32_t mapping_offset;
|
||||
struct drm_ttm_backend *be;
|
||||
unsigned long highest_lomem_entry;
|
||||
unsigned long lowest_himem_entry;
|
||||
enum {
|
||||
ttm_bound,
|
||||
ttm_evicted,
|
||||
|
|
@ -798,8 +800,10 @@ extern void drm_regs_init(struct drm_reg_manager *manager,
|
|||
|
||||
extern void drm_bo_init_lock(struct drm_bo_lock *lock);
|
||||
extern void drm_bo_read_unlock(struct drm_bo_lock *lock);
|
||||
extern int drm_bo_read_lock(struct drm_bo_lock *lock);
|
||||
extern int drm_bo_read_lock(struct drm_bo_lock *lock,
|
||||
int interruptible);
|
||||
extern int drm_bo_write_lock(struct drm_bo_lock *lock,
|
||||
int interruptible,
|
||||
struct drm_file *file_priv);
|
||||
|
||||
extern int drm_bo_write_unlock(struct drm_bo_lock *lock,
|
||||
|
|
|
|||
|
|
@ -738,7 +738,7 @@ static unsigned long drm_bo_vm_nopfn(struct vm_area_struct *vma,
|
|||
return NOPFN_SIGBUS;
|
||||
|
||||
dev = bo->dev;
|
||||
err = drm_bo_read_lock(&dev->bm.bm_lock);
|
||||
err = drm_bo_read_lock(&dev->bm.bm_lock, 1);
|
||||
if (err)
|
||||
return NOPFN_REFAULT;
|
||||
|
||||
|
|
|
|||
|
|
@ -845,7 +845,7 @@ int i915_execbuffer(struct drm_device *dev, void *data,
|
|||
if (exec_buf->num_buffers > dev_priv->max_validate_buffers)
|
||||
return -EINVAL;
|
||||
|
||||
ret = drm_bo_read_lock(&dev->bm.bm_lock);
|
||||
ret = drm_bo_read_lock(&dev->bm.bm_lock, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue