From: Thomas Hellstrom Date: Wed, 17 Oct 2007 08:55:21 +0000 (+0200) Subject: Remove the op ioctl, and replace it with a setuser ioctl. X-Git-Tag: submit/1.0/20121108.012404~1030^2~28 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=086c058a417317491320129d2cbeb68d1cfcfefe;p=profile%2Fivi%2Flibdrm.git 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. --- diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index b8f3b98..78cbb09 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2695,62 +2695,37 @@ int drmBOUnmap(int fd, drmBO *buf) return 0; } -int drmBOValidate(int fd, drmBO *buf, uint32_t fence_class, - uint64_t flags, uint64_t mask, - unsigned hint) +int drmBOSetStatus(int fd, drmBO *buf, uint32_t fence_class, + uint64_t flags, uint64_t mask, + unsigned int hint, + unsigned int desired_tile_stride, + unsigned int tile_info) { - struct drm_bo_op_arg arg; - struct drm_bo_op_req *req = &arg.d.req; - struct drm_bo_arg_rep *rep = &arg.d.rep; + struct drm_bo_map_wait_idle_arg arg; + struct drm_bo_info_req *req = &arg.d.req; + struct drm_bo_info_rep *rep = &arg.d.rep; int ret = 0; memset(&arg, 0, sizeof(arg)); - req->bo_req.handle = buf->handle; - req->bo_req.flags = flags; - req->bo_req.mask = mask; - req->bo_req.hint = hint; - req->bo_req.fence_class = fence_class; - req->op = drm_bo_validate; - - do{ - ret = ioctl(fd, DRM_IOCTL_BO_OP, &arg); + req->mask = mask; + req->flags = flags; + req->handle = buf->handle; + req->hint = hint; + req->fence_class = fence_class; + req->desired_tile_stride = desired_tile_stride; + req->tile_info = tile_info; + + do { + ret = ioctl(fd, DRM_IOCTL_BO_SETSTATUS, &arg); } while (ret && errno == EAGAIN); if (ret) - return -errno; - if (!arg.handled) - return -EFAULT; - if (rep->ret) - return rep->ret; + return -errno; - drmBOCopyReply(&rep->bo_info, buf); - return 0; + drmBOCopyReply(rep, buf); } -int drmBOFence(int fd, drmBO *buf, unsigned flags, unsigned fenceHandle) -{ - struct drm_bo_op_arg arg; - struct drm_bo_op_req *req = &arg.d.req; - struct drm_bo_arg_rep *rep = &arg.d.rep; - int ret = 0; - - memset(&arg, 0, sizeof(arg)); - req->bo_req.handle = buf->handle; - req->bo_req.flags = flags; - req->arg_handle = fenceHandle; - req->op = drm_bo_fence; - - ret = ioctl(fd, DRM_IOCTL_BO_OP, &arg); - if (ret) - return -errno; - if (!arg.handled) - return -EFAULT; - if (rep->ret) - return rep->ret; - return 0; -} - int drmBOInfo(int fd, drmBO *buf) { struct drm_bo_reference_info_arg arg; diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index 7335d25..bdeefec 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; diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index 80e5693..9c867f1 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -142,7 +142,7 @@ static struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_BO_UNMAP, drm_bo_unmap_ioctl, DRM_AUTH), DRM_IOCTL_DEF(DRM_IOCTL_BO_REFERENCE, drm_bo_reference_ioctl, DRM_AUTH), DRM_IOCTL_DEF(DRM_IOCTL_BO_UNREFERENCE, drm_bo_unreference_ioctl, DRM_AUTH), - DRM_IOCTL_DEF(DRM_IOCTL_BO_OP, drm_bo_op_ioctl, DRM_AUTH), + DRM_IOCTL_DEF(DRM_IOCTL_BO_SETSTATUS, drm_bo_setstatus_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), }; diff --git a/linux-core/drm_objects.h b/linux-core/drm_objects.h index 91378b8..4d1ec99 100644 --- a/linux-core/drm_objects.h +++ b/linux-core/drm_objects.h @@ -470,9 +470,7 @@ extern int drm_bo_reference_ioctl(struct drm_device *dev, void *data, struct drm extern int drm_bo_unreference_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); 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); - - +extern int drm_bo_setstatus_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); extern int drm_mm_lock_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); diff --git a/shared-core/drm.h b/shared-core/drm.h index 021a52e..0ffd0ad 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -723,6 +723,7 @@ struct drm_fence_arg { * Flags: Acknowledge. */ #define DRM_BO_FLAG_FORCE_MAPPABLE (1ULL << 14) +#define DRM_BO_FLAG_TILE (1ULL << 15) /* * Memory type flags that can be or'ed together in the mask, but only @@ -755,7 +756,6 @@ struct drm_fence_arg { /* Don't place this buffer on the unfenced list.*/ #define DRM_BO_HINT_DONT_FENCE 0x00000004 #define DRM_BO_HINT_WAIT_LAZY 0x00000008 -#define DRM_BO_HINT_ALLOW_UNFENCED_MAP 0x00000010 #define DRM_BO_INIT_MAGIC 0xfe769812 #define DRM_BO_INIT_MAJOR 0 @@ -768,6 +768,8 @@ struct drm_bo_info_req { unsigned int handle; unsigned int hint; unsigned int fence_class; + unsigned int desired_tile_stride; + unsigned int tile_info; unsigned int pad64; }; @@ -779,15 +781,6 @@ struct drm_bo_create_req { unsigned int page_alignment; }; -struct drm_bo_op_req { - enum { - drm_bo_validate, - drm_bo_fence, - drm_bo_ref_fence, - } op; - unsigned int arg_handle; - struct drm_bo_info_req bo_req; -}; /* * Reply flags @@ -844,6 +837,17 @@ struct drm_bo_map_wait_idle_arg { } d; }; +struct drm_bo_op_req { + enum { + drm_bo_validate, + drm_bo_fence, + drm_bo_ref_fence, + } op; + unsigned int arg_handle; + struct drm_bo_info_req bo_req; +}; + + struct drm_bo_op_arg { uint64_t next; union { @@ -854,6 +858,7 @@ struct drm_bo_op_arg { unsigned int pad64; }; + #define DRM_BO_MEM_LOCAL 0 #define DRM_BO_MEM_TT 1 #define DRM_BO_MEM_VRAM 2 @@ -964,7 +969,7 @@ struct drm_mm_init_arg { #define DRM_IOCTL_BO_UNMAP DRM_IOWR(0xd0, struct drm_bo_handle_arg) #define DRM_IOCTL_BO_REFERENCE DRM_IOWR(0xd1, struct drm_bo_reference_info_arg) #define DRM_IOCTL_BO_UNREFERENCE DRM_IOWR(0xd2, struct drm_bo_handle_arg) -#define DRM_IOCTL_BO_OP DRM_IOWR(0xd3, struct drm_bo_op_arg) +#define DRM_IOCTL_BO_SETSTATUS DRM_IOWR(0xd3, struct drm_bo_map_wait_idle_arg) #define DRM_IOCTL_BO_INFO DRM_IOWR(0xd4, struct drm_bo_reference_info_arg) #define DRM_IOCTL_BO_WAIT_IDLE DRM_IOWR(0xd5, struct drm_bo_map_wait_idle_arg)