Commit f816f272 authored by Rob Clark's avatar Rob Clark

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
...@@ -499,10 +499,24 @@ int msm_wait_fence_interruptable(struct drm_device *dev, uint32_t fence, ...@@ -499,10 +499,24 @@ int msm_wait_fence_interruptable(struct drm_device *dev, uint32_t fence,
struct timespec *timeout) struct timespec *timeout)
{ {
struct msm_drm_private *priv = dev->dev_private; 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 timeout_jiffies = timespec_to_jiffies(timeout);
unsigned long start_jiffies = jiffies; unsigned long start_jiffies = jiffies;
unsigned long remaining_jiffies; unsigned long remaining_jiffies;
int ret;
if (time_after(start_jiffies, timeout_jiffies)) if (time_after(start_jiffies, timeout_jiffies))
remaining_jiffies = 0; remaining_jiffies = 0;
...@@ -510,8 +524,9 @@ int msm_wait_fence_interruptable(struct drm_device *dev, uint32_t fence, ...@@ -510,8 +524,9 @@ int msm_wait_fence_interruptable(struct drm_device *dev, uint32_t fence,
remaining_jiffies = timeout_jiffies - start_jiffies; remaining_jiffies = timeout_jiffies - start_jiffies;
ret = wait_event_interruptible_timeout(priv->fence_event, ret = wait_event_interruptible_timeout(priv->fence_event,
priv->completed_fence >= fence, fence_completed(dev, fence),
remaining_jiffies); remaining_jiffies);
if (ret == 0) { if (ret == 0) {
DBG("timeout waiting for fence: %u (completed: %u)", DBG("timeout waiting for fence: %u (completed: %u)",
fence, priv->completed_fence); fence, priv->completed_fence);
...@@ -519,6 +534,7 @@ int msm_wait_fence_interruptable(struct drm_device *dev, uint32_t fence, ...@@ -519,6 +534,7 @@ int msm_wait_fence_interruptable(struct drm_device *dev, uint32_t fence,
} else if (ret != -ERESTARTSYS) { } else if (ret != -ERESTARTSYS) {
ret = 0; ret = 0;
} }
}
return ret; return ret;
} }
......
...@@ -191,6 +191,12 @@ u32 msm_readl(const void __iomem *addr); ...@@ -191,6 +191,12 @@ u32 msm_readl(const void __iomem *addr);
#define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__) #define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
#define VERB(fmt, ...) if (0) 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) static inline int align_pitch(int width, int bpp)
{ {
int bytespp = (bpp + 7) / 8; int bytespp = (bpp + 7) / 8;
......
...@@ -437,12 +437,16 @@ int msm_gem_cpu_prep(struct drm_gem_object *obj, uint32_t op, ...@@ -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); struct msm_gem_object *msm_obj = to_msm_bo(obj);
int ret = 0; int ret = 0;
if (is_active(msm_obj) && !(op & MSM_PREP_NOSYNC)) { if (is_active(msm_obj)) {
uint32_t fence = 0; uint32_t fence = 0;
if (op & MSM_PREP_READ) if (op & MSM_PREP_READ)
fence = msm_obj->write_fence; fence = msm_obj->write_fence;
if (op & MSM_PREP_WRITE) if (op & MSM_PREP_WRITE)
fence = max(fence, msm_obj->read_fence); fence = max(fence, msm_obj->read_fence);
if (op & MSM_PREP_NOSYNC)
timeout = NULL;
ret = msm_wait_fence_interruptable(dev, fence, timeout); ret = msm_wait_fence_interruptable(dev, fence, timeout);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment