Commit 8bf445ce authored by Thomas Hellstrom's avatar Thomas Hellstrom Committed by Dave Airlie
Browse files

vmwgfx: Break out and comment vmw_execbuf_copy_fence_user



This function will be used also by the upcoming fence event code,
so break it out and add a comment about the functionality.

Signed-off-by: default avatarThomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: default avatarJakob Bornecrantz <jakob@vmware.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 005a83f1
Loading
Loading
Loading
Loading
+67 −33
Original line number Diff line number Diff line
@@ -1037,6 +1037,71 @@ int vmw_execbuf_fence_commands(struct drm_file *file_priv,
	return 0;
}

/**
 * vmw_execbuf_copy_fence_user - copy fence object information to
 * user-space.
 *
 * @dev_priv: Pointer to a vmw_private struct.
 * @vmw_fp: Pointer to the struct vmw_fpriv representing the calling file.
 * @ret: Return value from fence object creation.
 * @user_fence_rep: User space address of a struct drm_vmw_fence_rep to
 * which the information should be copied.
 * @fence: Pointer to the fenc object.
 * @fence_handle: User-space fence handle.
 *
 * This function copies fence information to user-space. If copying fails,
 * The user-space struct drm_vmw_fence_rep::error member is hopefully
 * left untouched, and if it's preloaded with an -EFAULT by user-space,
 * the error will hopefully be detected.
 * Also if copying fails, user-space will be unable to signal the fence
 * object so we wait for it immediately, and then unreference the
 * user-space reference.
 */
static void
vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv,
			    struct vmw_fpriv *vmw_fp,
			    int ret,
			    struct drm_vmw_fence_rep __user *user_fence_rep,
			    struct vmw_fence_obj *fence,
			    uint32_t fence_handle)
{
	struct drm_vmw_fence_rep fence_rep;

	if (user_fence_rep == NULL)
		return;

	fence_rep.error = ret;
	if (ret == 0) {
		BUG_ON(fence == NULL);

		fence_rep.handle = fence_handle;
		fence_rep.seqno = fence->seqno;
		vmw_update_seqno(dev_priv, &dev_priv->fifo);
		fence_rep.passed_seqno = dev_priv->last_read_seqno;
	}

	/*
	 * copy_to_user errors will be detected by user space not
	 * seeing fence_rep::error filled in. Typically
	 * user-space would have pre-set that member to -EFAULT.
	 */
	ret = copy_to_user(user_fence_rep, &fence_rep,
			   sizeof(fence_rep));

	/*
	 * User-space lost the fence object. We need to sync
	 * and unreference the handle.
	 */
	if (unlikely(ret != 0) && (fence_rep.error == 0)) {
		ttm_ref_object_base_unref(vmw_fp->tfile,
					  fence_handle, TTM_REF_USAGE);
		DRM_ERROR("Fence copy error. Syncing.\n");
		(void) vmw_fence_obj_wait(fence, fence->signal_mask,
					  false, false,
					  VMW_FENCE_WAIT_TIMEOUT);
	}
}

int vmw_execbuf_process(struct drm_file *file_priv,
			struct vmw_private *dev_priv,
			void __user *user_commands,
@@ -1046,7 +1111,6 @@ int vmw_execbuf_process(struct drm_file *file_priv,
			struct drm_vmw_fence_rep __user *user_fence_rep)
{
	struct vmw_sw_context *sw_context = &dev_priv->ctx;
	struct drm_vmw_fence_rep fence_rep;
	struct vmw_fence_obj *fence;
	uint32_t handle;
	void *cmd;
@@ -1140,38 +1204,8 @@ int vmw_execbuf_process(struct drm_file *file_priv,
				    (void *) fence);

	vmw_clear_validations(sw_context);

	if (user_fence_rep) {
		fence_rep.error = ret;
		fence_rep.handle = handle;
		fence_rep.seqno = fence->seqno;
		vmw_update_seqno(dev_priv, &dev_priv->fifo);
		fence_rep.passed_seqno = dev_priv->last_read_seqno;

		/*
		 * copy_to_user errors will be detected by user space not
		 * seeing fence_rep::error filled in. Typically
		 * user-space would have pre-set that member to -EFAULT.
		 */
		ret = copy_to_user(user_fence_rep, &fence_rep,
				   sizeof(fence_rep));

		/*
		 * User-space lost the fence object. We need to sync
		 * and unreference the handle.
		 */
		if (unlikely(ret != 0) && (fence_rep.error == 0)) {
			BUG_ON(fence == NULL);

			ttm_ref_object_base_unref(vmw_fpriv(file_priv)->tfile,
						  handle, TTM_REF_USAGE);
			DRM_ERROR("Fence copy error. Syncing.\n");
			(void) vmw_fence_obj_wait(fence,
						  fence->signal_mask,
						  false, false,
						  VMW_FENCE_WAIT_TIMEOUT);
		}
	}
	vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv), ret,
				    user_fence_rep, fence, handle);

	if (likely(fence != NULL))
		vmw_fence_obj_unreference(&fence);