aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorRob Clark <robdclark@gmail.com>2013-09-11 17:34:07 -0400
committerRob Clark <robdclark@gmail.com>2013-09-11 17:36:28 -0400
commitf816f272437f3a2be0c9254d4ab8f917950d86a0 (patch)
tree60a194cabed7ef5f367865d62daa99a62f5f6cf4 /drivers/gpu
parent1f70e079c773b2c5988b0f0b4d314fc0f6c7a1b8 (diff)
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: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/msm/msm_drv.c50
-rw-r--r--drivers/gpu/drm/msm/msm_drv.h6
-rw-r--r--drivers/gpu/drm/msm/msm_gem.c6
3 files changed, 44 insertions, 18 deletions
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 864c9773636b..008d772384c7 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -499,25 +499,41 @@ int msm_wait_fence_interruptable(struct drm_device *dev, uint32_t fence,
499 struct timespec *timeout) 499 struct timespec *timeout)
500{ 500{
501 struct msm_drm_private *priv = dev->dev_private; 501 struct msm_drm_private *priv = dev->dev_private;
502 unsigned long timeout_jiffies = timespec_to_jiffies(timeout);
503 unsigned long start_jiffies = jiffies;
504 unsigned long remaining_jiffies;
505 int ret; 502 int ret;
506 503
507 if (time_after(start_jiffies, timeout_jiffies)) 504 if (!priv->gpu)
508 remaining_jiffies = 0; 505 return 0;
509 else 506
510 remaining_jiffies = timeout_jiffies - start_jiffies; 507 if (fence > priv->gpu->submitted_fence) {
511 508 DRM_ERROR("waiting on invalid fence: %u (of %u)\n",
512 ret = wait_event_interruptible_timeout(priv->fence_event, 509 fence, priv->gpu->submitted_fence);
513 priv->completed_fence >= fence, 510 return -EINVAL;
514 remaining_jiffies); 511 }
515 if (ret == 0) { 512
516 DBG("timeout waiting for fence: %u (completed: %u)", 513 if (!timeout) {
517 fence, priv->completed_fence); 514 /* no-wait: */
518 ret = -ETIMEDOUT; 515 ret = fence_completed(dev, fence) ? 0 : -EBUSY;
519 } else if (ret != -ERESTARTSYS) { 516 } else {
520 ret = 0; 517 unsigned long timeout_jiffies = timespec_to_jiffies(timeout);
518 unsigned long start_jiffies = jiffies;
519 unsigned long remaining_jiffies;
520
521 if (time_after(start_jiffies, timeout_jiffies))
522 remaining_jiffies = 0;
523 else
524 remaining_jiffies = timeout_jiffies - start_jiffies;
525
526 ret = wait_event_interruptible_timeout(priv->fence_event,
527 fence_completed(dev, fence),
528 remaining_jiffies);
529
530 if (ret == 0) {
531 DBG("timeout waiting for fence: %u (completed: %u)",
532 fence, priv->completed_fence);
533 ret = -ETIMEDOUT;
534 } else if (ret != -ERESTARTSYS) {
535 ret = 0;
536 }
521 } 537 }
522 538
523 return ret; 539 return ret;
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 1ea9d46e01bc..df8f1d084bc1 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -191,6 +191,12 @@ u32 msm_readl(const void __iomem *addr);
191#define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__) 191#define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
192#define VERB(fmt, ...) if (0) DRM_DEBUG(fmt"\n", ##__VA_ARGS__) 192#define VERB(fmt, ...) if (0) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
193 193
194static inline bool fence_completed(struct drm_device *dev, uint32_t fence)
195{
196 struct msm_drm_private *priv = dev->dev_private;
197 return priv->completed_fence >= fence;
198}
199
194static inline int align_pitch(int width, int bpp) 200static inline int align_pitch(int width, int bpp)
195{ 201{
196 int bytespp = (bpp + 7) / 8; 202 int bytespp = (bpp + 7) / 8;
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 5999b67ec8f1..583286f39299 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -437,12 +437,16 @@ int msm_gem_cpu_prep(struct drm_gem_object *obj, uint32_t op,
437 struct msm_gem_object *msm_obj = to_msm_bo(obj); 437 struct msm_gem_object *msm_obj = to_msm_bo(obj);
438 int ret = 0; 438 int ret = 0;
439 439
440 if (is_active(msm_obj) && !(op & MSM_PREP_NOSYNC)) { 440 if (is_active(msm_obj)) {
441 uint32_t fence = 0; 441 uint32_t fence = 0;
442
442 if (op & MSM_PREP_READ) 443 if (op & MSM_PREP_READ)
443 fence = msm_obj->write_fence; 444 fence = msm_obj->write_fence;
444 if (op & MSM_PREP_WRITE) 445 if (op & MSM_PREP_WRITE)
445 fence = max(fence, msm_obj->read_fence); 446 fence = max(fence, msm_obj->read_fence);
447 if (op & MSM_PREP_NOSYNC)
448 timeout = NULL;
449
446 ret = msm_wait_fence_interruptable(dev, fence, timeout); 450 ret = msm_wait_fence_interruptable(dev, fence, timeout);
447 } 451 }
448 452