1*24f90d66SChris Wilson /* SPDX-License-Identifier: MIT */ 2112ed2d3SChris Wilson /* 3112ed2d3SChris Wilson * Copyright © 2019 Intel Corporation 4112ed2d3SChris Wilson */ 5112ed2d3SChris Wilson 6112ed2d3SChris Wilson #ifndef __INTEL_CONTEXT_H__ 7112ed2d3SChris Wilson #define __INTEL_CONTEXT_H__ 8112ed2d3SChris Wilson 99f3ccd40SChris Wilson #include <linux/bitops.h> 10112ed2d3SChris Wilson #include <linux/lockdep.h> 119f3ccd40SChris Wilson #include <linux/types.h> 12112ed2d3SChris Wilson 1312c255b5SChris Wilson #include "i915_active.h" 141883a0a4STvrtko Ursulin #include "i915_drv.h" 15112ed2d3SChris Wilson #include "intel_context_types.h" 16112ed2d3SChris Wilson #include "intel_engine_types.h" 172871ea85SChris Wilson #include "intel_ring_types.h" 18e5dadff4SChris Wilson #include "intel_timeline_types.h" 19112ed2d3SChris Wilson 20639f2f24SVenkata Sandeep Dhanalakota #define CE_TRACE(ce, fmt, ...) do { \ 21639f2f24SVenkata Sandeep Dhanalakota const struct intel_context *ce__ = (ce); \ 22639f2f24SVenkata Sandeep Dhanalakota ENGINE_TRACE(ce__->engine, "context:%llx " fmt, \ 23639f2f24SVenkata Sandeep Dhanalakota ce__->timeline->fence_context, \ 24639f2f24SVenkata Sandeep Dhanalakota ##__VA_ARGS__); \ 25639f2f24SVenkata Sandeep Dhanalakota } while (0) 26639f2f24SVenkata Sandeep Dhanalakota 2747b08693SMaarten Lankhorst struct i915_gem_ww_ctx; 2847b08693SMaarten Lankhorst 29112ed2d3SChris Wilson void intel_context_init(struct intel_context *ce, 30112ed2d3SChris Wilson struct intel_engine_cs *engine); 31df8cf31eSChris Wilson void intel_context_fini(struct intel_context *ce); 32112ed2d3SChris Wilson 33112ed2d3SChris Wilson struct intel_context * 34e6ba7648SChris Wilson intel_context_create(struct intel_engine_cs *engine); 35112ed2d3SChris Wilson 3689f98d63SChris Wilson int intel_context_alloc_state(struct intel_context *ce); 3789f98d63SChris Wilson 385e2a0419SChris Wilson void intel_context_free(struct intel_context *ce); 395e2a0419SChris Wilson 40b4d3acaaSChris Wilson int intel_context_reconfigure_sseu(struct intel_context *ce, 41b4d3acaaSChris Wilson const struct intel_sseu sseu); 42b4d3acaaSChris Wilson 43112ed2d3SChris Wilson /** 446b736de5SChris Wilson * intel_context_lock_pinned - Stablises the 'pinned' status of the HW context 456b736de5SChris Wilson * @ce - the context 46112ed2d3SChris Wilson * 47112ed2d3SChris Wilson * Acquire a lock on the pinned status of the HW context, such that the context 48112ed2d3SChris Wilson * can neither be bound to the GPU or unbound whilst the lock is held, i.e. 49112ed2d3SChris Wilson * intel_context_is_pinned() remains stable. 50112ed2d3SChris Wilson */ 516b736de5SChris Wilson static inline int intel_context_lock_pinned(struct intel_context *ce) 526b736de5SChris Wilson __acquires(ce->pin_mutex) 536b736de5SChris Wilson { 546b736de5SChris Wilson return mutex_lock_interruptible(&ce->pin_mutex); 556b736de5SChris Wilson } 56112ed2d3SChris Wilson 576b736de5SChris Wilson /** 586b736de5SChris Wilson * intel_context_is_pinned - Reports the 'pinned' status 596b736de5SChris Wilson * @ce - the context 606b736de5SChris Wilson * 616b736de5SChris Wilson * While in use by the GPU, the context, along with its ring and page 626b736de5SChris Wilson * tables is pinned into memory and the GTT. 636b736de5SChris Wilson * 646b736de5SChris Wilson * Returns: true if the context is currently pinned for use by the GPU. 656b736de5SChris Wilson */ 66112ed2d3SChris Wilson static inline bool 67112ed2d3SChris Wilson intel_context_is_pinned(struct intel_context *ce) 68112ed2d3SChris Wilson { 69112ed2d3SChris Wilson return atomic_read(&ce->pin_count); 70112ed2d3SChris Wilson } 71112ed2d3SChris Wilson 726b736de5SChris Wilson /** 736b736de5SChris Wilson * intel_context_unlock_pinned - Releases the earlier locking of 'pinned' status 746b736de5SChris Wilson * @ce - the context 756b736de5SChris Wilson * 766b736de5SChris Wilson * Releases the lock earlier acquired by intel_context_unlock_pinned(). 776b736de5SChris Wilson */ 786b736de5SChris Wilson static inline void intel_context_unlock_pinned(struct intel_context *ce) 796b736de5SChris Wilson __releases(ce->pin_mutex) 806b736de5SChris Wilson { 816b736de5SChris Wilson mutex_unlock(&ce->pin_mutex); 826b736de5SChris Wilson } 83112ed2d3SChris Wilson 84fa9f6681SChris Wilson int __intel_context_do_pin(struct intel_context *ce); 8547b08693SMaarten Lankhorst int __intel_context_do_pin_ww(struct intel_context *ce, 8647b08693SMaarten Lankhorst struct i915_gem_ww_ctx *ww); 87fa9f6681SChris Wilson 88feed5c7bSChris Wilson static inline bool intel_context_pin_if_active(struct intel_context *ce) 89feed5c7bSChris Wilson { 90feed5c7bSChris Wilson return atomic_inc_not_zero(&ce->pin_count); 91feed5c7bSChris Wilson } 92feed5c7bSChris Wilson 93fa9f6681SChris Wilson static inline int intel_context_pin(struct intel_context *ce) 94fa9f6681SChris Wilson { 95feed5c7bSChris Wilson if (likely(intel_context_pin_if_active(ce))) 96fa9f6681SChris Wilson return 0; 97fa9f6681SChris Wilson 98fa9f6681SChris Wilson return __intel_context_do_pin(ce); 99fa9f6681SChris Wilson } 100112ed2d3SChris Wilson 10147b08693SMaarten Lankhorst static inline int intel_context_pin_ww(struct intel_context *ce, 10247b08693SMaarten Lankhorst struct i915_gem_ww_ctx *ww) 10347b08693SMaarten Lankhorst { 10447b08693SMaarten Lankhorst if (likely(intel_context_pin_if_active(ce))) 10547b08693SMaarten Lankhorst return 0; 10647b08693SMaarten Lankhorst 10747b08693SMaarten Lankhorst return __intel_context_do_pin_ww(ce, ww); 10847b08693SMaarten Lankhorst } 10947b08693SMaarten Lankhorst 110112ed2d3SChris Wilson static inline void __intel_context_pin(struct intel_context *ce) 111112ed2d3SChris Wilson { 112112ed2d3SChris Wilson GEM_BUG_ON(!intel_context_is_pinned(ce)); 113112ed2d3SChris Wilson atomic_inc(&ce->pin_count); 114112ed2d3SChris Wilson } 115112ed2d3SChris Wilson 116112ed2d3SChris Wilson void intel_context_unpin(struct intel_context *ce); 117112ed2d3SChris Wilson 1186eee33e8SChris Wilson void intel_context_enter_engine(struct intel_context *ce); 1196eee33e8SChris Wilson void intel_context_exit_engine(struct intel_context *ce); 1206eee33e8SChris Wilson 1216eee33e8SChris Wilson static inline void intel_context_enter(struct intel_context *ce) 1226eee33e8SChris Wilson { 1236c69a454SChris Wilson lockdep_assert_held(&ce->timeline->mutex); 1246eee33e8SChris Wilson if (!ce->active_count++) 1256eee33e8SChris Wilson ce->ops->enter(ce); 1266eee33e8SChris Wilson } 1276eee33e8SChris Wilson 1286eee33e8SChris Wilson static inline void intel_context_mark_active(struct intel_context *ce) 1296eee33e8SChris Wilson { 1306c69a454SChris Wilson lockdep_assert_held(&ce->timeline->mutex); 1316eee33e8SChris Wilson ++ce->active_count; 1326eee33e8SChris Wilson } 1336eee33e8SChris Wilson 1346eee33e8SChris Wilson static inline void intel_context_exit(struct intel_context *ce) 1356eee33e8SChris Wilson { 1366c69a454SChris Wilson lockdep_assert_held(&ce->timeline->mutex); 1376eee33e8SChris Wilson GEM_BUG_ON(!ce->active_count); 1386eee33e8SChris Wilson if (!--ce->active_count) 1396eee33e8SChris Wilson ce->ops->exit(ce); 1406eee33e8SChris Wilson } 1416eee33e8SChris Wilson 142112ed2d3SChris Wilson static inline struct intel_context *intel_context_get(struct intel_context *ce) 143112ed2d3SChris Wilson { 144112ed2d3SChris Wilson kref_get(&ce->ref); 145112ed2d3SChris Wilson return ce; 146112ed2d3SChris Wilson } 147112ed2d3SChris Wilson 148112ed2d3SChris Wilson static inline void intel_context_put(struct intel_context *ce) 149112ed2d3SChris Wilson { 150112ed2d3SChris Wilson kref_put(&ce->ref, ce->ops->destroy); 151112ed2d3SChris Wilson } 152112ed2d3SChris Wilson 153e5dadff4SChris Wilson static inline struct intel_timeline *__must_check 154f4d57d83SChris Wilson intel_context_timeline_lock(struct intel_context *ce) 15575d0a7f3SChris Wilson __acquires(&ce->timeline->mutex) 1562ccdf6a1SChris Wilson { 157e5dadff4SChris Wilson struct intel_timeline *tl = ce->timeline; 158e5dadff4SChris Wilson int err; 159e5dadff4SChris Wilson 160e5dadff4SChris Wilson err = mutex_lock_interruptible(&tl->mutex); 161e5dadff4SChris Wilson if (err) 162e5dadff4SChris Wilson return ERR_PTR(err); 163e5dadff4SChris Wilson 164e5dadff4SChris Wilson return tl; 1652ccdf6a1SChris Wilson } 1662ccdf6a1SChris Wilson 167e5dadff4SChris Wilson static inline void intel_context_timeline_unlock(struct intel_timeline *tl) 168e5dadff4SChris Wilson __releases(&tl->mutex) 1692ccdf6a1SChris Wilson { 170e5dadff4SChris Wilson mutex_unlock(&tl->mutex); 1712ccdf6a1SChris Wilson } 1722ccdf6a1SChris Wilson 173a9877da2SChris Wilson int intel_context_prepare_remote_request(struct intel_context *ce, 174a9877da2SChris Wilson struct i915_request *rq); 175a9877da2SChris Wilson 1765e2a0419SChris Wilson struct i915_request *intel_context_create_request(struct intel_context *ce); 1775e2a0419SChris Wilson 17848ae397bSChris Wilson static inline struct intel_ring *__intel_context_ring_size(u64 sz) 17948ae397bSChris Wilson { 18048ae397bSChris Wilson return u64_to_ptr(struct intel_ring, sz); 18148ae397bSChris Wilson } 18248ae397bSChris Wilson 183e6ba7648SChris Wilson static inline bool intel_context_is_barrier(const struct intel_context *ce) 184e6ba7648SChris Wilson { 185e6ba7648SChris Wilson return test_bit(CONTEXT_BARRIER_BIT, &ce->flags); 186e6ba7648SChris Wilson } 187e6ba7648SChris Wilson 1882e46a2a0SChris Wilson static inline bool intel_context_is_closed(const struct intel_context *ce) 1892e46a2a0SChris Wilson { 1902e46a2a0SChris Wilson return test_bit(CONTEXT_CLOSED_BIT, &ce->flags); 1912e46a2a0SChris Wilson } 1922e46a2a0SChris Wilson 193cc1557caSChris Wilson static inline bool intel_context_has_inflight(const struct intel_context *ce) 194cc1557caSChris Wilson { 195cc1557caSChris Wilson return test_bit(COPS_HAS_INFLIGHT_BIT, &ce->ops->flags); 196cc1557caSChris Wilson } 197cc1557caSChris Wilson 1980f100b70SChris Wilson static inline bool intel_context_use_semaphores(const struct intel_context *ce) 1990f100b70SChris Wilson { 2000f100b70SChris Wilson return test_bit(CONTEXT_USE_SEMAPHORES, &ce->flags); 2010f100b70SChris Wilson } 2020f100b70SChris Wilson 2030f100b70SChris Wilson static inline void intel_context_set_use_semaphores(struct intel_context *ce) 2040f100b70SChris Wilson { 2050f100b70SChris Wilson set_bit(CONTEXT_USE_SEMAPHORES, &ce->flags); 2060f100b70SChris Wilson } 2070f100b70SChris Wilson 2080f100b70SChris Wilson static inline void intel_context_clear_use_semaphores(struct intel_context *ce) 2090f100b70SChris Wilson { 2100f100b70SChris Wilson clear_bit(CONTEXT_USE_SEMAPHORES, &ce->flags); 2110f100b70SChris Wilson } 2120f100b70SChris Wilson 2139f3ccd40SChris Wilson static inline bool intel_context_is_banned(const struct intel_context *ce) 2149f3ccd40SChris Wilson { 2159f3ccd40SChris Wilson return test_bit(CONTEXT_BANNED, &ce->flags); 2169f3ccd40SChris Wilson } 2179f3ccd40SChris Wilson 2189f3ccd40SChris Wilson static inline bool intel_context_set_banned(struct intel_context *ce) 2199f3ccd40SChris Wilson { 2209f3ccd40SChris Wilson return test_and_set_bit(CONTEXT_BANNED, &ce->flags); 2219f3ccd40SChris Wilson } 2229f3ccd40SChris Wilson 2239f3ccd40SChris Wilson static inline bool 2249f3ccd40SChris Wilson intel_context_force_single_submission(const struct intel_context *ce) 2259f3ccd40SChris Wilson { 2269f3ccd40SChris Wilson return test_bit(CONTEXT_FORCE_SINGLE_SUBMISSION, &ce->flags); 2279f3ccd40SChris Wilson } 2289f3ccd40SChris Wilson 2299f3ccd40SChris Wilson static inline void 2309f3ccd40SChris Wilson intel_context_set_single_submission(struct intel_context *ce) 2319f3ccd40SChris Wilson { 2329f3ccd40SChris Wilson __set_bit(CONTEXT_FORCE_SINGLE_SUBMISSION, &ce->flags); 2339f3ccd40SChris Wilson } 2349f3ccd40SChris Wilson 2359f3ccd40SChris Wilson static inline bool 2369f3ccd40SChris Wilson intel_context_nopreempt(const struct intel_context *ce) 2379f3ccd40SChris Wilson { 2389f3ccd40SChris Wilson return test_bit(CONTEXT_NOPREEMPT, &ce->flags); 2399f3ccd40SChris Wilson } 2409f3ccd40SChris Wilson 2419f3ccd40SChris Wilson static inline void 2429f3ccd40SChris Wilson intel_context_set_nopreempt(struct intel_context *ce) 2439f3ccd40SChris Wilson { 2449f3ccd40SChris Wilson set_bit(CONTEXT_NOPREEMPT, &ce->flags); 2459f3ccd40SChris Wilson } 2469f3ccd40SChris Wilson 2479f3ccd40SChris Wilson static inline void 2489f3ccd40SChris Wilson intel_context_clear_nopreempt(struct intel_context *ce) 2499f3ccd40SChris Wilson { 2509f3ccd40SChris Wilson clear_bit(CONTEXT_NOPREEMPT, &ce->flags); 2519f3ccd40SChris Wilson } 2529f3ccd40SChris Wilson 2531883a0a4STvrtko Ursulin static inline u64 intel_context_get_total_runtime_ns(struct intel_context *ce) 2541883a0a4STvrtko Ursulin { 255f170523aSChris Wilson const u32 period = ce->engine->gt->clock_period_ns; 2561883a0a4STvrtko Ursulin 2571883a0a4STvrtko Ursulin return READ_ONCE(ce->runtime.total) * period; 2581883a0a4STvrtko Ursulin } 2591883a0a4STvrtko Ursulin 2601883a0a4STvrtko Ursulin static inline u64 intel_context_get_avg_runtime_ns(struct intel_context *ce) 2611883a0a4STvrtko Ursulin { 262f170523aSChris Wilson const u32 period = ce->engine->gt->clock_period_ns; 2631883a0a4STvrtko Ursulin 2641883a0a4STvrtko Ursulin return mul_u32_u32(ewma_runtime_read(&ce->runtime.avg), period); 2651883a0a4STvrtko Ursulin } 2661883a0a4STvrtko Ursulin 267112ed2d3SChris Wilson #endif /* __INTEL_CONTEXT_H__ */ 268