15ca02815Sjsg // SPDX-License-Identifier: MIT 2c349dbc7Sjsg /* 3c349dbc7Sjsg * Copyright © 2019 Intel Corporation 4c349dbc7Sjsg */ 5c349dbc7Sjsg 6c349dbc7Sjsg #include "gem/i915_gem_context.h" 7c349dbc7Sjsg #include "gem/i915_gem_pm.h" 8c349dbc7Sjsg 9c349dbc7Sjsg #include "i915_drv.h" 105ca02815Sjsg #include "i915_trace.h" 11c349dbc7Sjsg 12c349dbc7Sjsg #include "intel_context.h" 13c349dbc7Sjsg #include "intel_engine.h" 14c349dbc7Sjsg #include "intel_engine_pm.h" 15c349dbc7Sjsg #include "intel_ring.h" 16c349dbc7Sjsg 175ca02815Sjsg static struct pool slab_ce; 18c349dbc7Sjsg 19c349dbc7Sjsg static struct intel_context *intel_context_alloc(void) 20c349dbc7Sjsg { 21c349dbc7Sjsg #ifdef __linux__ 225ca02815Sjsg return kmem_cache_zalloc(slab_ce, GFP_KERNEL); 23c349dbc7Sjsg #else 245ca02815Sjsg return pool_get(&slab_ce, PR_WAITOK | PR_ZERO); 25c349dbc7Sjsg #endif 26c349dbc7Sjsg } 27c349dbc7Sjsg 28ad8b1aafSjsg static void rcu_context_free(struct rcu_head *rcu) 29c349dbc7Sjsg { 30ad8b1aafSjsg struct intel_context *ce = container_of(rcu, typeof(*ce), rcu); 31ad8b1aafSjsg 325ca02815Sjsg trace_intel_context_free(ce); 33c349dbc7Sjsg #ifdef __linux__ 345ca02815Sjsg kmem_cache_free(slab_ce, ce); 35c349dbc7Sjsg #else 365ca02815Sjsg pool_put(&slab_ce, ce); 37c349dbc7Sjsg #endif 38c349dbc7Sjsg } 39c349dbc7Sjsg 40ad8b1aafSjsg void intel_context_free(struct intel_context *ce) 41ad8b1aafSjsg { 42ad8b1aafSjsg call_rcu(&ce->rcu, rcu_context_free); 43ad8b1aafSjsg } 44ad8b1aafSjsg 45c349dbc7Sjsg struct intel_context * 46c349dbc7Sjsg intel_context_create(struct intel_engine_cs *engine) 47c349dbc7Sjsg { 48c349dbc7Sjsg struct intel_context *ce; 49c349dbc7Sjsg 50c349dbc7Sjsg ce = intel_context_alloc(); 51c349dbc7Sjsg if (!ce) 52c349dbc7Sjsg return ERR_PTR(-ENOMEM); 53c349dbc7Sjsg 54c349dbc7Sjsg intel_context_init(ce, engine); 555ca02815Sjsg trace_intel_context_create(ce); 56c349dbc7Sjsg return ce; 57c349dbc7Sjsg } 58c349dbc7Sjsg 59c349dbc7Sjsg int intel_context_alloc_state(struct intel_context *ce) 60c349dbc7Sjsg { 61c349dbc7Sjsg int err = 0; 62c349dbc7Sjsg 63c349dbc7Sjsg if (mutex_lock_interruptible(&ce->pin_mutex)) 64c349dbc7Sjsg return -EINTR; 65c349dbc7Sjsg 66c349dbc7Sjsg if (!test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) { 67c349dbc7Sjsg if (intel_context_is_banned(ce)) { 68c349dbc7Sjsg err = -EIO; 69c349dbc7Sjsg goto unlock; 70c349dbc7Sjsg } 71c349dbc7Sjsg 72c349dbc7Sjsg err = ce->ops->alloc(ce); 73c349dbc7Sjsg if (unlikely(err)) 74c349dbc7Sjsg goto unlock; 75c349dbc7Sjsg 76c349dbc7Sjsg set_bit(CONTEXT_ALLOC_BIT, &ce->flags); 77c349dbc7Sjsg } 78c349dbc7Sjsg 79c349dbc7Sjsg unlock: 80c349dbc7Sjsg mutex_unlock(&ce->pin_mutex); 81c349dbc7Sjsg return err; 82c349dbc7Sjsg } 83c349dbc7Sjsg 84c349dbc7Sjsg static int intel_context_active_acquire(struct intel_context *ce) 85c349dbc7Sjsg { 86c349dbc7Sjsg int err; 87c349dbc7Sjsg 88c349dbc7Sjsg __i915_active_acquire(&ce->active); 89c349dbc7Sjsg 901bb76ff1Sjsg if (intel_context_is_barrier(ce) || intel_engine_uses_guc(ce->engine) || 911bb76ff1Sjsg intel_context_is_parallel(ce)) 92c349dbc7Sjsg return 0; 93c349dbc7Sjsg 94c349dbc7Sjsg /* Preallocate tracking nodes */ 95c349dbc7Sjsg err = i915_active_acquire_preallocate_barrier(&ce->active, 96c349dbc7Sjsg ce->engine); 97c349dbc7Sjsg if (err) 98c349dbc7Sjsg i915_active_release(&ce->active); 99c349dbc7Sjsg 100c349dbc7Sjsg return err; 101c349dbc7Sjsg } 102c349dbc7Sjsg 103c349dbc7Sjsg static void intel_context_active_release(struct intel_context *ce) 104c349dbc7Sjsg { 105c349dbc7Sjsg /* Nodes preallocated in intel_context_active() */ 106c349dbc7Sjsg i915_active_acquire_barrier(&ce->active); 107c349dbc7Sjsg i915_active_release(&ce->active); 108c349dbc7Sjsg } 109c349dbc7Sjsg 110ad8b1aafSjsg static int __context_pin_state(struct i915_vma *vma, struct i915_gem_ww_ctx *ww) 111c349dbc7Sjsg { 112c349dbc7Sjsg unsigned int bias = i915_ggtt_pin_bias(vma) | PIN_OFFSET_BIAS; 113c349dbc7Sjsg int err; 114c349dbc7Sjsg 115ad8b1aafSjsg err = i915_ggtt_pin(vma, ww, 0, bias | PIN_HIGH); 116c349dbc7Sjsg if (err) 117c349dbc7Sjsg return err; 118c349dbc7Sjsg 119c349dbc7Sjsg err = i915_active_acquire(&vma->active); 120c349dbc7Sjsg if (err) 121c349dbc7Sjsg goto err_unpin; 122c349dbc7Sjsg 123c349dbc7Sjsg /* 124c349dbc7Sjsg * And mark it as a globally pinned object to let the shrinker know 125c349dbc7Sjsg * it cannot reclaim the object until we release it. 126c349dbc7Sjsg */ 127c349dbc7Sjsg i915_vma_make_unshrinkable(vma); 128c349dbc7Sjsg vma->obj->mm.dirty = true; 129c349dbc7Sjsg 130c349dbc7Sjsg return 0; 131c349dbc7Sjsg 132c349dbc7Sjsg err_unpin: 133c349dbc7Sjsg i915_vma_unpin(vma); 134c349dbc7Sjsg return err; 135c349dbc7Sjsg } 136c349dbc7Sjsg 137c349dbc7Sjsg static void __context_unpin_state(struct i915_vma *vma) 138c349dbc7Sjsg { 139c349dbc7Sjsg i915_vma_make_shrinkable(vma); 140c349dbc7Sjsg i915_active_release(&vma->active); 141c349dbc7Sjsg __i915_vma_unpin(vma); 142c349dbc7Sjsg } 143c349dbc7Sjsg 144ad8b1aafSjsg static int __ring_active(struct intel_ring *ring, 145ad8b1aafSjsg struct i915_gem_ww_ctx *ww) 146c349dbc7Sjsg { 147c349dbc7Sjsg int err; 148c349dbc7Sjsg 149ad8b1aafSjsg err = intel_ring_pin(ring, ww); 150c349dbc7Sjsg if (err) 151c349dbc7Sjsg return err; 152c349dbc7Sjsg 15315914761Sjsg err = i915_active_acquire(&ring->vma->active); 154c349dbc7Sjsg if (err) 15515914761Sjsg goto err_pin; 156c349dbc7Sjsg 157c349dbc7Sjsg return 0; 158c349dbc7Sjsg 15915914761Sjsg err_pin: 16015914761Sjsg intel_ring_unpin(ring); 161c349dbc7Sjsg return err; 162c349dbc7Sjsg } 163c349dbc7Sjsg 164c349dbc7Sjsg static void __ring_retire(struct intel_ring *ring) 165c349dbc7Sjsg { 166c349dbc7Sjsg i915_active_release(&ring->vma->active); 16715914761Sjsg intel_ring_unpin(ring); 168c349dbc7Sjsg } 169c349dbc7Sjsg 170ad8b1aafSjsg static int intel_context_pre_pin(struct intel_context *ce, 171ad8b1aafSjsg struct i915_gem_ww_ctx *ww) 172ad8b1aafSjsg { 173ad8b1aafSjsg int err; 174ad8b1aafSjsg 175ad8b1aafSjsg CE_TRACE(ce, "active\n"); 176ad8b1aafSjsg 177ad8b1aafSjsg err = __ring_active(ce->ring, ww); 178ad8b1aafSjsg if (err) 179ad8b1aafSjsg return err; 180ad8b1aafSjsg 181ad8b1aafSjsg err = intel_timeline_pin(ce->timeline, ww); 182ad8b1aafSjsg if (err) 183ad8b1aafSjsg goto err_ring; 184ad8b1aafSjsg 185ad8b1aafSjsg if (!ce->state) 186ad8b1aafSjsg return 0; 187ad8b1aafSjsg 188ad8b1aafSjsg err = __context_pin_state(ce->state, ww); 189ad8b1aafSjsg if (err) 190ad8b1aafSjsg goto err_timeline; 191ad8b1aafSjsg 192ad8b1aafSjsg 193ad8b1aafSjsg return 0; 194ad8b1aafSjsg 195ad8b1aafSjsg err_timeline: 196ad8b1aafSjsg intel_timeline_unpin(ce->timeline); 197ad8b1aafSjsg err_ring: 198ad8b1aafSjsg __ring_retire(ce->ring); 199ad8b1aafSjsg return err; 200ad8b1aafSjsg } 201ad8b1aafSjsg 202ad8b1aafSjsg static void intel_context_post_unpin(struct intel_context *ce) 203ad8b1aafSjsg { 204ad8b1aafSjsg if (ce->state) 205ad8b1aafSjsg __context_unpin_state(ce->state); 206ad8b1aafSjsg 207ad8b1aafSjsg intel_timeline_unpin(ce->timeline); 208ad8b1aafSjsg __ring_retire(ce->ring); 209ad8b1aafSjsg } 210ad8b1aafSjsg 211ad8b1aafSjsg int __intel_context_do_pin_ww(struct intel_context *ce, 212ad8b1aafSjsg struct i915_gem_ww_ctx *ww) 213ad8b1aafSjsg { 214ad8b1aafSjsg bool handoff = false; 215ad8b1aafSjsg void *vaddr; 216ad8b1aafSjsg int err = 0; 217ad8b1aafSjsg 218ad8b1aafSjsg if (unlikely(!test_bit(CONTEXT_ALLOC_BIT, &ce->flags))) { 219ad8b1aafSjsg err = intel_context_alloc_state(ce); 220ad8b1aafSjsg if (err) 221ad8b1aafSjsg return err; 222ad8b1aafSjsg } 223ad8b1aafSjsg 224ad8b1aafSjsg /* 225ad8b1aafSjsg * We always pin the context/ring/timeline here, to ensure a pin 226ad8b1aafSjsg * refcount for __intel_context_active(), which prevent a lock 227ad8b1aafSjsg * inversion of ce->pin_mutex vs dma_resv_lock(). 228ad8b1aafSjsg */ 229ad8b1aafSjsg 230ad8b1aafSjsg err = i915_gem_object_lock(ce->timeline->hwsp_ggtt->obj, ww); 2311bb76ff1Sjsg if (!err) 232ad8b1aafSjsg err = i915_gem_object_lock(ce->ring->vma->obj, ww); 233ad8b1aafSjsg if (!err && ce->state) 234ad8b1aafSjsg err = i915_gem_object_lock(ce->state->obj, ww); 235ad8b1aafSjsg if (!err) 236ad8b1aafSjsg err = intel_context_pre_pin(ce, ww); 237ad8b1aafSjsg if (err) 238ad8b1aafSjsg return err; 239ad8b1aafSjsg 2401bb76ff1Sjsg err = ce->ops->pre_pin(ce, ww, &vaddr); 241ad8b1aafSjsg if (err) 242ad8b1aafSjsg goto err_ctx_unpin; 243ad8b1aafSjsg 2441bb76ff1Sjsg err = i915_active_acquire(&ce->active); 245ad8b1aafSjsg if (err) 2461bb76ff1Sjsg goto err_post_unpin; 247ad8b1aafSjsg 248ad8b1aafSjsg err = mutex_lock_interruptible(&ce->pin_mutex); 249ad8b1aafSjsg if (err) 2501bb76ff1Sjsg goto err_release; 2511bb76ff1Sjsg 2521bb76ff1Sjsg intel_engine_pm_might_get(ce->engine); 253ad8b1aafSjsg 254ad8b1aafSjsg if (unlikely(intel_context_is_closed(ce))) { 255ad8b1aafSjsg err = -ENOENT; 256ad8b1aafSjsg goto err_unlock; 257ad8b1aafSjsg } 258ad8b1aafSjsg 259ad8b1aafSjsg if (likely(!atomic_add_unless(&ce->pin_count, 1, 0))) { 260ad8b1aafSjsg err = intel_context_active_acquire(ce); 261ad8b1aafSjsg if (unlikely(err)) 262ad8b1aafSjsg goto err_unlock; 263ad8b1aafSjsg 264ad8b1aafSjsg err = ce->ops->pin(ce, vaddr); 265ad8b1aafSjsg if (err) { 266ad8b1aafSjsg intel_context_active_release(ce); 267ad8b1aafSjsg goto err_unlock; 268ad8b1aafSjsg } 269ad8b1aafSjsg 270ad8b1aafSjsg CE_TRACE(ce, "pin ring:{start:%08x, head:%04x, tail:%04x}\n", 271ad8b1aafSjsg i915_ggtt_offset(ce->ring->vma), 272ad8b1aafSjsg ce->ring->head, ce->ring->tail); 273ad8b1aafSjsg 274ad8b1aafSjsg handoff = true; 275ad8b1aafSjsg smp_mb__before_atomic(); /* flush pin before it is visible */ 276ad8b1aafSjsg atomic_inc(&ce->pin_count); 277ad8b1aafSjsg } 278ad8b1aafSjsg 279ad8b1aafSjsg GEM_BUG_ON(!intel_context_is_pinned(ce)); /* no overflow! */ 280ad8b1aafSjsg 2815ca02815Sjsg trace_intel_context_do_pin(ce); 2825ca02815Sjsg 283ad8b1aafSjsg err_unlock: 284ad8b1aafSjsg mutex_unlock(&ce->pin_mutex); 2851bb76ff1Sjsg err_release: 2861bb76ff1Sjsg i915_active_release(&ce->active); 287ad8b1aafSjsg err_post_unpin: 288ad8b1aafSjsg if (!handoff) 289ad8b1aafSjsg ce->ops->post_unpin(ce); 290ad8b1aafSjsg err_ctx_unpin: 291ad8b1aafSjsg intel_context_post_unpin(ce); 292ad8b1aafSjsg 293ad8b1aafSjsg /* 294ad8b1aafSjsg * Unlock the hwsp_ggtt object since it's shared. 295ad8b1aafSjsg * In principle we can unlock all the global state locked above 296ad8b1aafSjsg * since it's pinned and doesn't need fencing, and will 297ad8b1aafSjsg * thus remain resident until it is explicitly unpinned. 298ad8b1aafSjsg */ 299ad8b1aafSjsg i915_gem_ww_unlock_single(ce->timeline->hwsp_ggtt->obj); 300ad8b1aafSjsg 301ad8b1aafSjsg return err; 302ad8b1aafSjsg } 303ad8b1aafSjsg 304ad8b1aafSjsg int __intel_context_do_pin(struct intel_context *ce) 305ad8b1aafSjsg { 306ad8b1aafSjsg struct i915_gem_ww_ctx ww; 307ad8b1aafSjsg int err; 308ad8b1aafSjsg 309ad8b1aafSjsg i915_gem_ww_ctx_init(&ww, true); 310ad8b1aafSjsg retry: 311ad8b1aafSjsg err = __intel_context_do_pin_ww(ce, &ww); 312ad8b1aafSjsg if (err == -EDEADLK) { 313ad8b1aafSjsg err = i915_gem_ww_ctx_backoff(&ww); 314ad8b1aafSjsg if (!err) 315ad8b1aafSjsg goto retry; 316ad8b1aafSjsg } 317ad8b1aafSjsg i915_gem_ww_ctx_fini(&ww); 318ad8b1aafSjsg return err; 319ad8b1aafSjsg } 320ad8b1aafSjsg 3215ca02815Sjsg void __intel_context_do_unpin(struct intel_context *ce, int sub) 322ad8b1aafSjsg { 3235ca02815Sjsg if (!atomic_sub_and_test(sub, &ce->pin_count)) 324ad8b1aafSjsg return; 325ad8b1aafSjsg 326ad8b1aafSjsg CE_TRACE(ce, "unpin\n"); 327ad8b1aafSjsg ce->ops->unpin(ce); 328ad8b1aafSjsg ce->ops->post_unpin(ce); 329ad8b1aafSjsg 330ad8b1aafSjsg /* 331ad8b1aafSjsg * Once released, we may asynchronously drop the active reference. 332ad8b1aafSjsg * As that may be the only reference keeping the context alive, 333ad8b1aafSjsg * take an extra now so that it is not freed before we finish 334ad8b1aafSjsg * dereferencing it. 335ad8b1aafSjsg */ 336ad8b1aafSjsg intel_context_get(ce); 337ad8b1aafSjsg intel_context_active_release(ce); 3385ca02815Sjsg trace_intel_context_do_unpin(ce); 339ad8b1aafSjsg intel_context_put(ce); 340ad8b1aafSjsg } 341ad8b1aafSjsg 342c349dbc7Sjsg static void __intel_context_retire(struct i915_active *active) 343c349dbc7Sjsg { 344c349dbc7Sjsg struct intel_context *ce = container_of(active, typeof(*ce), active); 345c349dbc7Sjsg 346c349dbc7Sjsg CE_TRACE(ce, "retire runtime: { total:%lluns, avg:%lluns }\n", 347c349dbc7Sjsg intel_context_get_total_runtime_ns(ce), 348c349dbc7Sjsg intel_context_get_avg_runtime_ns(ce)); 349c349dbc7Sjsg 350c349dbc7Sjsg set_bit(CONTEXT_VALID_BIT, &ce->flags); 351ad8b1aafSjsg intel_context_post_unpin(ce); 352c349dbc7Sjsg intel_context_put(ce); 353c349dbc7Sjsg } 354c349dbc7Sjsg 355c349dbc7Sjsg static int __intel_context_active(struct i915_active *active) 356c349dbc7Sjsg { 357c349dbc7Sjsg struct intel_context *ce = container_of(active, typeof(*ce), active); 358c349dbc7Sjsg 359c349dbc7Sjsg intel_context_get(ce); 360c349dbc7Sjsg 361ad8b1aafSjsg /* everything should already be activated by intel_context_pre_pin() */ 362ad8b1aafSjsg GEM_WARN_ON(!i915_active_acquire_if_busy(&ce->ring->vma->active)); 363ad8b1aafSjsg __intel_ring_pin(ce->ring); 364c349dbc7Sjsg 365ad8b1aafSjsg __intel_timeline_pin(ce->timeline); 366c349dbc7Sjsg 367ad8b1aafSjsg if (ce->state) { 368ad8b1aafSjsg GEM_WARN_ON(!i915_active_acquire_if_busy(&ce->state->active)); 369ad8b1aafSjsg __i915_vma_pin(ce->state); 370ad8b1aafSjsg i915_vma_make_unshrinkable(ce->state); 371ad8b1aafSjsg } 372c349dbc7Sjsg 373c349dbc7Sjsg return 0; 374c349dbc7Sjsg } 375c349dbc7Sjsg 3761bb76ff1Sjsg static int 3775ca02815Sjsg sw_fence_dummy_notify(struct i915_sw_fence *sf, 3785ca02815Sjsg enum i915_sw_fence_notify state) 3795ca02815Sjsg { 3805ca02815Sjsg return NOTIFY_DONE; 3815ca02815Sjsg } 3825ca02815Sjsg 383c349dbc7Sjsg void 384ad8b1aafSjsg intel_context_init(struct intel_context *ce, struct intel_engine_cs *engine) 385c349dbc7Sjsg { 386c349dbc7Sjsg GEM_BUG_ON(!engine->cops); 387c349dbc7Sjsg GEM_BUG_ON(!engine->gt->vm); 388c349dbc7Sjsg 389c349dbc7Sjsg kref_init(&ce->ref); 390c349dbc7Sjsg 391c349dbc7Sjsg ce->engine = engine; 392c349dbc7Sjsg ce->ops = engine->cops; 393c349dbc7Sjsg ce->sseu = engine->sseu; 3945ca02815Sjsg ce->ring = NULL; 3955ca02815Sjsg ce->ring_size = SZ_4K; 396c349dbc7Sjsg 3971bb76ff1Sjsg ewma_runtime_init(&ce->stats.runtime.avg); 398c349dbc7Sjsg 399c349dbc7Sjsg ce->vm = i915_vm_get(engine->gt->vm); 400c349dbc7Sjsg 401ad8b1aafSjsg /* NB ce->signal_link/lock is used under RCU */ 402ad8b1aafSjsg mtx_init(&ce->signal_lock, IPL_NONE); 403c349dbc7Sjsg INIT_LIST_HEAD(&ce->signals); 404c349dbc7Sjsg 405c349dbc7Sjsg rw_init(&ce->pin_mutex, "cepin"); 406c349dbc7Sjsg 407*a35b0b99Sjsg mtx_init(&ce->guc_state.lock, IPL_TTY); 4085ca02815Sjsg INIT_LIST_HEAD(&ce->guc_state.fences); 4091bb76ff1Sjsg INIT_LIST_HEAD(&ce->guc_state.requests); 4105ca02815Sjsg 4111bb76ff1Sjsg ce->guc_id.id = GUC_INVALID_CONTEXT_ID; 4121bb76ff1Sjsg INIT_LIST_HEAD(&ce->guc_id.link); 4135ca02815Sjsg 4141bb76ff1Sjsg INIT_LIST_HEAD(&ce->destroyed_link); 4151bb76ff1Sjsg 4161bb76ff1Sjsg INIT_LIST_HEAD(&ce->parallel.child_list); 4175ca02815Sjsg 4185ca02815Sjsg /* 4195ca02815Sjsg * Initialize fence to be complete as this is expected to be complete 4205ca02815Sjsg * unless there is a pending schedule disable outstanding. 4215ca02815Sjsg */ 4221bb76ff1Sjsg i915_sw_fence_init(&ce->guc_state.blocked, 4231bb76ff1Sjsg sw_fence_dummy_notify); 4241bb76ff1Sjsg i915_sw_fence_commit(&ce->guc_state.blocked); 4255ca02815Sjsg 426c349dbc7Sjsg i915_active_init(&ce->active, 4275ca02815Sjsg __intel_context_active, __intel_context_retire, 0); 428c349dbc7Sjsg } 429c349dbc7Sjsg 430c349dbc7Sjsg void intel_context_fini(struct intel_context *ce) 431c349dbc7Sjsg { 4321bb76ff1Sjsg struct intel_context *child, *next; 4331bb76ff1Sjsg 434c349dbc7Sjsg if (ce->timeline) 435c349dbc7Sjsg intel_timeline_put(ce->timeline); 436c349dbc7Sjsg i915_vm_put(ce->vm); 437c349dbc7Sjsg 4381bb76ff1Sjsg /* Need to put the creation ref for the children */ 4391bb76ff1Sjsg if (intel_context_is_parent(ce)) 4401bb76ff1Sjsg for_each_child_safe(ce, child, next) 4411bb76ff1Sjsg intel_context_put(child); 4421bb76ff1Sjsg 443c349dbc7Sjsg mutex_destroy(&ce->pin_mutex); 444c349dbc7Sjsg i915_active_fini(&ce->active); 4451bb76ff1Sjsg i915_sw_fence_fini(&ce->guc_state.blocked); 446c349dbc7Sjsg } 447c349dbc7Sjsg 4485ca02815Sjsg void i915_context_module_exit(void) 449c349dbc7Sjsg { 450c349dbc7Sjsg #ifdef __linux__ 4515ca02815Sjsg kmem_cache_destroy(slab_ce); 452c349dbc7Sjsg #else 4535ca02815Sjsg pool_destroy(&slab_ce); 454c349dbc7Sjsg #endif 455c349dbc7Sjsg } 456c349dbc7Sjsg 4575ca02815Sjsg int __init i915_context_module_init(void) 458c349dbc7Sjsg { 459c349dbc7Sjsg #ifdef __linux__ 4605ca02815Sjsg slab_ce = KMEM_CACHE(intel_context, SLAB_HWCACHE_ALIGN); 4615ca02815Sjsg if (!slab_ce) 462c349dbc7Sjsg return -ENOMEM; 463c349dbc7Sjsg #else 4645ca02815Sjsg pool_init(&slab_ce, sizeof(struct intel_context), 4650f557061Sjsg CACHELINESIZE, IPL_TTY, 0, "ictx", NULL); 466c349dbc7Sjsg #endif 467c349dbc7Sjsg 468c349dbc7Sjsg return 0; 469c349dbc7Sjsg } 470c349dbc7Sjsg 471c349dbc7Sjsg void intel_context_enter_engine(struct intel_context *ce) 472c349dbc7Sjsg { 473c349dbc7Sjsg intel_engine_pm_get(ce->engine); 474c349dbc7Sjsg intel_timeline_enter(ce->timeline); 475c349dbc7Sjsg } 476c349dbc7Sjsg 477c349dbc7Sjsg void intel_context_exit_engine(struct intel_context *ce) 478c349dbc7Sjsg { 479c349dbc7Sjsg intel_timeline_exit(ce->timeline); 480c349dbc7Sjsg intel_engine_pm_put(ce->engine); 481c349dbc7Sjsg } 482c349dbc7Sjsg 483c349dbc7Sjsg int intel_context_prepare_remote_request(struct intel_context *ce, 484c349dbc7Sjsg struct i915_request *rq) 485c349dbc7Sjsg { 486c349dbc7Sjsg struct intel_timeline *tl = ce->timeline; 487c349dbc7Sjsg int err; 488c349dbc7Sjsg 489c349dbc7Sjsg /* Only suitable for use in remotely modifying this context */ 490c349dbc7Sjsg GEM_BUG_ON(rq->context == ce); 491c349dbc7Sjsg 492c349dbc7Sjsg if (rcu_access_pointer(rq->timeline) != tl) { /* timeline sharing! */ 493c349dbc7Sjsg /* Queue this switch after current activity by this context. */ 494c349dbc7Sjsg err = i915_active_fence_set(&tl->last_request, rq); 495c349dbc7Sjsg if (err) 496c349dbc7Sjsg return err; 497c349dbc7Sjsg } 498c349dbc7Sjsg 499c349dbc7Sjsg /* 500c349dbc7Sjsg * Guarantee context image and the timeline remains pinned until the 501c349dbc7Sjsg * modifying request is retired by setting the ce activity tracker. 502c349dbc7Sjsg * 503c349dbc7Sjsg * But we only need to take one pin on the account of it. Or in other 504c349dbc7Sjsg * words transfer the pinned ce object to tracked active request. 505c349dbc7Sjsg */ 506c349dbc7Sjsg GEM_BUG_ON(i915_active_is_idle(&ce->active)); 507c349dbc7Sjsg return i915_active_add_request(&ce->active, rq); 508c349dbc7Sjsg } 509c349dbc7Sjsg 510c349dbc7Sjsg struct i915_request *intel_context_create_request(struct intel_context *ce) 511c349dbc7Sjsg { 512ad8b1aafSjsg struct i915_gem_ww_ctx ww; 513c349dbc7Sjsg struct i915_request *rq; 514c349dbc7Sjsg int err; 515c349dbc7Sjsg 516ad8b1aafSjsg i915_gem_ww_ctx_init(&ww, true); 517ad8b1aafSjsg retry: 518ad8b1aafSjsg err = intel_context_pin_ww(ce, &ww); 519ad8b1aafSjsg if (!err) { 520c349dbc7Sjsg rq = i915_request_create(ce); 521c349dbc7Sjsg intel_context_unpin(ce); 522ad8b1aafSjsg } else if (err == -EDEADLK) { 523ad8b1aafSjsg err = i915_gem_ww_ctx_backoff(&ww); 524ad8b1aafSjsg if (!err) 525ad8b1aafSjsg goto retry; 526ad8b1aafSjsg rq = ERR_PTR(err); 527ad8b1aafSjsg } else { 528ad8b1aafSjsg rq = ERR_PTR(err); 529ad8b1aafSjsg } 530ad8b1aafSjsg 531ad8b1aafSjsg i915_gem_ww_ctx_fini(&ww); 532ad8b1aafSjsg 533ad8b1aafSjsg if (IS_ERR(rq)) 534ad8b1aafSjsg return rq; 535ad8b1aafSjsg 536ad8b1aafSjsg /* 537ad8b1aafSjsg * timeline->mutex should be the inner lock, but is used as outer lock. 538ad8b1aafSjsg * Hack around this to shut up lockdep in selftests.. 539ad8b1aafSjsg */ 540ad8b1aafSjsg lockdep_unpin_lock(&ce->timeline->mutex, rq->cookie); 541ad8b1aafSjsg mutex_release(&ce->timeline->mutex.dep_map, _RET_IP_); 542ad8b1aafSjsg mutex_acquire(&ce->timeline->mutex.dep_map, SINGLE_DEPTH_NESTING, 0, _RET_IP_); 543ad8b1aafSjsg rq->cookie = lockdep_pin_lock(&ce->timeline->mutex); 544c349dbc7Sjsg 545c349dbc7Sjsg return rq; 546c349dbc7Sjsg } 547c349dbc7Sjsg 5487c23aa04Sjsg struct i915_request *intel_context_get_active_request(struct intel_context *ce) 5495ca02815Sjsg { 5501bb76ff1Sjsg struct intel_context *parent = intel_context_to_parent(ce); 5515ca02815Sjsg struct i915_request *rq, *active = NULL; 5525ca02815Sjsg unsigned long flags; 5535ca02815Sjsg 5545ca02815Sjsg GEM_BUG_ON(!intel_engine_uses_guc(ce->engine)); 5555ca02815Sjsg 5561bb76ff1Sjsg /* 5571bb76ff1Sjsg * We search the parent list to find an active request on the submitted 5581bb76ff1Sjsg * context. The parent list contains the requests for all the contexts 5591bb76ff1Sjsg * in the relationship so we have to do a compare of each request's 5601bb76ff1Sjsg * context. 5611bb76ff1Sjsg */ 5621bb76ff1Sjsg spin_lock_irqsave(&parent->guc_state.lock, flags); 5631bb76ff1Sjsg list_for_each_entry_reverse(rq, &parent->guc_state.requests, 5645ca02815Sjsg sched.link) { 5651bb76ff1Sjsg if (rq->context != ce) 5661bb76ff1Sjsg continue; 5675ca02815Sjsg if (i915_request_completed(rq)) 5685ca02815Sjsg break; 5695ca02815Sjsg 5705ca02815Sjsg active = rq; 5715ca02815Sjsg } 5727c23aa04Sjsg if (active) 5737c23aa04Sjsg active = i915_request_get_rcu(active); 5741bb76ff1Sjsg spin_unlock_irqrestore(&parent->guc_state.lock, flags); 5755ca02815Sjsg 5765ca02815Sjsg return active; 5775ca02815Sjsg } 5785ca02815Sjsg 5791bb76ff1Sjsg void intel_context_bind_parent_child(struct intel_context *parent, 5801bb76ff1Sjsg struct intel_context *child) 5811bb76ff1Sjsg { 5821bb76ff1Sjsg /* 5831bb76ff1Sjsg * Callers responsibility to validate that this function is used 5841bb76ff1Sjsg * correctly but we use GEM_BUG_ON here ensure that they do. 5851bb76ff1Sjsg */ 5861bb76ff1Sjsg GEM_BUG_ON(intel_context_is_pinned(parent)); 5871bb76ff1Sjsg GEM_BUG_ON(intel_context_is_child(parent)); 5881bb76ff1Sjsg GEM_BUG_ON(intel_context_is_pinned(child)); 5891bb76ff1Sjsg GEM_BUG_ON(intel_context_is_child(child)); 5901bb76ff1Sjsg GEM_BUG_ON(intel_context_is_parent(child)); 5911bb76ff1Sjsg 5921bb76ff1Sjsg parent->parallel.child_index = parent->parallel.number_children++; 5931bb76ff1Sjsg list_add_tail(&child->parallel.child_link, 5941bb76ff1Sjsg &parent->parallel.child_list); 5951bb76ff1Sjsg child->parallel.parent = parent; 5961bb76ff1Sjsg } 5971bb76ff1Sjsg 598f005ef32Sjsg u64 intel_context_get_total_runtime_ns(struct intel_context *ce) 5991bb76ff1Sjsg { 6001bb76ff1Sjsg u64 total, active; 6011bb76ff1Sjsg 602f005ef32Sjsg if (ce->ops->update_stats) 603f005ef32Sjsg ce->ops->update_stats(ce); 604f005ef32Sjsg 6051bb76ff1Sjsg total = ce->stats.runtime.total; 6061bb76ff1Sjsg if (ce->ops->flags & COPS_RUNTIME_CYCLES) 6071bb76ff1Sjsg total *= ce->engine->gt->clock_period_ns; 6081bb76ff1Sjsg 6091bb76ff1Sjsg active = READ_ONCE(ce->stats.active); 6101bb76ff1Sjsg if (active) 6111bb76ff1Sjsg active = intel_context_clock() - active; 6121bb76ff1Sjsg 6131bb76ff1Sjsg return total + active; 6141bb76ff1Sjsg } 6151bb76ff1Sjsg 6161bb76ff1Sjsg u64 intel_context_get_avg_runtime_ns(struct intel_context *ce) 6171bb76ff1Sjsg { 6181bb76ff1Sjsg u64 avg = ewma_runtime_read(&ce->stats.runtime.avg); 6191bb76ff1Sjsg 6201bb76ff1Sjsg if (ce->ops->flags & COPS_RUNTIME_CYCLES) 6211bb76ff1Sjsg avg *= ce->engine->gt->clock_period_ns; 6221bb76ff1Sjsg 6231bb76ff1Sjsg return avg; 6241bb76ff1Sjsg } 6251bb76ff1Sjsg 6261bb76ff1Sjsg bool intel_context_ban(struct intel_context *ce, struct i915_request *rq) 6271bb76ff1Sjsg { 6281bb76ff1Sjsg bool ret = intel_context_set_banned(ce); 6291bb76ff1Sjsg 6301bb76ff1Sjsg trace_intel_context_ban(ce); 6311bb76ff1Sjsg 6321bb76ff1Sjsg if (ce->ops->revoke) 6331bb76ff1Sjsg ce->ops->revoke(ce, rq, 6341bb76ff1Sjsg INTEL_CONTEXT_BANNED_PREEMPT_TIMEOUT_MS); 6351bb76ff1Sjsg 6361bb76ff1Sjsg return ret; 6371bb76ff1Sjsg } 6381bb76ff1Sjsg 6391bb76ff1Sjsg bool intel_context_revoke(struct intel_context *ce) 6401bb76ff1Sjsg { 6411bb76ff1Sjsg bool ret = intel_context_set_exiting(ce); 6421bb76ff1Sjsg 6431bb76ff1Sjsg if (ce->ops->revoke) 6441bb76ff1Sjsg ce->ops->revoke(ce, NULL, ce->engine->props.preempt_timeout_ms); 6451bb76ff1Sjsg 6461bb76ff1Sjsg return ret; 6471bb76ff1Sjsg } 6481bb76ff1Sjsg 649c349dbc7Sjsg #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) 650c349dbc7Sjsg #include "selftest_context.c" 651c349dbc7Sjsg #endif 652