Merge "disp: msm: sde: avoid duplicate fence create from client"
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

commit
bfffbd8af1
@@ -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,23 +1248,42 @@ 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,
|
||||||
* update the the offset to a timeline for commit completion
|
sizeof(uint64_t));
|
||||||
*/
|
|
||||||
rc = sde_fence_create(c_conn->retire_fence, &fence_fd, 1);
|
|
||||||
if (rc) {
|
if (rc) {
|
||||||
SDE_ERROR("fence create failed rc:%d\n", rc);
|
SDE_ERROR("copy from user failed rc:%d\n", rc);
|
||||||
|
rc = -EFAULT;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = copy_to_user((uint64_t __user *)(uintptr_t)val, &fence_fd,
|
/*
|
||||||
sizeof(uint64_t));
|
* client is expected to reset the property to -1 before
|
||||||
if (rc) {
|
* requesting for the retire fence
|
||||||
SDE_ERROR("copy to user failed rc:%d\n", rc);
|
*/
|
||||||
/* fence will be released with timeline update */
|
if (prev_user_fd == -1) {
|
||||||
put_unused_fd(fence_fd);
|
/*
|
||||||
rc = -EFAULT;
|
* update the offset to a timeline for
|
||||||
goto end;
|
* commit completion
|
||||||
|
*/
|
||||||
|
rc = sde_fence_create(c_conn->retire_fence,
|
||||||
|
&fence_user_fd, 1);
|
||||||
|
if (rc) {
|
||||||
|
SDE_ERROR("fence create failed rc:%d\n", rc);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = copy_to_user((uint64_t __user *)(uintptr_t)val,
|
||||||
|
&fence_user_fd, sizeof(uint64_t));
|
||||||
|
if (rc) {
|
||||||
|
SDE_ERROR("copy to user failed rc:%d\n", rc);
|
||||||
|
/*
|
||||||
|
* fence will be released with timeline
|
||||||
|
* update
|
||||||
|
*/
|
||||||
|
put_unused_fd(fence_user_fd);
|
||||||
|
rc = -EFAULT;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CONNECTOR_PROP_ROI_V1:
|
case CONNECTOR_PROP_ROI_V1:
|
||||||
|
@@ -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,19 +5086,34 @@ 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) {
|
if (ret) {
|
||||||
SDE_ERROR("fence create failed rc:%d\n", ret);
|
SDE_ERROR("copy from user failed rc:%d\n", ret);
|
||||||
|
ret = -EFAULT;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = copy_to_user((uint64_t __user *)(uintptr_t)val, &fence_fd,
|
/*
|
||||||
sizeof(uint64_t));
|
* client is expected to reset the property to -1 before
|
||||||
if (ret) {
|
* requesting for the release fence
|
||||||
SDE_ERROR("copy to user failed rc:%d\n", ret);
|
*/
|
||||||
put_unused_fd(fence_fd);
|
if (prev_user_fd == -1) {
|
||||||
ret = -EFAULT;
|
ret = _sde_crtc_get_output_fence(crtc, state,
|
||||||
goto exit;
|
&fence_user_fd);
|
||||||
|
if (ret) {
|
||||||
|
SDE_ERROR("fence create failed rc:%d\n", ret);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = copy_to_user((uint64_t __user *)(uintptr_t)val,
|
||||||
|
&fence_user_fd, sizeof(uint64_t));
|
||||||
|
if (ret) {
|
||||||
|
SDE_ERROR("copy to user failed rc:%d\n", ret);
|
||||||
|
put_unused_fd(fence_user_fd);
|
||||||
|
ret = -EFAULT;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@@ -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);
|
fd = _sde_fence_create_fd(ctx, trigger_value);
|
||||||
list_for_each_entry(fc, &ctx->fence_list_head, fence_list) {
|
*val = fd;
|
||||||
if (trigger_value == fc->base.seqno) {
|
SDE_DEBUG("fd:%d trigger:%d commit:%d offset:%d\n",
|
||||||
fd = fc->fd;
|
fd, trigger_value, ctx->commit_count, offset);
|
||||||
*val = fd;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
spin_unlock(&ctx->list_lock);
|
|
||||||
|
|
||||||
if (fd < 0) {
|
|
||||||
fd = _sde_fence_create_fd(ctx, trigger_value);
|
|
||||||
*val = fd;
|
|
||||||
SDE_DEBUG("fd:%d trigger:%d commit:%d offset:%d\n",
|
|
||||||
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;
|
||||||
|
@@ -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;
|
||||||
|
Reference in New Issue
Block a user