From 12b989a7108a52f16b1b1bb6dd2ea818c235b52c Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Thu, 4 Oct 2007 09:51:01 +0200 Subject: Revert "Remove the pinned buffer from the LRU when pinning." This reverts 3a0bc518e35c62bb9c64c9105f836584d949653f commit. --- linux-core/drm_bo.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'linux-core/drm_bo.c') diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index fb360e7f..099ebe07 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -1965,8 +1965,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, bo->fence_class, 0, 0); if (ret) { @@ -1974,12 +1974,9 @@ drm_bo_set_pin(struct drm_device *dev, struct drm_buffer_object *bo, return ret; } - /* Pull the buffer off of the LRU and add it to the pinned - * list - */ + /* Add our buffer 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); @@ -1989,7 +1986,6 @@ 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 { @@ -2001,9 +1997,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 From cd276d9cab0be8eff2d9450e5c95b6eb3cd639af Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Thu, 4 Oct 2007 10:01:30 +0200 Subject: Revert "Copy the important parts of object_validate into object_create()." This reverts f9c27aa50b715a7d21858f1ce9e4785120bd0c36 commit. --- linux-core/drm_bo.c | 44 +++++++++----------------------------------- 1 file changed, 9 insertions(+), 35 deletions(-) (limited to 'linux-core/drm_bo.c') diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index 099ebe07..6e1de80b 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -1587,7 +1587,6 @@ 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; @@ -1646,7 +1645,7 @@ int drm_buffer_object_create(struct drm_device *dev, if (ret) goto out_err; } - +#if 0 bo->fence_class = 0; ret = driver->fence_type(bo, &bo->fence_class, &bo->fence_type); if (ret) { @@ -1655,13 +1654,12 @@ int drm_buffer_object_create(struct drm_device *dev, } ret = drm_bo_add_ttm(bo); +#else + ret = drm_buffer_object_validate(bo, 0, 0, hint & DRM_BO_HINT_DONT_BLOCK); +#endif 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; @@ -1711,8 +1709,6 @@ 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; @@ -1792,6 +1788,11 @@ int drm_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *fil DRM_ERROR("Buffer object manager is not initialized.\n"); return -EINVAL; } +#if 0 + ret = drm_bo_lock_test(dev, file_priv); + if (ret) + goto out; +#endif ret = drm_buffer_object_create(file_priv->head->dev, req->size, drm_bo_type_dc, req->mask, @@ -1821,9 +1822,6 @@ 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; @@ -1841,9 +1839,6 @@ 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; @@ -1862,8 +1857,6 @@ 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; @@ -1886,8 +1879,6 @@ 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; @@ -1904,8 +1895,6 @@ 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; @@ -1924,9 +1913,6 @@ 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; @@ -2013,9 +1999,6 @@ 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; @@ -2445,9 +2428,6 @@ 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; @@ -2502,8 +2482,6 @@ 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; @@ -2541,8 +2519,6 @@ 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; @@ -2565,8 +2541,6 @@ 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 0d1926d36e59ddfc34d8c9c0cdef10b71a49ecf1 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Thu, 4 Oct 2007 10:14:41 +0200 Subject: Revert "Replace NO_MOVE/NO_EVICT flags to buffer objects with an ioctl to set pinning." This reverts cf2d569daca6954d11a796f4d110148ae2e0c827 commit. --- linux-core/drm_bo.c | 174 +++++++++++++++------------------------------------- 1 file changed, 51 insertions(+), 123 deletions(-) (limited to 'linux-core/drm_bo.c') diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index 6e1de80b..7335d258 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -80,7 +80,8 @@ void drm_bo_add_to_lru(struct drm_buffer_object * bo) DRM_ASSERT_LOCKED(&bo->dev->struct_mutex); - if (!bo->pinned || bo->mem.mem_type != bo->pinned_mem_type) { + if (!(bo->mem.mask & (DRM_BO_FLAG_NO_MOVE | DRM_BO_FLAG_NO_EVICT)) + || 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 { @@ -638,8 +639,7 @@ int drm_fence_buffer_objects(struct drm_device *dev, mutex_lock(&entry->mutex); mutex_lock(&dev->struct_mutex); list_del_init(l); - if (entry->priv_flags & _DRM_BO_FLAG_UNFENCED && - entry->fence_class == fence_class) { + if (entry->priv_flags & _DRM_BO_FLAG_UNFENCED) { count++; if (entry->fence) drm_fence_usage_deref_locked(&entry->fence); @@ -761,7 +761,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->pinned); + BUG_ON(entry->mem.flags & (DRM_BO_FLAG_NO_MOVE | DRM_BO_FLAG_NO_EVICT)); ret = drm_bo_evict(entry, mem_type, no_wait); mutex_unlock(&entry->mutex); @@ -929,6 +929,18 @@ 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); @@ -1372,12 +1384,6 @@ 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. @@ -1418,6 +1424,37 @@ 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. */ @@ -1517,10 +1554,6 @@ int drm_bo_handle_validate(struct drm_file * file_priv, uint32_t handle, } EXPORT_SYMBOL(drm_bo_handle_validate); -/** - * 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) { @@ -1926,112 +1959,6 @@ 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, bo->fence_class, 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; -} - - /** *Clean the unfenced list and put on regular LRU. *This is part of the memory manager cleanup and should only be @@ -2112,10 +2039,11 @@ static int drm_bo_leave_list(struct drm_buffer_object * bo, mutex_unlock(&dev->struct_mutex); } - if (bo->pinned) { - DRM_ERROR("A pinned buffer was present at " + if (bo->mem.flags & DRM_BO_FLAG_NO_EVICT) { + DRM_ERROR("A DRM_BO_NO_EVICT buffer present at " "cleanup. Removing flag and evicting.\n"); - bo->pinned = 0; + bo->mem.flags &= ~DRM_BO_FLAG_NO_EVICT; + bo->mem.mask &= ~DRM_BO_FLAG_NO_EVICT; } if (bo->mem.mem_type == mem_type) -- cgit v1.2.3 From 086c058a417317491320129d2cbeb68d1cfcfefe Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 17 Oct 2007 10:55:21 +0200 Subject: Remove the op ioctl, and replace it with a setuser ioctl. Remove need for lock for now. May create races when we clean memory areas or on takedown. Needs to be fixed. Really do a validate on buffer creation in order to avoid problems with fixed memory buffers. --- linux-core/drm_bo.c | 146 ++++++++++++++-------------------------------------- 1 file changed, 39 insertions(+), 107 deletions(-) (limited to 'linux-core/drm_bo.c') diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index 7335d258..bdeefec2 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -929,11 +929,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 @@ -942,6 +937,12 @@ static int drm_bo_new_mask(struct drm_buffer_object * bo, return -EPERM; } + if ((new_mask & DRM_BO_FLAG_NO_MOVE)) { + DRM_ERROR + ("DRM_BO_FLAG_NO_MOVE is not properly implemented yet.\n"); + return -EPERM; + } + new_props = new_mask & (DRM_BO_FLAG_EXE | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_READ); @@ -1160,11 +1161,9 @@ static int drm_buffer_object_map(struct drm_file *file_priv, uint32_t handle, return -EINVAL; mutex_lock(&bo->mutex); - if (!(hint & DRM_BO_HINT_ALLOW_UNFENCED_MAP)) { - ret = drm_bo_wait_unfenced(bo, no_wait, 0); - if (ret) - goto out; - } + ret = drm_bo_wait_unfenced(bo, no_wait, 0); + if (ret) + goto out; /* * If this returns true, we are currently unmapped. @@ -1542,6 +1541,7 @@ int drm_bo_handle_validate(struct drm_file * file_priv, uint32_t handle, return -EINVAL; } + ret = drm_bo_do_validate(bo, flags, mask, hint, fence_class, no_wait, rep); @@ -1663,8 +1663,10 @@ int drm_buffer_object_create(struct drm_device *dev, bo->mem.page_alignment = page_alignment; bo->buffer_start = buffer_start; bo->priv_flags = 0; - bo->mem.flags = 0ULL; - bo->mem.mask = 0ULL; + bo->mem.flags = DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED | + DRM_BO_FLAG_MAPPABLE; + bo->mem.mask = DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED | + DRM_BO_FLAG_MAPPABLE; atomic_inc(&bm->count); ret = drm_bo_new_mask(bo, mask, hint); @@ -1678,18 +1680,8 @@ int drm_buffer_object_create(struct drm_device *dev, if (ret) goto out_err; } -#if 0 - bo->fence_class = 0; - ret = driver->fence_type(bo, &bo->fence_class, &bo->fence_type); - if (ret) { - DRM_ERROR("Driver did not support given buffer permissions\n"); - goto out_err; - } - ret = drm_bo_add_ttm(bo); -#else ret = drm_buffer_object_validate(bo, 0, 0, hint & DRM_BO_HINT_DONT_BLOCK); -#endif if (ret) goto out_err; @@ -1705,6 +1697,7 @@ int drm_buffer_object_create(struct drm_device *dev, } EXPORT_SYMBOL(drm_buffer_object_create); + static int drm_bo_add_user_object(struct drm_file *file_priv, struct drm_buffer_object *bo, int shareable) { @@ -1726,86 +1719,6 @@ static int drm_bo_add_user_object(struct drm_file *file_priv, return ret; } -static int drm_bo_lock_test(struct drm_device * dev, struct drm_file *file_priv) -{ - LOCK_TEST_WITH_RETURN(dev, file_priv); - return 0; -} - -int drm_bo_op_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_bo_op_arg curarg; - struct drm_bo_op_arg *arg = data; - struct drm_bo_op_req *req = &arg->d.req; - struct drm_bo_info_rep rep; - unsigned long next = 0; - void __user *curuserarg = NULL; - int ret; - - if (!dev->bm.initialized) { - DRM_ERROR("Buffer object manager is not initialized.\n"); - return -EINVAL; - } - - do { - if (next != 0) { - curuserarg = (void __user *)next; - if (copy_from_user(&curarg, curuserarg, - sizeof(curarg)) != 0) - return -EFAULT; - arg = &curarg; - } - - if (arg->handled) { - next = arg->next; - continue; - } - req = &arg->d.req; - ret = 0; - switch (req->op) { - case drm_bo_validate: - ret = drm_bo_lock_test(dev, file_priv); - if (ret) - break; - ret = drm_bo_handle_validate(file_priv, req->bo_req.handle, - req->bo_req.fence_class, - req->bo_req.flags, - req->bo_req.mask, - req->bo_req.hint, - &rep, NULL); - break; - case drm_bo_fence: - ret = -EINVAL; - DRM_ERROR("Function is not implemented yet.\n"); - break; - case drm_bo_ref_fence: - ret = -EINVAL; - DRM_ERROR("Function is not implemented yet.\n"); - break; - default: - ret = -EINVAL; - } - next = arg->next; - - /* - * A signal interrupted us. Make sure the ioctl is restartable. - */ - - if (ret == -EAGAIN) - return -EAGAIN; - - arg->handled = 1; - arg->d.rep.ret = ret; - arg->d.rep.bo_info = rep; - if (arg != data) { - if (copy_to_user(curuserarg, &curarg, - sizeof(curarg)) != 0) - return -EFAULT; - } - } while (next != 0); - return 0; -} - int drm_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_bo_create_arg *arg = data; @@ -1821,11 +1734,6 @@ int drm_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *fil DRM_ERROR("Buffer object manager is not initialized.\n"); return -EINVAL; } -#if 0 - ret = drm_bo_lock_test(dev, file_priv); - if (ret) - goto out; -#endif ret = drm_buffer_object_create(file_priv->head->dev, req->size, drm_bo_type_dc, req->mask, @@ -1849,6 +1757,30 @@ out: return ret; } +int drm_bo_setstatus_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv) +{ + struct drm_bo_map_wait_idle_arg *arg = data; + struct drm_bo_info_req *req = &arg->d.req; + struct drm_bo_info_rep *rep = &arg->d.rep; + int ret; + if (!dev->bm.initialized) { + DRM_ERROR("Buffer object manager is not initialized.\n"); + return -EINVAL; + } + + ret = drm_bo_handle_validate(file_priv, req->handle, req->fence_class, + req->flags, + req->mask, + req->hint | DRM_BO_HINT_DONT_FENCE, + rep, NULL); + + if (ret) + return ret; + + return 0; +} + int drm_bo_map_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_bo_map_wait_idle_arg *arg = data; -- cgit v1.2.3 From bb29ba7fa77659be284c365ebfb2f740491e8506 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 17 Oct 2007 10:57:12 +0200 Subject: Only allow creator to change shared buffer mask. --- linux-core/drm_bo.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'linux-core/drm_bo.c') diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index bdeefec2..d40be07f 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -1540,8 +1540,16 @@ int drm_bo_handle_validate(struct drm_file * file_priv, uint32_t handle, if (!bo) { return -EINVAL; } - + /* + * Only allow creator to change shared buffer mask. + */ + + if (bo->base.owner != file_priv) { + flags = 0x0; + mask = 0x0; + } + ret = drm_bo_do_validate(bo, flags, mask, hint, fence_class, no_wait, rep); -- cgit v1.2.3 From cf2d1bba5513ae38d8efbaf50251fc136ed1d414 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Fri, 19 Oct 2007 16:24:36 +0200 Subject: Remove the clean_unfenced function. Change the restriction that non-creators can't change the buffer flags to non-creators can't change EVICT and NO_MOVE flags. --- linux-core/drm_bo.c | 65 ++++------------------------------------------------- 1 file changed, 4 insertions(+), 61 deletions(-) (limited to 'linux-core/drm_bo.c') diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index d40be07f..89c014e3 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -1545,10 +1545,9 @@ int drm_bo_handle_validate(struct drm_file * file_priv, uint32_t handle, * Only allow creator to change shared buffer mask. */ - if (bo->base.owner != file_priv) { - flags = 0x0; - mask = 0x0; - } + if (bo->base.owner != file_priv) + mask &= ~(DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_NO_MOVE); + ret = drm_bo_do_validate(bo, flags, mask, hint, fence_class, no_wait, rep); @@ -1899,60 +1898,6 @@ int drm_bo_wait_idle_ioctl(struct drm_device *dev, void *data, struct drm_file * return 0; } -/** - *Clean the unfenced list and put on regular LRU. - *This is part of the memory manager cleanup and should only be - *called with the DRI lock held. - *Call dev->struct_sem locked. - */ - -static void drm_bo_clean_unfenced(struct drm_device *dev) -{ - struct drm_buffer_manager *bm = &dev->bm; - struct list_head *head, *list; - struct drm_buffer_object *entry; - struct drm_fence_object *fence; - - head = &bm->unfenced; - - if (list_empty(head)) - return; - - DRM_ERROR("Clean unfenced\n"); - - if (drm_fence_buffer_objects(dev, NULL, 0, NULL, &fence)) { - - /* - * Fixme: Should really wait here. - */ - } - - if (fence) - drm_fence_usage_deref_locked(&fence); - - if (list_empty(head)) - return; - - DRM_ERROR("Really clean unfenced\n"); - - list = head->next; - while(list != head) { - prefetch(list->next); - entry = list_entry(list, struct drm_buffer_object, lru); - - atomic_inc(&entry->usage); - mutex_unlock(&dev->struct_mutex); - mutex_lock(&entry->mutex); - mutex_lock(&dev->struct_mutex); - - list_del(&entry->lru); - DRM_FLAG_MASKED(entry->priv_flags, 0, _DRM_BO_FLAG_UNFENCED); - drm_bo_add_to_lru(entry); - mutex_unlock(&entry->mutex); - list = head->next; - } -} - static int drm_bo_leave_list(struct drm_buffer_object * bo, uint32_t mem_type, int free_pinned, int allow_errors) @@ -2103,8 +2048,7 @@ int drm_bo_clean_mm(struct drm_device * dev, unsigned mem_type) ret = 0; if (mem_type > 0) { - - drm_bo_clean_unfenced(dev); + BUG_ON(!list_empty(&bm->unfenced)); drm_bo_force_list_clean(dev, &man->lru, mem_type, 1, 0, 0); drm_bo_force_list_clean(dev, &man->pinned, mem_type, 1, 0, 1); @@ -2142,7 +2086,6 @@ static int drm_bo_lock_mm(struct drm_device * dev, unsigned mem_type) return 0; } - drm_bo_clean_unfenced(dev); ret = drm_bo_force_list_clean(dev, &man->lru, mem_type, 0, 1, 0); if (ret) return ret; -- cgit v1.2.3 From 733ff568346e8fe40e9790f21f8b7efc659d5d12 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Fri, 19 Oct 2007 16:28:47 +0200 Subject: No fence_class argument on drmBOSetStatus since it's not associated with a particular command submission. --- linux-core/drm_bo.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'linux-core/drm_bo.c') diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index 89c014e3..cc4743dc 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -1524,7 +1524,9 @@ EXPORT_SYMBOL(drm_bo_do_validate); int drm_bo_handle_validate(struct drm_file * file_priv, uint32_t handle, uint32_t fence_class, - uint64_t flags, uint64_t mask, uint32_t hint, + uint64_t flags, uint64_t mask, + uint32_t hint, + int use_old_fence_class, struct drm_bo_info_rep * rep, struct drm_buffer_object **bo_rep) { @@ -1537,10 +1539,12 @@ int drm_bo_handle_validate(struct drm_file * file_priv, uint32_t handle, bo = drm_lookup_buffer_object(file_priv, handle, 1); mutex_unlock(&dev->struct_mutex); - if (!bo) { + if (!bo) return -EINVAL; - } - + + if (use_old_fence_class) + fence_class = bo->fence_class; + /* * Only allow creator to change shared buffer mask. */ @@ -1780,6 +1784,7 @@ int drm_bo_setstatus_ioctl(struct drm_device *dev, req->flags, req->mask, req->hint | DRM_BO_HINT_DONT_FENCE, + 1, rep, NULL); if (ret) -- cgit v1.2.3 From c0e3537e77f1765001f665f93e5349ccd0f1d092 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Fri, 19 Oct 2007 16:44:12 +0200 Subject: Some comment updates pending removal of the init mutex. --- linux-core/drm_bo.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'linux-core/drm_bo.c') diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index cc4743dc..35ac8a0a 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -1072,13 +1072,6 @@ static int drm_bo_check_unfenced(struct drm_buffer_object * bo) /* * Wait until a buffer, scheduled to be fenced moves off the unfenced list. * Until then, we cannot really do anything with it except delete it. - * The unfenced list is a PITA, and the operations - * 1) validating - * 2) submitting commands - * 3) fencing - * Should really be an atomic operation. - * We now "solve" this problem by keeping - * the buffer "unfenced" after validating, but before fencing. */ static int drm_bo_wait_unfenced(struct drm_buffer_object * bo, int no_wait, @@ -2144,8 +2137,10 @@ int drm_bo_init_mm(struct drm_device * dev, EXPORT_SYMBOL(drm_bo_init_mm); /* - * This is called from lastclose, so we don't need to bother about - * any clients still running when we set the initialized flag to zero. + * This function is intended to be called on drm driver unload. + * If you decide to call it from lastclose, you must protect the call + * from a potentially racing drm_bo_driver_init in firstopen. + * (This may happen on X server restart). */ int drm_bo_driver_finish(struct drm_device * dev) @@ -2199,6 +2194,13 @@ int drm_bo_driver_finish(struct drm_device * dev) return ret; } +/* + * This function is intended to be called on drm driver load. + * If you decide to call it from firstopen, you must protect the call + * from a potentially racing drm_bo_driver_finish in lastclose. + * (This may happen on X server restart). + */ + int drm_bo_driver_init(struct drm_device * dev) { struct drm_bo_driver *driver = dev->driver->bo_driver; -- cgit v1.2.3 From 48b5eaf303b60077faed09db77785d7a544ac335 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Sat, 20 Oct 2007 16:49:43 +0200 Subject: Simple replacement for hardware lock in some cases. Fix i915 since last commit. --- linux-core/drm_bo.c | 65 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 25 deletions(-) (limited to 'linux-core/drm_bo.c') diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index 35ac8a0a..a2a0291d 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -1768,11 +1768,16 @@ int drm_bo_setstatus_ioctl(struct drm_device *dev, struct drm_bo_info_req *req = &arg->d.req; struct drm_bo_info_rep *rep = &arg->d.rep; int ret; + if (!dev->bm.initialized) { DRM_ERROR("Buffer object manager is not initialized.\n"); return -EINVAL; } + ret = drm_bo_read_lock(&dev->bm.bm_lock); + if (ret) + return ret; + ret = drm_bo_handle_validate(file_priv, req->handle, req->fence_class, req->flags, req->mask, @@ -1780,6 +1785,7 @@ int drm_bo_setstatus_ioctl(struct drm_device *dev, 1, rep, NULL); + (void) drm_bo_read_unlock(&dev->bm.bm_lock); if (ret) return ret; @@ -1898,7 +1904,8 @@ int drm_bo_wait_idle_ioctl(struct drm_device *dev, void *data, struct drm_file * static int drm_bo_leave_list(struct drm_buffer_object * bo, uint32_t mem_type, - int free_pinned, int allow_errors) + int free_pinned, + int allow_errors) { struct drm_device *dev = bo->dev; int ret = 0; @@ -2150,7 +2157,6 @@ int drm_bo_driver_finish(struct drm_device * dev) unsigned i = DRM_BO_MEM_TYPES; struct drm_mem_type_manager *man; - mutex_lock(&dev->bm.init_mutex); mutex_lock(&dev->struct_mutex); if (!bm->initialized) @@ -2190,7 +2196,6 @@ int drm_bo_driver_finish(struct drm_device * dev) } out: mutex_unlock(&dev->struct_mutex); - mutex_unlock(&dev->bm.init_mutex); return ret; } @@ -2207,7 +2212,7 @@ int drm_bo_driver_init(struct drm_device * dev) struct drm_buffer_manager *bm = &dev->bm; int ret = -EINVAL; - mutex_lock(&dev->bm.init_mutex); + drm_bo_init_lock(&bm->bm_lock); mutex_lock(&dev->struct_mutex); if (!driver) goto out_unlock; @@ -2233,7 +2238,6 @@ int drm_bo_driver_init(struct drm_device * dev) INIT_LIST_HEAD(&bm->ddestroy); out_unlock: mutex_unlock(&dev->struct_mutex); - mutex_unlock(&dev->bm.init_mutex); return ret; } @@ -2252,6 +2256,10 @@ int drm_mm_init_ioctl(struct drm_device *dev, void *data, struct drm_file *file_ } ret = -EINVAL; + ret = drm_bo_write_lock(&bm->bm_lock, file_priv); + if (ret) + return ret; + if (arg->magic != DRM_BO_INIT_MAGIC) { DRM_ERROR("You are using an old libdrm that is not compatible with\n" "\tthe kernel DRM module. Please upgrade your libdrm.\n"); @@ -2271,7 +2279,6 @@ int drm_mm_init_ioctl(struct drm_device *dev, void *data, struct drm_file *file_ return -EINVAL; } - mutex_lock(&dev->bm.init_mutex); mutex_lock(&dev->struct_mutex); if (!bm->initialized) { DRM_ERROR("DRM memory manager was not initialized.\n"); @@ -2286,7 +2293,8 @@ int drm_mm_init_ioctl(struct drm_device *dev, void *data, struct drm_file *file_ out: mutex_unlock(&dev->struct_mutex); - mutex_unlock(&dev->bm.init_mutex); + (void) drm_bo_write_unlock(&bm->bm_lock, file_priv); + if (ret) return ret; @@ -2305,8 +2313,10 @@ int drm_mm_takedown_ioctl(struct drm_device *dev, void *data, struct drm_file *f return -EINVAL; } - LOCK_TEST_WITH_RETURN(dev, file_priv); - mutex_lock(&dev->bm.init_mutex); + ret = drm_bo_write_lock(&bm->bm_lock, file_priv); + if (ret) + return ret; + mutex_lock(&dev->struct_mutex); ret = -EINVAL; if (!bm->initialized) { @@ -2324,7 +2334,8 @@ int drm_mm_takedown_ioctl(struct drm_device *dev, void *data, struct drm_file *f } out: mutex_unlock(&dev->struct_mutex); - mutex_unlock(&dev->bm.init_mutex); + (void) drm_bo_write_unlock(&bm->bm_lock, file_priv); + if (ret) return ret; @@ -2342,20 +2353,28 @@ int drm_mm_lock_ioctl(struct drm_device *dev, void *data, struct drm_file *file_ return -EINVAL; } - LOCK_TEST_WITH_RETURN(dev, file_priv); - mutex_lock(&dev->bm.init_mutex); + if (arg->lock_unlock_bm) { + ret = drm_bo_write_lock(&dev->bm.bm_lock, file_priv); + if (ret) + return ret; + } + mutex_lock(&dev->struct_mutex); ret = drm_bo_lock_mm(dev, arg->mem_type); mutex_unlock(&dev->struct_mutex); - mutex_unlock(&dev->bm.init_mutex); - if (ret) + if (ret) { + (void) drm_bo_write_unlock(&dev->bm.bm_lock, file_priv); return ret; + } return 0; } -int drm_mm_unlock_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) +int drm_mm_unlock_ioctl(struct drm_device *dev, + void *data, + struct drm_file *file_priv) { + struct drm_mm_type_arg *arg = data; struct drm_bo_driver *driver = dev->driver->bo_driver; int ret; @@ -2364,16 +2383,12 @@ int drm_mm_unlock_ioctl(struct drm_device *dev, void *data, struct drm_file *fil return -EINVAL; } - LOCK_TEST_WITH_RETURN(dev, file_priv); - mutex_lock(&dev->bm.init_mutex); - mutex_lock(&dev->struct_mutex); - ret = 0; - - mutex_unlock(&dev->struct_mutex); - mutex_unlock(&dev->bm.init_mutex); - if (ret) - return ret; - + if (arg->lock_unlock_bm) { + ret = drm_bo_write_unlock(&dev->bm.bm_lock, file_priv); + if (ret) + return ret; + } + return 0; } -- cgit v1.2.3 From 3b19b50cb5cd31e60eb03e99dd1109b6d0f5b8a3 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Sun, 21 Oct 2007 12:20:56 +0200 Subject: Remove the need for the hardware lock in the buffer manager. Add interface entry cleaning a memory type without touching NO_EVICT buffers. --- linux-core/drm_bo.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'linux-core/drm_bo.c') diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index a2a0291d..e6eb6320 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -2255,11 +2255,11 @@ int drm_mm_init_ioctl(struct drm_device *dev, void *data, struct drm_file *file_ return -EINVAL; } - ret = -EINVAL; ret = drm_bo_write_lock(&bm->bm_lock, file_priv); if (ret) return ret; + ret = -EINVAL; if (arg->magic != DRM_BO_INIT_MAGIC) { DRM_ERROR("You are using an old libdrm that is not compatible with\n" "\tthe kernel DRM module. Please upgrade your libdrm.\n"); @@ -2353,7 +2353,12 @@ int drm_mm_lock_ioctl(struct drm_device *dev, void *data, struct drm_file *file_ return -EINVAL; } - if (arg->lock_unlock_bm) { + if (arg->lock_flags & DRM_BO_LOCK_IGNORE_NO_EVICT) { + DRM_ERROR("Lock flag DRM_BO_LOCK_IGNORE_NO_EVICT not supported yet.\n"); + return -EINVAL; + } + + if (arg->lock_flags & DRM_BO_LOCK_UNLOCK_BM) { ret = drm_bo_write_lock(&dev->bm.bm_lock, file_priv); if (ret) return ret; @@ -2383,7 +2388,7 @@ int drm_mm_unlock_ioctl(struct drm_device *dev, return -EINVAL; } - if (arg->lock_unlock_bm) { + if (arg->lock_flags & DRM_BO_LOCK_UNLOCK_BM) { ret = drm_bo_write_unlock(&dev->bm.bm_lock, file_priv); if (ret) return ret; -- cgit v1.2.3 From 824330d0e652e0bab1851437f120c7e76feee832 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Mon, 22 Oct 2007 19:09:36 +0200 Subject: Don't clobber the unfenced list with DONT_FENCE operations. --- linux-core/drm_bo.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'linux-core/drm_bo.c') diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index e6eb6320..9598e353 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -1299,10 +1299,7 @@ int drm_bo_move_buffer(struct drm_buffer_object * bo, uint32_t new_mem_flags, mutex_lock(&bm->evict_mutex); mutex_lock(&dev->struct_mutex); - list_del(&bo->lru); - list_add_tail(&bo->lru, &bm->unfenced); - DRM_FLAG_MASKED(bo->priv_flags, _DRM_BO_FLAG_UNFENCED, - _DRM_BO_FLAG_UNFENCED); + list_del_init(&bo->lru); mutex_unlock(&dev->struct_mutex); /* @@ -1322,10 +1319,6 @@ int drm_bo_move_buffer(struct drm_buffer_object * bo, uint32_t new_mem_flags, drm_mm_put_block(mem.mm_node); mem.mm_node = NULL; } - DRM_FLAG_MASKED(bo->priv_flags, 0, _DRM_BO_FLAG_UNFENCED); - DRM_WAKEUP(&bo->event_queue); - list_del(&bo->lru); - drm_bo_add_to_lru(bo); mutex_unlock(&dev->struct_mutex); } -- cgit v1.2.3 From b5cad27e05ad3666be8ccdf71e10d743efa5849e Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Thu, 25 Oct 2007 09:49:33 +0200 Subject: Fix buffer object flag / mask checking. --- linux-core/drm_bo.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'linux-core/drm_bo.c') diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index 9598e353..039873ca 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -921,37 +921,37 @@ int drm_bo_mem_space(struct drm_buffer_object * bo, EXPORT_SYMBOL(drm_bo_mem_space); static int drm_bo_new_mask(struct drm_buffer_object * bo, - uint64_t new_mask, uint32_t hint) + uint64_t new_flags, uint64_t used_mask) { uint32_t new_props; if (bo->type == drm_bo_type_user) { - DRM_ERROR("User buffers are not supported yet\n"); + DRM_ERROR("User buffers are not supported yet.\n"); return -EINVAL; } - if ((new_mask & DRM_BO_FLAG_NO_EVICT) && !DRM_SUSER(DRM_CURPROC)) { + if ((used_mask & DRM_BO_FLAG_NO_EVICT) && !DRM_SUSER(DRM_CURPROC)) { DRM_ERROR ("DRM_BO_FLAG_NO_EVICT is only available to priviliged " - "processes\n"); + "processes.\n"); return -EPERM; } - if ((new_mask & DRM_BO_FLAG_NO_MOVE)) { + if ((new_flags & DRM_BO_FLAG_NO_MOVE)) { DRM_ERROR ("DRM_BO_FLAG_NO_MOVE is not properly implemented yet.\n"); return -EPERM; } - new_props = new_mask & (DRM_BO_FLAG_EXE | DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_READ); + new_props = new_flags & (DRM_BO_FLAG_EXE | DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_READ); if (!new_props) { DRM_ERROR("Invalid buffer object rwx properties\n"); return -EINVAL; } - bo->mem.mask = new_mask; + bo->mem.mask = new_flags; return 0; } @@ -1490,7 +1490,7 @@ int drm_bo_do_validate(struct drm_buffer_object *bo, DRM_FLAG_MASKED(flags, bo->mem.mask, ~mask); - ret = drm_bo_new_mask(bo, flags, hint); + ret = drm_bo_new_mask(bo, flags, mask); if (ret) goto out; -- cgit v1.2.3 From 11f3e5e53f8fc4de90d1c289e0ba218ddfca23dc Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Thu, 25 Oct 2007 10:12:21 +0200 Subject: Buffer manager: Implement a version check IOCTL for drivers that don't use drmMMInit from user-space. Remove the minor check from the kernel code. That's really up to the driver. Bump major. --- linux-core/drm_bo.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'linux-core/drm_bo.c') diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index 039873ca..8d1e2f56 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -2260,17 +2260,10 @@ int drm_mm_init_ioctl(struct drm_device *dev, void *data, struct drm_file *file_ } if (arg->major != DRM_BO_INIT_MAJOR) { DRM_ERROR("libdrm and kernel DRM buffer object interface major\n" - "\tversion don't match. Got %d, expected %d,\n", + "\tversion don't match. Got %d, expected %d.\n", arg->major, DRM_BO_INIT_MAJOR); return -EINVAL; } - if (arg->minor > DRM_BO_INIT_MINOR) { - DRM_ERROR("libdrm expects a newer DRM buffer object interface.\n" - "\tlibdrm buffer object interface version is %d.%d.\n" - "\tkernel DRM buffer object interface version is %d.%d\n", - arg->major, arg->minor, DRM_BO_INIT_MAJOR, DRM_BO_INIT_MINOR); - return -EINVAL; - } mutex_lock(&dev->struct_mutex); if (!bm->initialized) { @@ -2535,3 +2528,15 @@ static int drm_bo_setup_vm_locked(struct drm_buffer_object * bo) return 0; } + +int drm_bo_version_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_bo_version_arg *arg = (struct drm_bo_version_arg *)data; + + arg->major = DRM_BO_INIT_MAJOR; + arg->minor = DRM_BO_INIT_MINOR; + arg->patchlevel = DRM_BO_INIT_PATCH; + + return 0; +} -- cgit v1.2.3