Merge "disp: msm: sde: avoid duplicate fence create from client"

This commit is contained in:
qctecmdr
2019-07-11 20:21:39 -07:00
committed by Gerrit - the friendly Code Review server
4 changed files with 68 additions and 44 deletions

View File

@@ -1204,7 +1204,8 @@ static int sde_connector_atomic_set_property(struct drm_connector *connector,
struct sde_connector *c_conn; struct sde_connector *c_conn;
struct sde_connector_state *c_state; struct sde_connector_state *c_state;
int idx, rc; int idx, rc;
uint64_t fence_fd; uint64_t fence_user_fd;
uint64_t __user prev_user_fd;
if (!connector || !state || !property) { if (!connector || !state || !property) {
SDE_ERROR("invalid argument(s), conn %pK, state %pK, prp %pK\n", SDE_ERROR("invalid argument(s), conn %pK, state %pK, prp %pK\n",
@@ -1247,24 +1248,43 @@ static int sde_connector_atomic_set_property(struct drm_connector *connector,
if (!val) if (!val)
goto end; goto end;
rc = copy_from_user(&prev_user_fd, (void __user *)val,
sizeof(uint64_t));
if (rc) {
SDE_ERROR("copy from user failed rc:%d\n", rc);
rc = -EFAULT;
goto end;
}
/* /*
* update the the offset to a timeline for commit completion * client is expected to reset the property to -1 before
* requesting for the retire fence
*/ */
rc = sde_fence_create(c_conn->retire_fence, &fence_fd, 1); if (prev_user_fd == -1) {
/*
* update the offset to a timeline for
* commit completion
*/
rc = sde_fence_create(c_conn->retire_fence,
&fence_user_fd, 1);
if (rc) { if (rc) {
SDE_ERROR("fence create failed rc:%d\n", rc); SDE_ERROR("fence create failed rc:%d\n", rc);
goto end; goto end;
} }
rc = copy_to_user((uint64_t __user *)(uintptr_t)val, &fence_fd, rc = copy_to_user((uint64_t __user *)(uintptr_t)val,
sizeof(uint64_t)); &fence_user_fd, sizeof(uint64_t));
if (rc) { if (rc) {
SDE_ERROR("copy to user failed rc:%d\n", rc); SDE_ERROR("copy to user failed rc:%d\n", rc);
/* fence will be released with timeline update */ /*
put_unused_fd(fence_fd); * fence will be released with timeline
* update
*/
put_unused_fd(fence_user_fd);
rc = -EFAULT; rc = -EFAULT;
goto end; goto end;
} }
}
break; break;
case CONNECTOR_PROP_ROI_V1: case CONNECTOR_PROP_ROI_V1:
rc = _sde_connector_set_roi_v1(c_conn, c_state, rc = _sde_connector_set_roi_v1(c_conn, c_state,

View File

@@ -5025,7 +5025,8 @@ static int sde_crtc_atomic_set_property(struct drm_crtc *crtc,
struct sde_crtc *sde_crtc; struct sde_crtc *sde_crtc;
struct sde_crtc_state *cstate; struct sde_crtc_state *cstate;
int idx, ret; int idx, ret;
uint64_t fence_fd; uint64_t fence_user_fd;
uint64_t __user prev_user_fd;
if (!crtc || !state || !property) { if (!crtc || !state || !property) {
SDE_ERROR("invalid argument(s)\n"); SDE_ERROR("invalid argument(s)\n");
@@ -5085,20 +5086,35 @@ static int sde_crtc_atomic_set_property(struct drm_crtc *crtc,
if (!val) if (!val)
goto exit; goto exit;
ret = _sde_crtc_get_output_fence(crtc, state, &fence_fd); ret = copy_from_user(&prev_user_fd, (void __user *)val,
sizeof(uint64_t));
if (ret) {
SDE_ERROR("copy from user failed rc:%d\n", ret);
ret = -EFAULT;
goto exit;
}
/*
* client is expected to reset the property to -1 before
* requesting for the release fence
*/
if (prev_user_fd == -1) {
ret = _sde_crtc_get_output_fence(crtc, state,
&fence_user_fd);
if (ret) { if (ret) {
SDE_ERROR("fence create failed rc:%d\n", ret); SDE_ERROR("fence create failed rc:%d\n", ret);
goto exit; goto exit;
} }
ret = copy_to_user((uint64_t __user *)(uintptr_t)val, &fence_fd, ret = copy_to_user((uint64_t __user *)(uintptr_t)val,
sizeof(uint64_t)); &fence_user_fd, sizeof(uint64_t));
if (ret) { if (ret) {
SDE_ERROR("copy to user failed rc:%d\n", ret); SDE_ERROR("copy to user failed rc:%d\n", ret);
put_unused_fd(fence_fd); put_unused_fd(fence_user_fd);
ret = -EFAULT; ret = -EFAULT;
goto exit; goto exit;
} }
}
break; break;
default: default:
/* nothing to do */ /* nothing to do */

View File

@@ -325,9 +325,8 @@ int sde_fence_create(struct sde_fence_context *ctx, uint64_t *val,
uint32_t offset) uint32_t offset)
{ {
uint32_t trigger_value; uint32_t trigger_value;
int fd = -1, rc = -EINVAL; int fd, rc = -EINVAL;
unsigned long flags; unsigned long flags;
struct sde_fence *fc;
if (!ctx || !val) { if (!ctx || !val) {
SDE_ERROR("invalid argument(s), fence %d, pval %d\n", SDE_ERROR("invalid argument(s), fence %d, pval %d\n",
@@ -347,22 +346,10 @@ int sde_fence_create(struct sde_fence_context *ctx, uint64_t *val,
trigger_value = ctx->commit_count + offset; trigger_value = ctx->commit_count + offset;
spin_unlock_irqrestore(&ctx->lock, flags); spin_unlock_irqrestore(&ctx->lock, flags);
spin_lock(&ctx->list_lock);
list_for_each_entry(fc, &ctx->fence_list_head, fence_list) {
if (trigger_value == fc->base.seqno) {
fd = fc->fd;
*val = fd;
break;
}
}
spin_unlock(&ctx->list_lock);
if (fd < 0) {
fd = _sde_fence_create_fd(ctx, trigger_value); fd = _sde_fence_create_fd(ctx, trigger_value);
*val = fd; *val = fd;
SDE_DEBUG("fd:%d trigger:%d commit:%d offset:%d\n", SDE_DEBUG("fd:%d trigger:%d commit:%d offset:%d\n",
fd, trigger_value, ctx->commit_count, offset); fd, trigger_value, ctx->commit_count, offset);
}
SDE_EVT32(ctx->drm_id, trigger_value, fd); SDE_EVT32(ctx->drm_id, trigger_value, fd);
rc = (fd >= 0) ? 0 : fd; rc = (fd >= 0) ? 0 : fd;

View File

@@ -766,8 +766,9 @@ int sde_plane_wait_input_fence(struct drm_plane *plane, uint32_t wait_ms)
switch (rc) { switch (rc) {
case 0: case 0:
SDE_ERROR_PLANE(psde, "%ums timeout on %08X\n", SDE_ERROR_PLANE(psde, "%ums timeout on %08X fd %d\n",
wait_ms, prefix); wait_ms, prefix, sde_plane_get_property(pstate,
PLANE_PROP_INPUT_FENCE));
psde->is_error = true; psde->is_error = true;
sde_kms_timeline_status(plane->dev); sde_kms_timeline_status(plane->dev);
ret = -ETIMEDOUT; ret = -ETIMEDOUT;