#include <linux/interrupt.h>
#include <linux/string_helpers.h>
#include "i915_drv.h"
#include "i915_reg.h"
#include "i915_trace.h"
#include "i915_vgpu.h"
#include "gen8_engine_cs.h"
#include "intel_breadcrumbs.h"
#include "intel_context.h"
#include "intel_engine_heartbeat.h"
#include "intel_engine_pm.h"
#include "intel_engine_regs.h"
#include "intel_engine_stats.h"
#include "intel_execlists_submission.h"
#include "intel_gt.h"
#include "intel_gt_irq.h"
#include "intel_gt_pm.h"
#include "intel_gt_regs.h"
#include "intel_gt_requests.h"
#include "intel_lrc.h"
#include "intel_lrc_reg.h"
#include "intel_mocs.h"
#include "intel_reset.h"
#include "intel_ring.h"
#include "intel_workarounds.h"
#include "shmem_utils.h"
#define RING_EXECLIST_QFULL …
#define RING_EXECLIST1_VALID …
#define RING_EXECLIST0_VALID …
#define RING_EXECLIST_ACTIVE_STATUS …
#define RING_EXECLIST1_ACTIVE …
#define RING_EXECLIST0_ACTIVE …
#define GEN8_CTX_STATUS_IDLE_ACTIVE …
#define GEN8_CTX_STATUS_PREEMPTED …
#define GEN8_CTX_STATUS_ELEMENT_SWITCH …
#define GEN8_CTX_STATUS_ACTIVE_IDLE …
#define GEN8_CTX_STATUS_COMPLETE …
#define GEN8_CTX_STATUS_LITE_RESTORE …
#define GEN8_CTX_STATUS_COMPLETED_MASK …
#define GEN12_CTX_STATUS_SWITCHED_TO_NEW_QUEUE …
#define GEN12_CTX_SWITCH_DETAIL(csb_dw) …
#define GEN12_CSB_SW_CTX_ID_MASK …
#define GEN12_IDLE_CTX_ID …
#define GEN12_CSB_CTX_VALID(csb_dw) …
#define XEHP_CTX_STATUS_SWITCHED_TO_NEW_QUEUE …
#define XEHP_CSB_SW_CTX_ID_MASK …
#define XEHP_IDLE_CTX_ID …
#define XEHP_CSB_CTX_VALID(csb_dw) …
#define EXECLISTS_REQUEST_SIZE …
struct virtual_engine { … };
static struct virtual_engine *to_virtual_engine(struct intel_engine_cs *engine)
{ … }
static struct intel_context *
execlists_create_virtual(struct intel_engine_cs **siblings, unsigned int count,
unsigned long flags);
static struct i915_request *
__active_request(const struct intel_timeline * const tl,
struct i915_request *rq,
int error)
{ … }
static struct i915_request *
active_request(const struct intel_timeline * const tl, struct i915_request *rq)
{ … }
static void ring_set_paused(const struct intel_engine_cs *engine, int state)
{ … }
static struct i915_priolist *to_priolist(struct rb_node *rb)
{ … }
static int rq_prio(const struct i915_request *rq)
{ … }
static int effective_prio(const struct i915_request *rq)
{ … }
static int queue_prio(const struct i915_sched_engine *sched_engine)
{ … }
static int virtual_prio(const struct intel_engine_execlists *el)
{ … }
static bool need_preempt(const struct intel_engine_cs *engine,
const struct i915_request *rq)
{ … }
__maybe_unused static bool
assert_priority_queue(const struct i915_request *prev,
const struct i915_request *next)
{ … }
static struct i915_request *
__unwind_incomplete_requests(struct intel_engine_cs *engine)
{ … }
struct i915_request *
execlists_unwind_incomplete_requests(struct intel_engine_execlists *execlists)
{ … }
static void
execlists_context_status_change(struct i915_request *rq, unsigned long status)
{ … }
static void reset_active(struct i915_request *rq,
struct intel_engine_cs *engine)
{ … }
static bool bad_request(const struct i915_request *rq)
{ … }
static struct intel_engine_cs *
__execlists_schedule_in(struct i915_request *rq)
{ … }
static void execlists_schedule_in(struct i915_request *rq, int idx)
{ … }
static void
resubmit_virtual_request(struct i915_request *rq, struct virtual_engine *ve)
{ … }
static void kick_siblings(struct i915_request *rq, struct intel_context *ce)
{ … }
static void __execlists_schedule_out(struct i915_request * const rq,
struct intel_context * const ce)
{ … }
static inline void execlists_schedule_out(struct i915_request *rq)
{ … }
static u32 map_i915_prio_to_lrc_desc_prio(int prio)
{ … }
static u64 execlists_update_context(struct i915_request *rq)
{ … }
static void write_desc(struct intel_engine_execlists *execlists, u64 desc, u32 port)
{ … }
static __maybe_unused char *
dump_port(char *buf, int buflen, const char *prefix, struct i915_request *rq)
{ … }
static __maybe_unused noinline void
trace_ports(const struct intel_engine_execlists *execlists,
const char *msg,
struct i915_request * const *ports)
{ … }
static bool
reset_in_progress(const struct intel_engine_cs *engine)
{ … }
static __maybe_unused noinline bool
assert_pending_valid(const struct intel_engine_execlists *execlists,
const char *msg)
{ … }
static void execlists_submit_ports(struct intel_engine_cs *engine)
{ … }
static bool ctx_single_port_submission(const struct intel_context *ce)
{ … }
static bool can_merge_ctx(const struct intel_context *prev,
const struct intel_context *next)
{ … }
static unsigned long i915_request_flags(const struct i915_request *rq)
{ … }
static bool can_merge_rq(const struct i915_request *prev,
const struct i915_request *next)
{ … }
static bool virtual_matches(const struct virtual_engine *ve,
const struct i915_request *rq,
const struct intel_engine_cs *engine)
{ … }
static struct virtual_engine *
first_virtual_engine(struct intel_engine_cs *engine)
{ … }
static void virtual_xfer_context(struct virtual_engine *ve,
struct intel_engine_cs *engine)
{ … }
static void defer_request(struct i915_request *rq, struct list_head * const pl)
{ … }
static void defer_active(struct intel_engine_cs *engine)
{ … }
static bool
timeslice_yield(const struct intel_engine_execlists *el,
const struct i915_request *rq)
{ … }
static bool needs_timeslice(const struct intel_engine_cs *engine,
const struct i915_request *rq)
{ … }
static bool
timeslice_expired(struct intel_engine_cs *engine, const struct i915_request *rq)
{ … }
static unsigned long timeslice(const struct intel_engine_cs *engine)
{ … }
static void start_timeslice(struct intel_engine_cs *engine)
{ … }
static void record_preemption(struct intel_engine_execlists *execlists)
{ … }
static unsigned long active_preempt_timeout(struct intel_engine_cs *engine,
const struct i915_request *rq)
{ … }
static void set_preempt_timeout(struct intel_engine_cs *engine,
const struct i915_request *rq)
{ … }
static bool completed(const struct i915_request *rq)
{ … }
static void execlists_dequeue(struct intel_engine_cs *engine)
{ … }
static void execlists_dequeue_irq(struct intel_engine_cs *engine)
{ … }
static void clear_ports(struct i915_request **ports, int count)
{ … }
static void
copy_ports(struct i915_request **dst, struct i915_request **src, int count)
{ … }
static struct i915_request **
cancel_port_requests(struct intel_engine_execlists * const execlists,
struct i915_request **inactive)
{ … }
static inline bool
__gen12_csb_parse(bool ctx_to_valid, bool ctx_away_valid, bool new_queue,
u8 switch_detail)
{ … }
static bool xehp_csb_parse(const u64 csb)
{ … }
static bool gen12_csb_parse(const u64 csb)
{ … }
static bool gen8_csb_parse(const u64 csb)
{ … }
static noinline u64
wa_csb_read(const struct intel_engine_cs *engine, u64 * const csb)
{ … }
static u64 csb_read(const struct intel_engine_cs *engine, u64 * const csb)
{ … }
static void new_timeslice(struct intel_engine_execlists *el)
{ … }
static struct i915_request **
process_csb(struct intel_engine_cs *engine, struct i915_request **inactive)
{ … }
static void post_process_csb(struct i915_request **port,
struct i915_request **last)
{ … }
static void __execlists_hold(struct i915_request *rq)
{ … }
static bool execlists_hold(struct intel_engine_cs *engine,
struct i915_request *rq)
{ … }
static bool hold_request(const struct i915_request *rq)
{ … }
static void __execlists_unhold(struct i915_request *rq)
{ … }
static void execlists_unhold(struct intel_engine_cs *engine,
struct i915_request *rq)
{ … }
struct execlists_capture { … };
static void execlists_capture_work(struct work_struct *work)
{ … }
static struct execlists_capture *capture_regs(struct intel_engine_cs *engine)
{ … }
static struct i915_request *
active_context(struct intel_engine_cs *engine, u32 ccid)
{ … }
static u32 active_ccid(struct intel_engine_cs *engine)
{ … }
static void execlists_capture(struct intel_engine_cs *engine)
{ … }
static void execlists_reset(struct intel_engine_cs *engine, const char *msg)
{ … }
static bool preempt_timeout(const struct intel_engine_cs *const engine)
{ … }
static void execlists_submission_tasklet(struct tasklet_struct *t)
{ … }
static void execlists_irq_handler(struct intel_engine_cs *engine, u16 iir)
{ … }
static void __execlists_kick(struct intel_engine_execlists *execlists)
{ … }
#define execlists_kick(t, member) …
static void execlists_timeslice(struct timer_list *timer)
{ … }
static void execlists_preempt(struct timer_list *timer)
{ … }
static void queue_request(struct intel_engine_cs *engine,
struct i915_request *rq)
{ … }
static bool submit_queue(struct intel_engine_cs *engine,
const struct i915_request *rq)
{ … }
static bool ancestor_on_hold(const struct intel_engine_cs *engine,
const struct i915_request *rq)
{ … }
static void execlists_submit_request(struct i915_request *request)
{ … }
static int
__execlists_context_pre_pin(struct intel_context *ce,
struct intel_engine_cs *engine,
struct i915_gem_ww_ctx *ww, void **vaddr)
{ … }
static int execlists_context_pre_pin(struct intel_context *ce,
struct i915_gem_ww_ctx *ww,
void **vaddr)
{ … }
static int execlists_context_pin(struct intel_context *ce, void *vaddr)
{ … }
static int execlists_context_alloc(struct intel_context *ce)
{ … }
static void execlists_context_cancel_request(struct intel_context *ce,
struct i915_request *rq)
{ … }
static struct intel_context *
execlists_create_parallel(struct intel_engine_cs **engines,
unsigned int num_siblings,
unsigned int width)
{ … }
static const struct intel_context_ops execlists_context_ops = …;
static int emit_pdps(struct i915_request *rq)
{ … }
static int execlists_request_alloc(struct i915_request *request)
{ … }
static void reset_csb_pointers(struct intel_engine_cs *engine)
{ … }
static void sanitize_hwsp(struct intel_engine_cs *engine)
{ … }
static void execlists_sanitize(struct intel_engine_cs *engine)
{ … }
static void enable_error_interrupt(struct intel_engine_cs *engine)
{ … }
static void enable_execlists(struct intel_engine_cs *engine)
{ … }
static int execlists_resume(struct intel_engine_cs *engine)
{ … }
static void execlists_reset_prepare(struct intel_engine_cs *engine)
{ … }
static struct i915_request **
reset_csb(struct intel_engine_cs *engine, struct i915_request **inactive)
{ … }
static void
execlists_reset_active(struct intel_engine_cs *engine, bool stalled)
{ … }
static void execlists_reset_csb(struct intel_engine_cs *engine, bool stalled)
{ … }
static void execlists_reset_rewind(struct intel_engine_cs *engine, bool stalled)
{ … }
static void nop_submission_tasklet(struct tasklet_struct *t)
{ … }
static void execlists_reset_cancel(struct intel_engine_cs *engine)
{ … }
static void execlists_reset_finish(struct intel_engine_cs *engine)
{ … }
static void gen8_logical_ring_enable_irq(struct intel_engine_cs *engine)
{ … }
static void gen8_logical_ring_disable_irq(struct intel_engine_cs *engine)
{ … }
static void execlists_park(struct intel_engine_cs *engine)
{ … }
static void add_to_engine(struct i915_request *rq)
{ … }
static void remove_from_engine(struct i915_request *rq)
{ … }
static bool can_preempt(struct intel_engine_cs *engine)
{ … }
static void kick_execlists(const struct i915_request *rq, int prio)
{ … }
static void execlists_set_default_submission(struct intel_engine_cs *engine)
{ … }
static void execlists_shutdown(struct intel_engine_cs *engine)
{ … }
static void execlists_release(struct intel_engine_cs *engine)
{ … }
static ktime_t __execlists_engine_busyness(struct intel_engine_cs *engine,
ktime_t *now)
{ … }
static ktime_t execlists_engine_busyness(struct intel_engine_cs *engine,
ktime_t *now)
{ … }
static void
logical_ring_default_vfuncs(struct intel_engine_cs *engine)
{ … }
static void logical_ring_default_irqs(struct intel_engine_cs *engine)
{ … }
static void rcs_submission_override(struct intel_engine_cs *engine)
{ … }
int intel_execlists_submission_setup(struct intel_engine_cs *engine)
{ … }
static struct list_head *virtual_queue(struct virtual_engine *ve)
{ … }
static void rcu_virtual_context_destroy(struct work_struct *wrk)
{ … }
static void virtual_context_destroy(struct kref *kref)
{ … }
static void virtual_engine_initial_hint(struct virtual_engine *ve)
{ … }
static int virtual_context_alloc(struct intel_context *ce)
{ … }
static int virtual_context_pre_pin(struct intel_context *ce,
struct i915_gem_ww_ctx *ww,
void **vaddr)
{ … }
static int virtual_context_pin(struct intel_context *ce, void *vaddr)
{ … }
static void virtual_context_enter(struct intel_context *ce)
{ … }
static void virtual_context_exit(struct intel_context *ce)
{ … }
static struct intel_engine_cs *
virtual_get_sibling(struct intel_engine_cs *engine, unsigned int sibling)
{ … }
static const struct intel_context_ops virtual_context_ops = …;
static intel_engine_mask_t virtual_submission_mask(struct virtual_engine *ve)
{ … }
static void virtual_submission_tasklet(struct tasklet_struct *t)
{ … }
static void virtual_submit_request(struct i915_request *rq)
{ … }
static struct intel_context *
execlists_create_virtual(struct intel_engine_cs **siblings, unsigned int count,
unsigned long flags)
{ … }
void intel_execlists_show_requests(struct intel_engine_cs *engine,
struct drm_printer *m,
void (*show_request)(struct drm_printer *m,
const struct i915_request *rq,
const char *prefix,
int indent),
unsigned int max)
{ … }
void intel_execlists_dump_active_requests(struct intel_engine_cs *engine,
struct i915_request *hung_rq,
struct drm_printer *m)
{ … }
#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
#include "selftest_execlists.c"
#endif