diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_request.h')
| -rw-r--r-- | drivers/gpu/drm/i915/i915_request.h | 141 |
1 files changed, 115 insertions, 26 deletions
diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h index 270f6cd37650..b09135301f39 100644 --- a/drivers/gpu/drm/i915/i915_request.h +++ b/drivers/gpu/drm/i915/i915_request.h @@ -31,28 +31,37 @@ #include <linux/llist.h> #include <linux/lockdep.h> +#include <uapi/drm/i915_drm.h> + #include "gem/i915_gem_context_types.h" #include "gt/intel_context_types.h" #include "gt/intel_engine_types.h" #include "gt/intel_timeline_types.h" #include "i915_gem.h" +#include "i915_ptr_util.h" #include "i915_scheduler.h" #include "i915_selftest.h" #include "i915_sw_fence.h" - -#include <uapi/drm/i915_drm.h> +#include "i915_vma_resource.h" struct drm_file; struct drm_i915_gem_object; struct drm_printer; +struct i915_deps; struct i915_request; +#if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR) struct i915_capture_list { + struct i915_vma_resource *vma_res; struct i915_capture_list *next; - struct i915_vma *vma; }; +void i915_request_free_capture_list(struct i915_capture_list *capture); +#else +#define i915_request_free_capture_list(_a) do {} while (0) +#endif + #define RQ_TRACE(rq, fmt, ...) do { \ const struct i915_request *rq__ = (rq); \ ENGINE_TRACE(rq__->engine, "fence %llx:%lld, current %d " fmt, \ @@ -139,9 +148,32 @@ enum { * the GPU. Here we track such boost requests on a per-request basis. */ I915_FENCE_FLAG_BOOST, + + /* + * I915_FENCE_FLAG_SUBMIT_PARALLEL - request with a context in a + * parent-child relationship (parallel submission, multi-lrc) should + * trigger a submission to the GuC rather than just moving the context + * tail. + */ + I915_FENCE_FLAG_SUBMIT_PARALLEL, + + /* + * I915_FENCE_FLAG_SKIP_PARALLEL - request with a context in a + * parent-child relationship (parallel submission, multi-lrc) that + * hit an error while generating requests in the execbuf IOCTL. + * Indicates this request should be skipped as another request in + * submission / relationship encountered an error. + */ + I915_FENCE_FLAG_SKIP_PARALLEL, + + /* + * I915_FENCE_FLAG_COMPOSITE - Indicates fence is part of a composite + * fence (dma_fence_array) and i915 generated for parallel submission. + */ + I915_FENCE_FLAG_COMPOSITE, }; -/** +/* * Request queue structure. * * The request queue allows us to note sequence numbers that have been emitted @@ -156,7 +188,7 @@ enum { * RCU lookup of it that may race against reallocation of the struct * from the slab freelist. We intentionally do not zero the structure on * allocation so that the lookup can use the dangling pointers (and is - * cogniscent that those pointers may be wrong). Instead, everything that + * cognisant that those pointers may be wrong). Instead, everything that * needs to be initialised must be done so explicitly. * * The requests are reference counted. @@ -165,7 +197,9 @@ struct i915_request { struct dma_fence fence; spinlock_t lock; - /** + struct drm_i915_private *i915; + + /* * Context and ring buffer related to this request * Contexts are refcounted, so when this request is associated with a * context, we must increment the context's refcount, to guarantee that @@ -218,6 +252,11 @@ struct i915_request { }; struct llist_head execute_cb; struct i915_sw_fence semaphore; + /* + * complete submit fence from an IRQ if needed for locking hierarchy + * reasons. + */ + struct irq_work submit_work; /* * A list of everyone we wait upon, and everyone who waits upon us. @@ -239,52 +278,82 @@ struct i915_request { */ const u32 *hwsp_seqno; - /** Position in the ring of the start of the request */ + /* Position in the ring of the start of the request */ u32 head; - /** Position in the ring of the start of the user packets */ + /* Position in the ring of the start of the user packets */ u32 infix; - /** + /* * Position in the ring of the start of the postfix. * This is required to calculate the maximum available ring space * without overwriting the postfix. */ u32 postfix; - /** Position in the ring of the end of the whole request */ + /* Position in the ring of the end of the whole request */ u32 tail; - /** Position in the ring of the end of any workarounds after the tail */ + /* Position in the ring of the end of any workarounds after the tail */ u32 wa_tail; - /** Preallocate space in the ring for the emitting the request */ + /* Preallocate space in the ring for the emitting the request */ u32 reserved_space; - /** Batch buffer related to this request if any (used for - * error state dump only). - */ - struct i915_vma *batch; - /** + /* Batch buffer pointer for selftest internal use. */ + I915_SELFTEST_DECLARE(struct i915_vma *batch); + + struct i915_vma_resource *batch_res; + +#if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR) + /* * Additional buffers requested by userspace to be captured upon * a GPU hang. The vma/obj on this list are protected by their * active reference - all objects on this list must also be * on the active_list (of their final request). */ struct i915_capture_list *capture_list; +#endif - /** Time at which this request was emitted, in jiffies. */ + /* Time at which this request was emitted, in jiffies. */ unsigned long emitted_jiffies; - /** timeline->request entry for this request */ + /* timeline->request entry for this request */ struct list_head link; - /** Watchdog support fields. */ + /* Watchdog support fields. */ struct i915_request_watchdog { struct llist_node link; struct hrtimer timer; } watchdog; + /* + * Requests may need to be stalled when using GuC submission waiting for + * certain GuC operations to complete. If that is the case, stalled + * requests are added to a per context list of stalled requests. The + * below list_head is the link in that list. Protected by + * ce->guc_state.lock. + */ + struct list_head guc_fence_link; + + /* + * Priority level while the request is in flight. Differs + * from i915 scheduler priority. See comment above + * I915_SCHEDULER_CAP_STATIC_PRIORITY_MAP for details. Protected by + * ce->guc_active.lock. Two special values (GUC_PRIO_INIT and + * GUC_PRIO_FINI) outside the GuC priority range are used to indicate + * if the priority has not been initialized yet or if no more updates + * are possible because the request has completed. + */ +#define GUC_PRIO_INIT 0xff +#define GUC_PRIO_FINI 0xfe + u8 guc_prio; + + /* + * wait queue entry used to wait on the HuC load to complete + */ + wait_queue_entry_t hucq; + I915_SELFTEST_DECLARE(struct { struct list_head link; unsigned long delay; @@ -351,10 +420,9 @@ int i915_request_await_object(struct i915_request *to, bool write); int i915_request_await_dma_fence(struct i915_request *rq, struct dma_fence *fence); +int i915_request_await_deps(struct i915_request *rq, const struct i915_deps *deps); int i915_request_await_execution(struct i915_request *rq, - struct dma_fence *fence, - void (*hook)(struct i915_request *rq, - struct dma_fence *signal)); + struct dma_fence *fence); void i915_request_add(struct i915_request *rq); @@ -366,6 +434,11 @@ void i915_request_unsubmit(struct i915_request *request); void i915_request_cancel(struct i915_request *rq, int error); +long i915_request_wait_timeout(struct i915_request *rq, + unsigned int flags, + long timeout) + __attribute__((nonnull(1))); + long i915_request_wait(struct i915_request *rq, unsigned int flags, long timeout) @@ -401,7 +474,7 @@ i915_request_has_initial_breadcrumb(const struct i915_request *rq) return test_bit(I915_FENCE_FLAG_INITIAL_BREADCRUMB, &rq->fence.flags); } -/** +/* * Returns true if seq1 is later than seq2. */ static inline bool i915_seqno_passed(u32 seq1, u32 seq2) @@ -594,7 +667,8 @@ i915_request_timeline(const struct i915_request *rq) { /* Valid only while the request is being constructed (or retired). */ return rcu_dereference_protected(rq->timeline, - lockdep_is_held(&rcu_access_pointer(rq->timeline)->mutex)); + lockdep_is_held(&rcu_access_pointer(rq->timeline)->mutex) || + test_bit(CONTEXT_IS_PARKING, &rq->context->flags)); } static inline struct i915_gem_context * @@ -613,7 +687,7 @@ i915_request_active_timeline(const struct i915_request *rq) * this submission. */ return rcu_dereference_protected(rq->timeline, - lockdep_is_held(&rq->engine->active.lock)); + lockdep_is_held(&rq->engine->sched_engine->lock)); } static inline u32 @@ -641,4 +715,19 @@ bool i915_request_active_engine(struct i915_request *rq, struct intel_engine_cs **active); +void i915_request_notify_execute_cb_imm(struct i915_request *rq); + +enum i915_request_state { + I915_REQUEST_UNKNOWN = 0, + I915_REQUEST_COMPLETE, + I915_REQUEST_PENDING, + I915_REQUEST_QUEUED, + I915_REQUEST_ACTIVE, +}; + +enum i915_request_state i915_test_request_state(struct i915_request *rq); + +void i915_request_module_exit(void); +int i915_request_module_init(void); + #endif /* I915_REQUEST_H */ |
