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

Commit f816f272 authored by Rob Clark's avatar Rob Clark
Browse files

drm/msm: return -EBUSY if bo still active



When we CPU_PREP a bo with NOSYNC flag (for example, to implement
PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE), an -EBUSY return indicates to
userspace that the bo is still busy.  Previously it was incorrectly
returning 0 in this case.

And while we're in there throw in an bit of extra sanity checking in
case userspace tries to wait for a bogus fence.

Signed-off-by: default avatarRob Clark <robdclark@gmail.com>
parent 1f70e079
Loading
Loading
Loading
Loading
+33 −17
Original line number Diff line number Diff line
@@ -499,10 +499,24 @@ int msm_wait_fence_interruptable(struct drm_device *dev, uint32_t fence,
		struct timespec *timeout)
{
	struct msm_drm_private *priv = dev->dev_private;
	int ret;

	if (!priv->gpu)
		return 0;

	if (fence > priv->gpu->submitted_fence) {
		DRM_ERROR("waiting on invalid fence: %u (of %u)\n",
				fence, priv->gpu->submitted_fence);
		return -EINVAL;
	}

	if (!timeout) {
		/* no-wait: */
		ret = fence_completed(dev, fence) ? 0 : -EBUSY;
	} else {
		unsigned long timeout_jiffies = timespec_to_jiffies(timeout);
		unsigned long start_jiffies = jiffies;
		unsigned long remaining_jiffies;
	int ret;

		if (time_after(start_jiffies, timeout_jiffies))
			remaining_jiffies = 0;
@@ -510,8 +524,9 @@ int msm_wait_fence_interruptable(struct drm_device *dev, uint32_t fence,
			remaining_jiffies = timeout_jiffies - start_jiffies;

		ret = wait_event_interruptible_timeout(priv->fence_event,
			priv->completed_fence >= fence,
				fence_completed(dev, fence),
				remaining_jiffies);

		if (ret == 0) {
			DBG("timeout waiting for fence: %u (completed: %u)",
					fence, priv->completed_fence);
@@ -519,6 +534,7 @@ int msm_wait_fence_interruptable(struct drm_device *dev, uint32_t fence,
		} else if (ret != -ERESTARTSYS) {
			ret = 0;
		}
	}

	return ret;
}
+6 −0
Original line number Diff line number Diff line
@@ -191,6 +191,12 @@ u32 msm_readl(const void __iomem *addr);
#define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
#define VERB(fmt, ...) if (0) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)

static inline bool fence_completed(struct drm_device *dev, uint32_t fence)
{
	struct msm_drm_private *priv = dev->dev_private;
	return priv->completed_fence >= fence;
}

static inline int align_pitch(int width, int bpp)
{
	int bytespp = (bpp + 7) / 8;
+5 −1
Original line number Diff line number Diff line
@@ -437,12 +437,16 @@ int msm_gem_cpu_prep(struct drm_gem_object *obj, uint32_t op,
	struct msm_gem_object *msm_obj = to_msm_bo(obj);
	int ret = 0;

	if (is_active(msm_obj) && !(op & MSM_PREP_NOSYNC)) {
	if (is_active(msm_obj)) {
		uint32_t fence = 0;

		if (op & MSM_PREP_READ)
			fence = msm_obj->write_fence;
		if (op & MSM_PREP_WRITE)
			fence = max(fence, msm_obj->read_fence);
		if (op & MSM_PREP_NOSYNC)
			timeout = NULL;

		ret = msm_wait_fence_interruptable(dev, fence, timeout);
	}