From 03e932e32be6ae3de6994c6893c813a34623ad7d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 23 Jul 2007 15:11:12 -0700 Subject: linux: Make DRM_IOCTL_GET_CLIENT return EINVAL when it can't find client #idx. Fixes the getclient test and dritest -c. --- linux-core/drm_ioctl.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) (limited to 'linux-core') diff --git a/linux-core/drm_ioctl.c b/linux-core/drm_ioctl.c index f3f757da..9d52fd8a 100644 --- a/linux-core/drm_ioctl.c +++ b/linux-core/drm_ioctl.c @@ -229,26 +229,23 @@ int drm_getclient(struct drm_device *dev, void *data, idx = client->idx; mutex_lock(&dev->struct_mutex); - - if (list_empty(&dev->filelist)) { - mutex_unlock(&dev->struct_mutex); - return -EINVAL; - } i = 0; list_for_each_entry(pt, &dev->filelist, lhead) { - if (i++ >= idx) - break; + if (i++ >= idx) { + client->auth = pt->authenticated; + client->pid = pt->pid; + client->uid = pt->uid; + client->magic = pt->magic; + client->iocs = pt->ioctl_count; + mutex_unlock(&dev->struct_mutex); + + return 0; + } } - - client->auth = pt->authenticated; - client->pid = pt->pid; - client->uid = pt->uid; - client->magic = pt->magic; - client->iocs = pt->ioctl_count; mutex_unlock(&dev->struct_mutex); - return 0; + return -EINVAL; } /** -- cgit v1.2.3 From cf2d569daca6954d11a796f4d110148ae2e0c827 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 26 Jul 2007 10:14:17 -0700 Subject: Replace NO_MOVE/NO_EVICT flags to buffer objects with an ioctl to set pinning. This cleans up the create/validate interfaces for this very uncommon path, and makes pinned object creation much easier to use for the X Server. --- linux-core/drm_bo.c | 169 +++++++++++++++++++++++++++++++++-------------- linux-core/drm_drv.c | 1 + linux-core/drm_objects.h | 3 +- 3 files changed, 122 insertions(+), 51 deletions(-) (limited to 'linux-core') diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index 75d89e46..53885a3e 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -80,8 +80,7 @@ void drm_bo_add_to_lru(struct drm_buffer_object * bo) DRM_ASSERT_LOCKED(&bo->dev->struct_mutex); - if (!(bo->mem.mask & (DRM_BO_FLAG_NO_MOVE | DRM_BO_FLAG_NO_EVICT)) - || bo->mem.mem_type != bo->pinned_mem_type) { + if (!bo->pinned || bo->mem.mem_type != bo->pinned_mem_type) { man = &bo->dev->bm.man[bo->mem.mem_type]; list_add_tail(&bo->lru, &man->lru); } else { @@ -733,7 +732,7 @@ static int drm_bo_mem_force_space(struct drm_device * dev, atomic_inc(&entry->usage); mutex_unlock(&dev->struct_mutex); mutex_lock(&entry->mutex); - BUG_ON(entry->mem.flags & (DRM_BO_FLAG_NO_MOVE | DRM_BO_FLAG_NO_EVICT)); + BUG_ON(entry->pinned); ret = drm_bo_evict(entry, mem_type, no_wait); mutex_unlock(&entry->mutex); @@ -893,18 +892,6 @@ static int drm_bo_new_mask(struct drm_buffer_object * bo, DRM_ERROR("User buffers are not supported yet\n"); return -EINVAL; } - if (bo->type == drm_bo_type_fake && - !(new_mask & (DRM_BO_FLAG_NO_MOVE | DRM_BO_FLAG_NO_EVICT))) { - DRM_ERROR("Fake buffers must be pinned.\n"); - return -EINVAL; - } - - if ((new_mask & DRM_BO_FLAG_NO_EVICT) && !DRM_SUSER(DRM_CURPROC)) { - DRM_ERROR - ("DRM_BO_FLAG_NO_EVICT is only available to priviliged " - "processes\n"); - return -EPERM; - } new_props = new_mask & (DRM_BO_FLAG_EXE | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_READ); @@ -1382,6 +1369,12 @@ static int drm_buffer_object_validate(struct drm_buffer_object * bo, return ret; } + if (bo->pinned && bo->pinned_mem_type != bo->mem.mem_type) { + DRM_ERROR("Attempt to validate pinned buffer into different memory " + "type\n"); + return -EINVAL; + } + /* * We're switching command submission mechanism, * or cannot simply rely on the hardware serializing for us. @@ -1425,37 +1418,6 @@ static int drm_buffer_object_validate(struct drm_buffer_object * bo, } } - /* - * Pinned buffers. - */ - - if (bo->mem.mask & (DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_NO_MOVE)) { - bo->pinned_mem_type = bo->mem.mem_type; - mutex_lock(&dev->struct_mutex); - list_del_init(&bo->pinned_lru); - drm_bo_add_to_pinned_lru(bo); - - if (bo->pinned_node != bo->mem.mm_node) { - if (bo->pinned_node != NULL) - drm_mm_put_block(bo->pinned_node); - bo->pinned_node = bo->mem.mm_node; - } - - mutex_unlock(&dev->struct_mutex); - - } else if (bo->pinned_node != NULL) { - - mutex_lock(&dev->struct_mutex); - - if (bo->pinned_node != bo->mem.mm_node) - drm_mm_put_block(bo->pinned_node); - - list_del_init(&bo->pinned_lru); - bo->pinned_node = NULL; - mutex_unlock(&dev->struct_mutex); - - } - /* * We might need to add a TTM. */ @@ -1533,6 +1495,10 @@ static int drm_bo_handle_validate(struct drm_file *file_priv, return ret; } +/** + * Fills out the generic buffer object ioctl reply with the information for + * the BO with id of handle. + */ static int drm_bo_handle_info(struct drm_file *file_priv, uint32_t handle, struct drm_bo_info_rep *rep) { @@ -1948,6 +1914,110 @@ int drm_bo_wait_idle_ioctl(struct drm_device *dev, void *data, struct drm_file * return 0; } +/** + * Pins or unpins the given buffer object in the given memory area. + * + * Pinned buffers will not be evicted from or move within their memory area. + * Must be called with the hardware lock held for pinning. + */ +static int +drm_bo_set_pin(struct drm_device *dev, struct drm_buffer_object *bo, + int pin) +{ + int ret = 0; + + mutex_lock(&bo->mutex); + if (bo->pinned == pin) { + mutex_unlock(&bo->mutex); + return 0; + } + + if (pin) { + ret = drm_bo_wait_unfenced(bo, 0, 0); + if (ret) { + mutex_unlock(&bo->mutex); + return ret; + } + + /* Validate the buffer into its pinned location, with no pending + * fence. + */ + ret = drm_buffer_object_validate(bo, 0, 0, 0); + if (ret) { + mutex_unlock(&bo->mutex); + return ret; + } + + /* Add our buffer to the pinned list */ + bo->pinned_mem_type = bo->mem.mem_type; + mutex_lock(&dev->struct_mutex); + list_del_init(&bo->pinned_lru); + drm_bo_add_to_pinned_lru(bo); + + if (bo->pinned_node != bo->mem.mm_node) { + if (bo->pinned_node != NULL) + drm_mm_put_block(bo->pinned_node); + bo->pinned_node = bo->mem.mm_node; + } + + mutex_unlock(&dev->struct_mutex); + + } else { + mutex_lock(&dev->struct_mutex); + + /* Remove our buffer from the pinned list */ + if (bo->pinned_node != bo->mem.mm_node) + drm_mm_put_block(bo->pinned_node); + + list_del_init(&bo->pinned_lru); + bo->pinned_node = NULL; + mutex_unlock(&dev->struct_mutex); + } + bo->pinned = pin; + mutex_unlock(&bo->mutex); + return 0; +} + +int drm_bo_set_pin_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_bo_set_pin_arg *arg = data; + struct drm_bo_set_pin_req *req = &arg->d.req; + struct drm_bo_info_rep *rep = &arg->d.rep; + struct drm_buffer_object *bo; + int ret; + + if (!dev->bm.initialized) { + DRM_ERROR("Buffer object manager is not initialized.\n"); + return -EINVAL; + } + + if (req->pin < 0 || req->pin > 1) { + DRM_ERROR("Bad arguments to set_pin\n"); + return -EINVAL; + } + + if (req->pin) + LOCK_TEST_WITH_RETURN(dev, file_priv); + + mutex_lock(&dev->struct_mutex); + bo = drm_lookup_buffer_object(file_priv, req->handle, 1); + mutex_unlock(&dev->struct_mutex); + if (!bo) { + return -EINVAL; + } + + ret = drm_bo_set_pin(dev, bo, req->pin); + if (ret) { + drm_bo_usage_deref_unlocked(&bo); + return ret; + } + + drm_bo_fill_rep_arg(bo, rep); + drm_bo_usage_deref_unlocked(&bo); + + return 0; +} /** @@ -2009,11 +2079,10 @@ static int drm_bo_leave_list(struct drm_buffer_object * bo, mutex_unlock(&dev->struct_mutex); } - if (bo->mem.flags & DRM_BO_FLAG_NO_EVICT) { - DRM_ERROR("A DRM_BO_NO_EVICT buffer present at " + if (bo->pinned) { + DRM_ERROR("A pinned buffer was present at " "cleanup. Removing flag and evicting.\n"); - bo->mem.flags &= ~DRM_BO_FLAG_NO_EVICT; - bo->mem.mask &= ~DRM_BO_FLAG_NO_EVICT; + bo->pinned = 0; } if (bo->mem.mem_type == mem_type) diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index cc676bda..93dfcdb5 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -147,6 +147,7 @@ static struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_BO_OP, drm_bo_op_ioctl, DRM_AUTH), DRM_IOCTL_DEF(DRM_IOCTL_BO_INFO, drm_bo_info_ioctl, DRM_AUTH), DRM_IOCTL_DEF(DRM_IOCTL_BO_WAIT_IDLE, drm_bo_wait_idle_ioctl, DRM_AUTH), + DRM_IOCTL_DEF(DRM_IOCTL_BO_SET_PIN, drm_bo_set_pin_ioctl, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY), }; #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) diff --git a/linux-core/drm_objects.h b/linux-core/drm_objects.h index e5f2b69c..64f71651 100644 --- a/linux-core/drm_objects.h +++ b/linux-core/drm_objects.h @@ -362,6 +362,7 @@ struct drm_buffer_object { struct mutex mutex; /* For pinned buffers */ + int pinned; struct drm_mm_node *pinned_node; uint32_t pinned_mem_type; struct list_head pinned_lru; @@ -455,7 +456,7 @@ extern int drm_bo_unreference_ioctl(struct drm_device *dev, void *data, struct d extern int drm_bo_wait_idle_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int drm_bo_info_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int drm_bo_op_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); - +int drm_bo_set_pin_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int drm_mm_init_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int drm_mm_takedown_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); -- cgit v1.2.3 From f9c27aa50b715a7d21858f1ce9e4785120bd0c36 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 26 Jul 2007 11:17:41 -0700 Subject: Copy the important parts of object_validate into object_create(). This should let us allocate buffers without holding the hardware lock. While here, add DRM_DEBUG info for the drm_bo ioctls, so you can see something more specific than just the cmd value per ioctl. --- linux-core/drm_bo.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 56 insertions(+), 5 deletions(-) (limited to 'linux-core') diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index 53885a3e..a2356c8a 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -1565,6 +1565,7 @@ int drm_buffer_object_create(struct drm_device *dev, { struct drm_buffer_manager *bm = &dev->bm; struct drm_buffer_object *bo; + struct drm_bo_driver *driver = dev->driver->bo_driver; int ret = 0; unsigned long num_pages; @@ -1624,10 +1625,28 @@ int drm_buffer_object_create(struct drm_device *dev, if (ret) goto out_err; } - ret = drm_buffer_object_validate(bo, 0, 0, hint & DRM_BO_HINT_DONT_BLOCK); + + bo->fence_class = 0; + ret = driver->fence_type(bo, &bo->fence_type); + if (ret) { + DRM_ERROR("Driver did not support given buffer permissions\n"); + goto out_err; + } + + if (bo->type == drm_bo_type_fake) { + ret = drm_bo_check_fake(dev, &bo->mem); + if (ret) + goto out_err; + } + + ret = drm_bo_add_ttm(bo); if (ret) goto out_err; + mutex_lock(&dev->struct_mutex); + drm_bo_add_to_lru(bo); + mutex_unlock(&dev->struct_mutex); + mutex_unlock(&bo->mutex); *buf_obj = bo; return 0; @@ -1677,6 +1696,8 @@ int drm_bo_op_ioctl(struct drm_device *dev, void *data, struct drm_file *file_pr void __user *curuserarg = NULL; int ret; + DRM_DEBUG("drm_bo_op_ioctl\n"); + if (!dev->bm.initialized) { DRM_ERROR("Buffer object manager is not initialized.\n"); return -EINVAL; @@ -1749,14 +1770,15 @@ int drm_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *fil struct drm_buffer_object *entry; int ret = 0; + DRM_DEBUG("drm_bo_create_ioctl: %dkb, %dkb align, %d type\n", + (int)(req->size / 1024), req->page_alignment * 4, req->type); + if (!dev->bm.initialized) { DRM_ERROR("Buffer object manager is not initialized.\n"); return -EINVAL; } - - ret = drm_bo_lock_test(dev, file_priv); - if (ret) - goto out; + if (req->type == drm_bo_type_fake) + LOCK_TEST_WITH_RETURN(dev, file_priv); ret = drm_buffer_object_create(file_priv->head->dev, req->size, req->type, req->mask, @@ -1787,6 +1809,8 @@ int drm_bo_destroy_ioctl(struct drm_device *dev, void *data, struct drm_file *fi struct drm_user_object *uo; int ret = 0; + DRM_DEBUG("drm_bo_destroy_ioctl: buffer %d\n", arg->handle); + if (!dev->bm.initialized) { DRM_ERROR("Buffer object manager is not initialized.\n"); return -EINVAL; @@ -1810,6 +1834,9 @@ int drm_bo_map_ioctl(struct drm_device *dev, void *data, struct drm_file *file_p struct drm_bo_info_req *req = &arg->d.req; struct drm_bo_info_rep *rep = &arg->d.rep; int ret; + + DRM_DEBUG("drm_bo_map_ioctl: buffer %d\n", req->handle); + if (!dev->bm.initialized) { DRM_ERROR("Buffer object manager is not initialized.\n"); return -EINVAL; @@ -1827,6 +1854,9 @@ int drm_bo_unmap_ioctl(struct drm_device *dev, void *data, struct drm_file *file { struct drm_bo_handle_arg *arg = data; int ret; + + DRM_DEBUG("drm_bo_unmap_ioctl: buffer %d\n", arg->handle); + if (!dev->bm.initialized) { DRM_ERROR("Buffer object manager is not initialized.\n"); return -EINVAL; @@ -1845,6 +1875,8 @@ int drm_bo_reference_ioctl(struct drm_device *dev, void *data, struct drm_file * struct drm_user_object *uo; int ret; + DRM_DEBUG("drm_bo_reference_ioctl: buffer %d\n", req->handle); + if (!dev->bm.initialized) { DRM_ERROR("Buffer object manager is not initialized.\n"); return -EINVAL; @@ -1867,6 +1899,8 @@ int drm_bo_unreference_ioctl(struct drm_device *dev, void *data, struct drm_file struct drm_bo_handle_arg *arg = data; int ret = 0; + DRM_DEBUG("drm_bo_unreference_ioctl: buffer %d\n", arg->handle); + if (!dev->bm.initialized) { DRM_ERROR("Buffer object manager is not initialized.\n"); return -EINVAL; @@ -1883,6 +1917,8 @@ int drm_bo_info_ioctl(struct drm_device *dev, void *data, struct drm_file *file_ struct drm_bo_info_rep *rep = &arg->d.rep; int ret; + DRM_DEBUG("drm_bo_info_ioctl: buffer %d\n", req->handle); + if (!dev->bm.initialized) { DRM_ERROR("Buffer object manager is not initialized.\n"); return -EINVAL; @@ -1901,6 +1937,9 @@ int drm_bo_wait_idle_ioctl(struct drm_device *dev, void *data, struct drm_file * struct drm_bo_info_req *req = &arg->d.req; struct drm_bo_info_rep *rep = &arg->d.rep; int ret; + + DRM_DEBUG("drm_bo_wait_idle_ioctl: buffer %d\n", req->handle); + if (!dev->bm.initialized) { DRM_ERROR("Buffer object manager is not initialized.\n"); return -EINVAL; @@ -1987,6 +2026,9 @@ int drm_bo_set_pin_ioctl(struct drm_device *dev, void *data, struct drm_buffer_object *bo; int ret; + DRM_DEBUG("drm_bo_set_pin_ioctl: buffer %d, pin %d\n", + req->handle, req->pin); + if (!dev->bm.initialized) { DRM_ERROR("Buffer object manager is not initialized.\n"); return -EINVAL; @@ -2395,6 +2437,9 @@ int drm_mm_init_ioctl(struct drm_device *dev, void *data, struct drm_file *file_ struct drm_bo_driver *driver = dev->driver->bo_driver; int ret; + DRM_DEBUG("drm_mm_init_ioctl: type %d, 0x%08llx offset, %dkb\n", + arg->mem_type, arg->p_offset * PAGE_SIZE, (int)(arg->p_size * 4)); + if (!driver) { DRM_ERROR("Buffer objects are not supported by this driver\n"); return -EINVAL; @@ -2449,6 +2494,8 @@ int drm_mm_takedown_ioctl(struct drm_device *dev, void *data, struct drm_file *f struct drm_bo_driver *driver = dev->driver->bo_driver; int ret; + DRM_DEBUG("drm_mm_takedown_ioctl: %d type\n", arg->mem_type); + if (!driver) { DRM_ERROR("Buffer objects are not supported by this driver\n"); return -EINVAL; @@ -2486,6 +2533,8 @@ int drm_mm_lock_ioctl(struct drm_device *dev, void *data, struct drm_file *file_ struct drm_bo_driver *driver = dev->driver->bo_driver; int ret; + DRM_DEBUG("drm_mm_lock_ioctl: %d type\n", arg->mem_type); + if (!driver) { DRM_ERROR("Buffer objects are not supported by this driver\n"); return -EINVAL; @@ -2508,6 +2557,8 @@ int drm_mm_unlock_ioctl(struct drm_device *dev, void *data, struct drm_file *fil struct drm_bo_driver *driver = dev->driver->bo_driver; int ret; + DRM_DEBUG("drm_mm_unlock_ioctl\n"); + if (!driver) { DRM_ERROR("Buffer objects are not supported by this driver\n"); return -EINVAL; -- cgit v1.2.3 From 3c8ebd94e48589711f44d23e85d713a1ed980f37 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 26 Jul 2007 11:26:12 -0700 Subject: debug print ioctl return value as -integer rather than fffffwhatever. --- linux-core/drm_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux-core') diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index 93dfcdb5..816b8a20 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -648,7 +648,7 @@ int drm_ioctl(struct inode *inode, struct file *filp, err_i1: atomic_dec(&dev->ioctl_count); if (retcode) - DRM_DEBUG("ret = %x\n", retcode); + DRM_DEBUG("ret = %d\n", retcode); return retcode; } EXPORT_SYMBOL(drm_ioctl); -- cgit v1.2.3 From cf4f1a85af69c2c2e5ba9c822d30863f16ce6821 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 2 Aug 2007 13:51:55 -0700 Subject: Add a couple of doxygen comments from reading the code. --- linux-core/drm_bo.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'linux-core') diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index a2356c8a..4ce5f480 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -705,6 +705,10 @@ static int drm_bo_evict(struct drm_buffer_object * bo, unsigned mem_type, return ret; } +/** + * Repeatedly evict memory from the LRU for @mem_type until we create enough + * space, or we've evicted everything and there isn't enough space. + */ static int drm_bo_mem_force_space(struct drm_device * dev, struct drm_bo_mem_reg * mem, uint32_t mem_type, int no_wait) @@ -791,6 +795,14 @@ static int drm_bo_mt_compatible(struct drm_mem_type_manager * man, return 1; } +/** + * Creates space for memory region @mem according to its type. + * + * This function first searches for free space in compatible memory types in + * the priority order defined by the driver. If free space isn't found, then + * drm_bo_mem_force_space is attempted in priority order to evict and find + * space. + */ int drm_bo_mem_space(struct drm_buffer_object * bo, struct drm_bo_mem_reg * mem, int no_wait) { @@ -2406,8 +2418,7 @@ int drm_bo_driver_init(struct drm_device * dev) * Initialize the system memory buffer type. * Other types need to be driver / IOCTL initialized. */ - - ret = drm_bo_init_mm(dev, 0, 0, 0); + ret = drm_bo_init_mm(dev, DRM_BO_MEM_LOCAL, 0, 0); if (ret) goto out_unlock; -- cgit v1.2.3 From 3a0bc518e35c62bb9c64c9105f836584d949653f Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 2 Aug 2007 14:08:04 -0700 Subject: Remove the pinned buffer from the LRU when pinning. Also, be a little safer with setting the pinned flag within the struct lock. I'm not 100% sure if this is required, but it seems like it might be. --- linux-core/Makefile | 1 + linux-core/drm_bo.c | 12 ++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'linux-core') diff --git a/linux-core/Makefile b/linux-core/Makefile index 1758777c..46c821a4 100644 --- a/linux-core/Makefile +++ b/linux-core/Makefile @@ -268,6 +268,7 @@ PAGE_AGP := $(shell cat $(LINUXDIR)/include/asm/agp.h 2>/dev/null | \ ifneq ($(PAGE_AGP),0) EXTRA_CFLAGS += -DHAVE_PAGE_AGP endif +EXTRA_CFLAGS += -g -O0 # Start with all modules turned off. CONFIG_DRM_GAMMA := n diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index 4ce5f480..53fb5afc 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -1990,8 +1990,8 @@ drm_bo_set_pin(struct drm_device *dev, struct drm_buffer_object *bo, return ret; } - /* Validate the buffer into its pinned location, with no pending - * fence. + /* Validate the buffer into its pinned location, with no + * pending fence. */ ret = drm_buffer_object_validate(bo, 0, 0, 0); if (ret) { @@ -1999,9 +1999,12 @@ drm_bo_set_pin(struct drm_device *dev, struct drm_buffer_object *bo, return ret; } - /* Add our buffer to the pinned list */ + /* Pull the buffer off of the LRU and add it to the pinned + * list + */ bo->pinned_mem_type = bo->mem.mem_type; mutex_lock(&dev->struct_mutex); + list_del_init(&bo->lru); list_del_init(&bo->pinned_lru); drm_bo_add_to_pinned_lru(bo); @@ -2011,6 +2014,7 @@ drm_bo_set_pin(struct drm_device *dev, struct drm_buffer_object *bo, bo->pinned_node = bo->mem.mm_node; } + bo->pinned = pin; mutex_unlock(&dev->struct_mutex); } else { @@ -2022,9 +2026,9 @@ drm_bo_set_pin(struct drm_device *dev, struct drm_buffer_object *bo, list_del_init(&bo->pinned_lru); bo->pinned_node = NULL; + bo->pinned = pin; mutex_unlock(&dev->struct_mutex); } - bo->pinned = pin; mutex_unlock(&bo->mutex); return 0; } -- cgit v1.2.3