aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_ringbuffer.h
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2017-05-17 08:10:03 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2017-05-17 08:38:09 -0400
commit6c067579e69b42bff476959fd7bb561ffa3f11e0 (patch)
treeef187856eb24eabdcdc5983432615b08935bc753 /drivers/gpu/drm/i915/intel_ringbuffer.h
parente4f815f6bf4694b275defee97d2cd36a4764d6a1 (diff)
drm/i915: Split execlist priority queue into rbtree + linked list
All the requests at the same priority are executed in FIFO order. They do not need to be stored in the rbtree themselves, as they are a simple list within a level. If we move the requests at one priority into a list, we can then reduce the rbtree to the set of priorities. This should keep the height of the rbtree small, as the number of active priorities can not exceed the number of active requests and should be typically only a few. Currently, we have ~2k possible different priority levels, that may increase to allow even more fine grained selection. Allocating those in advance seems a waste (and may be impossible), so we opt for allocating upon first use, and freeing after its requests are depleted. To avoid the possibility of an allocation failure causing us to lose a request, we preallocate the default priority (0) and bump any request to that priority if we fail to allocate it the appropriate plist. Having a request (that is ready to run, so not leading to corruption) execute out-of-order is better than leaking the request (and its dependency tree) entirely. There should be a benefit to reducing execlists_dequeue() to principally using a simple list (and reducing the frequency of both rbtree iteration and balancing on erase) but for typical workloads, request coalescing should be small enough that we don't notice any change. The main gain is from improving PI calls to schedule, and the explicit list within a level should make request unwinding simpler (we just need to insert at the head of the list rather than the tail and not have to make the rbtree search more complicated). v2: Avoid use-after-free when deleting a depleted priolist v3: Michał found the solution to handling the allocation failure gracefully. If we disable all priority scheduling following the allocation failure, those requests will be executed in fifo and we will ensure that this request and its dependencies are in strict fifo (even when it doesn't realise it is only a single list). Normal scheduling is restored once we know the device is idle, until the next failure! Suggested-by: Michał Wajdeczko <michal.wajdeczko@intel.com> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Michał Winiarski <michal.winiarski@intel.com> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Reviewed-by: Michał Winiarski <michal.winiarski@intel.com> Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170517121007.27224-8-chris@chris-wilson.co.uk
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.h')
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.h9
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 162f0a9c6abe..6aa20ac8cde3 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -177,6 +177,12 @@ enum intel_engine_id {
177 VECS 177 VECS
178}; 178};
179 179
180struct i915_priolist {
181 struct rb_node node;
182 struct list_head requests;
183 int priority;
184};
185
180#define INTEL_ENGINE_CS_MAX_NAME 8 186#define INTEL_ENGINE_CS_MAX_NAME 8
181 187
182struct intel_engine_cs { 188struct intel_engine_cs {
@@ -367,6 +373,8 @@ struct intel_engine_cs {
367 373
368 /* Execlists */ 374 /* Execlists */
369 struct tasklet_struct irq_tasklet; 375 struct tasklet_struct irq_tasklet;
376 struct i915_priolist default_priolist;
377 bool no_priolist;
370 struct execlist_port { 378 struct execlist_port {
371 struct drm_i915_gem_request *request_count; 379 struct drm_i915_gem_request *request_count;
372#define EXECLIST_COUNT_BITS 2 380#define EXECLIST_COUNT_BITS 2
@@ -723,6 +731,7 @@ static inline u32 *gen8_emit_pipe_control(u32 *batch, u32 flags, u32 offset)
723bool intel_engine_is_idle(struct intel_engine_cs *engine); 731bool intel_engine_is_idle(struct intel_engine_cs *engine);
724bool intel_engines_are_idle(struct drm_i915_private *dev_priv); 732bool intel_engines_are_idle(struct drm_i915_private *dev_priv);
725 733
734void intel_engines_mark_idle(struct drm_i915_private *i915);
726void intel_engines_reset_default_submission(struct drm_i915_private *i915); 735void intel_engines_reset_default_submission(struct drm_i915_private *i915);
727 736
728#endif /* _INTEL_RINGBUFFER_H_ */ 737#endif /* _INTEL_RINGBUFFER_H_ */