Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bfffbd8a authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

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

parents 91f4bcda d710ac7f
Loading
Loading
Loading
Loading
+34 −14
Original line number Diff line number Diff line
@@ -1204,7 +1204,8 @@ static int sde_connector_atomic_set_property(struct drm_connector *connector,
	struct sde_connector *c_conn;
	struct sde_connector_state *c_state;
	int idx, rc;
	uint64_t fence_fd;
	uint64_t fence_user_fd;
	uint64_t __user prev_user_fd;

	if (!connector || !state || !property) {
		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)
			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) {
				SDE_ERROR("fence create failed rc:%d\n", rc);
				goto end;
			}

		rc = copy_to_user((uint64_t __user *)(uintptr_t)val, &fence_fd,
			sizeof(uint64_t));
			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_fd);
				/*
				 * fence will be released with timeline
				 * update
				 */
				put_unused_fd(fence_user_fd);
				rc = -EFAULT;
				goto end;
			}
		}
		break;
	case CONNECTOR_PROP_ROI_V1:
		rc = _sde_connector_set_roi_v1(c_conn, c_state,
+26 −10
Original line number Diff line number Diff line
@@ -5025,7 +5025,8 @@ static int sde_crtc_atomic_set_property(struct drm_crtc *crtc,
	struct sde_crtc *sde_crtc;
	struct sde_crtc_state *cstate;
	int idx, ret;
	uint64_t fence_fd;
	uint64_t fence_user_fd;
	uint64_t __user prev_user_fd;

	if (!crtc || !state || !property) {
		SDE_ERROR("invalid argument(s)\n");
@@ -5085,20 +5086,35 @@ static int sde_crtc_atomic_set_property(struct drm_crtc *crtc,
		if (!val)
			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) {
				SDE_ERROR("fence create failed rc:%d\n", ret);
				goto exit;
			}

		ret = copy_to_user((uint64_t __user *)(uintptr_t)val, &fence_fd,
				sizeof(uint64_t));
			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_fd);
				put_unused_fd(fence_user_fd);
				ret = -EFAULT;
				goto exit;
			}
		}
		break;
	default:
		/* nothing to do */
+5 −18
Original line number Diff line number Diff line
@@ -325,9 +325,8 @@ int sde_fence_create(struct sde_fence_context *ctx, uint64_t *val,
							uint32_t offset)
{
	uint32_t trigger_value;
	int fd = -1, rc = -EINVAL;
	int fd, rc = -EINVAL;
	unsigned long flags;
	struct sde_fence *fc;

	if (!ctx || !val) {
		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;
	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);
	*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);
	rc = (fd >= 0) ? 0 : fd;
+3 −2
Original line number Diff line number Diff line
@@ -766,8 +766,9 @@ int sde_plane_wait_input_fence(struct drm_plane *plane, uint32_t wait_ms)

			switch (rc) {
			case 0:
				SDE_ERROR_PLANE(psde, "%ums timeout on %08X\n",
						wait_ms, prefix);
				SDE_ERROR_PLANE(psde, "%ums timeout on %08X fd %d\n",
						wait_ms, prefix, sde_plane_get_property(pstate,
						PLANE_PROP_INPUT_FENCE));
				psde->is_error = true;
				sde_kms_timeline_status(plane->dev);
				ret = -ETIMEDOUT;