Simplify two functions msm_parse_deps() and msm_parse_post_deps(): extract single item parsing function and clean up error path. Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@xxxxxxxxxx> --- drivers/gpu/drm/msm/msm_gem_submit.c | 196 +++++++++++++++------------ 1 file changed, 106 insertions(+), 90 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index a539eb31042f..c64907f0f249 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -546,6 +546,46 @@ struct msm_submit_post_dep { struct dma_fence_chain *chain; }; +static struct drm_syncobj *msm_parse_dep_one(struct msm_gem_submit *submit, + struct drm_file *file, + uint64_t address, + size_t syncobj_stride) +{ + struct drm_msm_gem_submit_syncobj syncobj_desc = {0}; + struct dma_fence *fence; + struct drm_syncobj *syncobj = NULL; + int ret; + + if (copy_from_user(&syncobj_desc, + u64_to_user_ptr(address), + min(syncobj_stride, sizeof(syncobj_desc)))) + return ERR_PTR(-EFAULT); + + if (syncobj_desc.point && + !drm_core_check_feature(submit->dev, DRIVER_SYNCOBJ_TIMELINE)) + return ERR_PTR(-EOPNOTSUPP); + + if (syncobj_desc.flags & ~MSM_SUBMIT_SYNCOBJ_FLAGS) + return ERR_PTR(-EINVAL); + + ret = drm_syncobj_find_fence(file, syncobj_desc.handle, + syncobj_desc.point, 0, &fence); + if (ret) + return ERR_PTR(ret); + + ret = drm_sched_job_add_dependency(&submit->base, fence); + if (ret) + return ERR_PTR(ret); + + if (syncobj_desc.flags & MSM_SUBMIT_SYNCOBJ_RESET) { + syncobj = drm_syncobj_find(file, syncobj_desc.handle); + if (!syncobj) + return ERR_PTR(-EINVAL); + } + + return syncobj; +} + static struct drm_syncobj **msm_parse_deps(struct msm_gem_submit *submit, struct drm_file *file, uint64_t in_syncobjs_addr, @@ -553,9 +593,8 @@ static struct drm_syncobj **msm_parse_deps(struct msm_gem_submit *submit, size_t syncobj_stride) { struct drm_syncobj **syncobjs = NULL; - struct drm_msm_gem_submit_syncobj syncobj_desc = {0}; - int ret = 0; - uint32_t i, j; + int ret; + int i; syncobjs = kcalloc(nr_in_syncobjs, sizeof(*syncobjs), GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY); @@ -564,54 +603,26 @@ static struct drm_syncobj **msm_parse_deps(struct msm_gem_submit *submit, for (i = 0; i < nr_in_syncobjs; ++i) { uint64_t address = in_syncobjs_addr + i * syncobj_stride; - struct dma_fence *fence; + struct drm_syncobj *syncobj; - if (copy_from_user(&syncobj_desc, - u64_to_user_ptr(address), - min(syncobj_stride, sizeof(syncobj_desc)))) { - ret = -EFAULT; - break; - } - - if (syncobj_desc.point && - !drm_core_check_feature(submit->dev, DRIVER_SYNCOBJ_TIMELINE)) { - ret = -EOPNOTSUPP; - break; + syncobj = msm_parse_dep_one(submit, file, address, syncobj_stride); + if (IS_ERR(syncobj)) { + ret = PTR_ERR(syncobj); + goto err; } - if (syncobj_desc.flags & ~MSM_SUBMIT_SYNCOBJ_FLAGS) { - ret = -EINVAL; - break; - } - - ret = drm_syncobj_find_fence(file, syncobj_desc.handle, - syncobj_desc.point, 0, &fence); - if (ret) - break; - - ret = drm_sched_job_add_dependency(&submit->base, fence); - if (ret) - break; - - if (syncobj_desc.flags & MSM_SUBMIT_SYNCOBJ_RESET) { - syncobjs[i] = - drm_syncobj_find(file, syncobj_desc.handle); - if (!syncobjs[i]) { - ret = -EINVAL; - break; - } - } + syncobjs[i] = syncobj; } - if (ret) { - for (j = 0; j <= i; ++j) { - if (syncobjs[j]) - drm_syncobj_put(syncobjs[j]); - } - kfree(syncobjs); - return ERR_PTR(ret); - } return syncobjs; + +err: + while (--i >= 0) + if (syncobjs[i]) + drm_syncobj_put(syncobjs[i]); + kfree(syncobjs); + + return ERR_PTR(ret); } static void msm_reset_syncobjs(struct drm_syncobj **syncobjs, @@ -625,6 +636,43 @@ static void msm_reset_syncobjs(struct drm_syncobj **syncobjs, } } +static int msm_parse_post_dep_one(struct drm_device *dev, + struct drm_file *file, + uint64_t address, + size_t syncobj_stride, + struct msm_submit_post_dep *post_dep) +{ + struct msm_submit_post_dep *post_deps; + struct drm_msm_gem_submit_syncobj syncobj_desc = {0}; + + if (copy_from_user(&syncobj_desc, + u64_to_user_ptr(address), + min(syncobj_stride, sizeof(syncobj_desc)))) + return -EFAULT; + + post_dep->point = syncobj_desc.point; + + if (syncobj_desc.flags) + return -EINVAL; + + if (syncobj_desc.point) { + if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE)) + return -EOPNOTSUPP; + + post_dep->chain = dma_fence_chain_alloc(); + if (!post_dep->chain) + return -ENOMEM; + } + + post_dep->syncobj = drm_syncobj_find(file, syncobj_desc.handle); + if (!post_dep->syncobj) { + dma_fence_chain_free(post_deps->chain); + return -EINVAL; + } + + return 0; +} + static struct msm_submit_post_dep *msm_parse_post_deps(struct drm_device *dev, struct drm_file *file, uint64_t syncobjs_addr, @@ -632,9 +680,8 @@ static struct msm_submit_post_dep *msm_parse_post_deps(struct drm_device *dev, size_t syncobj_stride) { struct msm_submit_post_dep *post_deps; - struct drm_msm_gem_submit_syncobj syncobj_desc = {0}; int ret = 0; - uint32_t i, j; + int i; post_deps = kcalloc(nr_syncobjs, sizeof(*post_deps), GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY); @@ -644,54 +691,23 @@ static struct msm_submit_post_dep *msm_parse_post_deps(struct drm_device *dev, for (i = 0; i < nr_syncobjs; ++i) { uint64_t address = syncobjs_addr + i * syncobj_stride; - if (copy_from_user(&syncobj_desc, - u64_to_user_ptr(address), - min(syncobj_stride, sizeof(syncobj_desc)))) { - ret = -EFAULT; - break; - } - - post_deps[i].point = syncobj_desc.point; - - if (syncobj_desc.flags) { - ret = -EINVAL; - break; - } - - if (syncobj_desc.point) { - if (!drm_core_check_feature(dev, - DRIVER_SYNCOBJ_TIMELINE)) { - ret = -EOPNOTSUPP; - break; - } - - post_deps[i].chain = dma_fence_chain_alloc(); - if (!post_deps[i].chain) { - ret = -ENOMEM; - break; - } - } - - post_deps[i].syncobj = - drm_syncobj_find(file, syncobj_desc.handle); - if (!post_deps[i].syncobj) { - ret = -EINVAL; - break; - } + ret = msm_parse_post_dep_one(dev, file, address, syncobj_stride, &post_deps[i]); + if (ret) + goto err; } - if (ret) { - for (j = 0; j <= i; ++j) { - dma_fence_chain_free(post_deps[j].chain); - if (post_deps[j].syncobj) - drm_syncobj_put(post_deps[j].syncobj); - } + return post_deps; - kfree(post_deps); - return ERR_PTR(ret); +err: + while (--i >= 0) { + dma_fence_chain_free(post_deps[i].chain); + if (post_deps[i].syncobj) + drm_syncobj_put(post_deps[i].syncobj); } - return post_deps; + kfree(post_deps); + + return ERR_PTR(ret); } static void msm_process_post_deps(struct msm_submit_post_dep *post_deps, -- 2.39.1