浏览代码

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

qctecmdr 6 年之前
父节点
当前提交
bfffbd8af1
共有 4 个文件被更改,包括 68 次插入44 次删除
  1. 34 14
      msm/sde/sde_connector.c
  2. 26 10
      msm/sde/sde_crtc.c
  3. 5 18
      msm/sde/sde_fence.c
  4. 3 2
      msm/sde/sde_plane.c

+ 34 - 14
msm/sde/sde_connector.c

@@ -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,23 +1248,42 @@ static int sde_connector_atomic_set_property(struct drm_connector *connector,
 		if (!val)
 			goto end;
 
-		/*
-		 * update the the offset to a timeline for commit completion
-		 */
-		rc = sde_fence_create(c_conn->retire_fence, &fence_fd, 1);
+		rc = copy_from_user(&prev_user_fd, (void __user *)val,
+				sizeof(uint64_t));
 		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;
 		}
 
-		rc = copy_to_user((uint64_t __user *)(uintptr_t)val, &fence_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);
-			rc = -EFAULT;
-			goto end;
+		/*
+		 * client is expected to reset the property to -1 before
+		 * requesting for the retire fence
+		 */
+		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_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;
 	case CONNECTOR_PROP_ROI_V1:

+ 26 - 10
msm/sde/sde_crtc.c

@@ -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);
-		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,
+		ret = copy_from_user(&prev_user_fd, (void __user *)val,
 				sizeof(uint64_t));
 		if (ret) {
-			SDE_ERROR("copy to user failed rc:%d\n", ret);
-			put_unused_fd(fence_fd);
+			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_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;
 	default:
 		/* nothing to do */

+ 5 - 18
msm/sde/sde_fence.c

@@ -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);
-	}
+	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
msm/sde/sde_plane.c

@@ -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;