All of lore.kernel.org
 help / color / mirror / Atom feed
* [Intel-gfx] [PATCH] drm/i915: Prevent waiting inside ring construction for critical sections
@ 2021-02-03 12:47 Chris Wilson
  2021-02-03 14:55 ` [Intel-gfx] [PATCH v2] " Chris Wilson
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Chris Wilson @ 2021-02-03 12:47 UTC (permalink / raw)
  To: intel-gfx; +Cc: Chris Wilson

From some contexts, we may not be allowed to wait during request
construction. For example, in the powermanagement handler that should
never block (as the engine was idle) and the driver would be crippled if
we did. Similarly, the user may request that the execbuf does not block,
and so would prefer to handle an EWOULDBLOCK error instead. In both
cases we need to propagate the flag to various blocking wait points, the
first and usually hit is intel_ring::wait_for_space().

Testcase: igt/gem_ctx_ringsize/spin
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c    |  3 +++
 drivers/gpu/drm/i915/gt/intel_ring.c          | 19 ++++++++--------
 drivers/gpu/drm/i915/i915_request.c           |  2 ++
 drivers/gpu/drm/i915/i915_request.h           | 22 +++++++++++++++++++
 4 files changed, 37 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index fe170186dd42..903eccad7ae2 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -3289,6 +3289,9 @@ i915_gem_do_execbuffer(struct drm_device *dev,
 		goto err_vma;
 	}
 
+	if (file->f_flags & O_NONBLOCK)
+		i915_request_set_nowait(eb.request);
+
 	if (in_fence) {
 		if (args->flags & I915_EXEC_FENCE_SUBMIT)
 			err = i915_request_await_execution(eb.request,
diff --git a/drivers/gpu/drm/i915/gt/intel_ring.c b/drivers/gpu/drm/i915/gt/intel_ring.c
index aee0a77c77e0..9f149fdc8416 100644
--- a/drivers/gpu/drm/i915/gt/intel_ring.c
+++ b/drivers/gpu/drm/i915/gt/intel_ring.c
@@ -184,9 +184,10 @@ void intel_ring_free(struct kref *ref)
 
 static noinline int
 wait_for_space(struct intel_ring *ring,
-	       struct intel_timeline *tl,
+	       struct i915_request *rq,
 	       unsigned int bytes)
 {
+	struct intel_timeline *tl = i915_request_timeline(rq);
 	struct i915_request *target;
 	long timeout;
 
@@ -207,11 +208,13 @@ wait_for_space(struct intel_ring *ring,
 	if (GEM_WARN_ON(&target->link == &tl->requests))
 		return -ENOSPC;
 
-	timeout = i915_request_wait(target,
-				    I915_WAIT_INTERRUPTIBLE,
-				    MAX_SCHEDULE_TIMEOUT);
-	if (timeout < 0)
-		return timeout;
+	timeout = MAX_SCHEDULE_TIMEOUT;
+	if (i915_request_nowait(rq))
+		timeout = 0;
+
+	timeout = i915_request_wait(target, I915_WAIT_INTERRUPTIBLE, timeout);
+	if (unlikely(timeout < 0))
+		return i915_request_nowait(rq) ? -EWOULDBLOCK : timeout;
 
 	i915_request_retire_upto(target);
 
@@ -271,9 +274,7 @@ u32 *intel_ring_begin(struct i915_request *rq, unsigned int num_dwords)
 		 */
 		GEM_BUG_ON(!rq->reserved_space);
 
-		ret = wait_for_space(ring,
-				     i915_request_timeline(rq),
-				     total_bytes);
+		ret = wait_for_space(ring, rq, total_bytes);
 		if (unlikely(ret))
 			return ERR_PTR(ret);
 	}
diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
index a336d6c40d8b..44b4c2a9f454 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -857,6 +857,8 @@ __i915_request_create(struct intel_context *ce, gfp_t gfp)
 
 	kref_init(&rq->fence.refcount);
 	rq->fence.flags = 0;
+	if ((flags & __GFP_RECLAIM) == 0)
+		__set_bit(I915_FENCE_FLAG_NOWAIT, &rq->fence.flags);
 	rq->fence.error = 0;
 	INIT_LIST_HEAD(&rq->fence.cb_list);
 
diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h
index c0bd4cb8786a..4cecfecc82e5 100644
--- a/drivers/gpu/drm/i915/i915_request.h
+++ b/drivers/gpu/drm/i915/i915_request.h
@@ -137,6 +137,18 @@ enum {
 	 * the GPU. Here we track such boost requests on a per-request basis.
 	 */
 	I915_FENCE_FLAG_BOOST,
+
+	/*
+	 * I915_FENCE_FLAG_NOWAIT - avoid waits while constructing the request
+	 *
+	 * We may wish to construct a request from some contexts where
+	 * we do not want to wait, and sometimes the client would prefer
+	 * to have a nonblocking interface. We may have to wait in a few place
+	 * during request construction (e.g. waiting for space in the
+	 * ringbuffer), this flag allows us to opt out of those waits and
+	 * return -EAGAIN instead.
+	 */
+	I915_FENCE_FLAG_NOWAIT,
 };
 
 /**
@@ -558,6 +570,16 @@ static inline void i915_request_mark_complete(struct i915_request *rq)
 		   (u32 *)&rq->fence.seqno);
 }
 
+static inline bool i915_request_nowait(const struct i915_request *rq)
+{
+	return test_bit(I915_FENCE_FLAG_NOWAIT, &rq->fence.flags);
+}
+
+static inline void i915_request_set_nowait(struct i915_request *rq)
+{
+	set_bit(I915_FENCE_FLAG_NOWAIT, &rq->fence.flags);
+}
+
 static inline bool i915_request_has_waitboost(const struct i915_request *rq)
 {
 	return test_bit(I915_FENCE_FLAG_BOOST, &rq->fence.flags);
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2021-02-03 17:55 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-03 12:47 [Intel-gfx] [PATCH] drm/i915: Prevent waiting inside ring construction for critical sections Chris Wilson
2021-02-03 14:55 ` [Intel-gfx] [PATCH v2] " Chris Wilson
2021-02-03 15:00 ` [Intel-gfx] [PATCH v3] " Chris Wilson
2021-02-03 16:58 ` [Intel-gfx] [PATCH] " kernel test robot
2021-02-03 16:58   ` kernel test robot
2021-02-03 17:24 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Prevent waiting inside ring construction for critical sections (rev3) Patchwork
2021-02-03 17:55 ` [Intel-gfx] ✗ Fi.CI.BAT: failure " Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.