aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChangbin Du <changbin.du@intel.com>2017-03-21 10:47:20 -0400
committerJani Nikula <jani.nikula@intel.com>2017-03-21 10:51:47 -0400
commit590379aef2e3fb7d00a093ed556c0a2714f86916 (patch)
tree821ba9d7b121ba58a880bfd4a66e057b3ffc59df
parent3d3d18f086cdda72ee18a454db70ca72c6e3246c (diff)
drm/i915: make context status notifier head be per engine
GVTg has introduced the context status notifier to schedule the GVTg workload. At that time, the notifier is bound to GVTg context only, so GVTg is not aware of host workloads. Now we are going to improve GVTg's guest workload scheduler policy, and add Guc emulation support for new Gen graphics. Both these two features require acknowledgment for all contexts running on hardware. (But will not alter host workload.) So here try to make some change. The change is simple: 1. Move the context status notifier head from i915_gem_context to intel_engine_cs. Which means there is a notifier head per engine instead of per context. Execlist driver still call notifier for each context sched-in/out events of current engine. 2. At GVTg side, it binds a notifier_block for each physical engine at GVTg initialization period. Then GVTg can hear all context status events. In this patch, GVTg do nothing for host context event, but later will add a function there. But in any case, the notifier callback is a noop if this is no active vGPU. Since intel_gvt_init() is called at early initialization stage and require the status notifier head has been initiated, I initiate it in intel_engine_setup(). v2: remove a redundant newline. (chris) Fixes: 3c7ba6359d70 ("drm/i915: Introduce execlist context status change notification") Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=100232 Signed-off-by: Changbin Du <changbin.du@intel.com> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com> Cc: Zhi Wang <zhi.a.wang@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/20170313024711.28591-1-changbin.du@intel.com Acked-by: Zhenyu Wang <zhenyuw@linux.intel.com> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> (cherry picked from commit 3fc03069bc6e6c316f19bb526e3c8ce784677477) Signed-off-by: Jani Nikula <jani.nikula@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170321144720.17020-1-chris@chris-wilson.co.uk
-rw-r--r--drivers/gpu/drm/i915/gvt/gvt.h2
-rw-r--r--drivers/gpu/drm/i915/gvt/scheduler.c45
-rw-r--r--drivers/gpu/drm/i915/i915_gem_context.c1
-rw-r--r--drivers/gpu/drm/i915/i915_gem_context.h3
-rw-r--r--drivers/gpu/drm/i915/intel_engine_cs.c2
-rw-r--r--drivers/gpu/drm/i915/intel_lrc.c3
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.h3
7 files changed, 27 insertions, 32 deletions
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index 23791920ced1..6dfc48b63b71 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -162,7 +162,6 @@ struct intel_vgpu {
162 atomic_t running_workload_num; 162 atomic_t running_workload_num;
163 DECLARE_BITMAP(tlb_handle_pending, I915_NUM_ENGINES); 163 DECLARE_BITMAP(tlb_handle_pending, I915_NUM_ENGINES);
164 struct i915_gem_context *shadow_ctx; 164 struct i915_gem_context *shadow_ctx;
165 struct notifier_block shadow_ctx_notifier_block;
166 165
167#if IS_ENABLED(CONFIG_DRM_I915_GVT_KVMGT) 166#if IS_ENABLED(CONFIG_DRM_I915_GVT_KVMGT)
168 struct { 167 struct {
@@ -233,6 +232,7 @@ struct intel_gvt {
233 struct intel_gvt_gtt gtt; 232 struct intel_gvt_gtt gtt;
234 struct intel_gvt_opregion opregion; 233 struct intel_gvt_opregion opregion;
235 struct intel_gvt_workload_scheduler scheduler; 234 struct intel_gvt_workload_scheduler scheduler;
235 struct notifier_block shadow_ctx_notifier_block[I915_NUM_ENGINES];
236 DECLARE_HASHTABLE(cmd_table, GVT_CMD_HASH_BITS); 236 DECLARE_HASHTABLE(cmd_table, GVT_CMD_HASH_BITS);
237 struct intel_vgpu_type *types; 237 struct intel_vgpu_type *types;
238 unsigned int num_types; 238 unsigned int num_types;
diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c
index 39a83eb7aecc..c4353ed86d4b 100644
--- a/drivers/gpu/drm/i915/gvt/scheduler.c
+++ b/drivers/gpu/drm/i915/gvt/scheduler.c
@@ -130,12 +130,10 @@ static int populate_shadow_context(struct intel_vgpu_workload *workload)
130static int shadow_context_status_change(struct notifier_block *nb, 130static int shadow_context_status_change(struct notifier_block *nb,
131 unsigned long action, void *data) 131 unsigned long action, void *data)
132{ 132{
133 struct intel_vgpu *vgpu = container_of(nb, 133 struct drm_i915_gem_request *req = (struct drm_i915_gem_request *)data;
134 struct intel_vgpu, shadow_ctx_notifier_block); 134 struct intel_gvt *gvt = container_of(nb, struct intel_gvt,
135 struct drm_i915_gem_request *req = 135 shadow_ctx_notifier_block[req->engine->id]);
136 (struct drm_i915_gem_request *)data; 136 struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler;
137 struct intel_gvt_workload_scheduler *scheduler =
138 &vgpu->gvt->scheduler;
139 struct intel_vgpu_workload *workload = 137 struct intel_vgpu_workload *workload =
140 scheduler->current_workload[req->engine->id]; 138 scheduler->current_workload[req->engine->id];
141 139
@@ -534,15 +532,16 @@ void intel_gvt_wait_vgpu_idle(struct intel_vgpu *vgpu)
534void intel_gvt_clean_workload_scheduler(struct intel_gvt *gvt) 532void intel_gvt_clean_workload_scheduler(struct intel_gvt *gvt)
535{ 533{
536 struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler; 534 struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler;
537 int i; 535 struct intel_engine_cs *engine;
536 enum intel_engine_id i;
538 537
539 gvt_dbg_core("clean workload scheduler\n"); 538 gvt_dbg_core("clean workload scheduler\n");
540 539
541 for (i = 0; i < I915_NUM_ENGINES; i++) { 540 for_each_engine(engine, gvt->dev_priv, i) {
542 if (scheduler->thread[i]) { 541 atomic_notifier_chain_unregister(
543 kthread_stop(scheduler->thread[i]); 542 &engine->context_status_notifier,
544 scheduler->thread[i] = NULL; 543 &gvt->shadow_ctx_notifier_block[i]);
545 } 544 kthread_stop(scheduler->thread[i]);
546 } 545 }
547} 546}
548 547
@@ -550,18 +549,15 @@ int intel_gvt_init_workload_scheduler(struct intel_gvt *gvt)
550{ 549{
551 struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler; 550 struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler;
552 struct workload_thread_param *param = NULL; 551 struct workload_thread_param *param = NULL;
552 struct intel_engine_cs *engine;
553 enum intel_engine_id i;
553 int ret; 554 int ret;
554 int i;
555 555
556 gvt_dbg_core("init workload scheduler\n"); 556 gvt_dbg_core("init workload scheduler\n");
557 557
558 init_waitqueue_head(&scheduler->workload_complete_wq); 558 init_waitqueue_head(&scheduler->workload_complete_wq);
559 559
560 for (i = 0; i < I915_NUM_ENGINES; i++) { 560 for_each_engine(engine, gvt->dev_priv, i) {
561 /* check ring mask at init time */
562 if (!HAS_ENGINE(gvt->dev_priv, i))
563 continue;
564
565 init_waitqueue_head(&scheduler->waitq[i]); 561 init_waitqueue_head(&scheduler->waitq[i]);
566 562
567 param = kzalloc(sizeof(*param), GFP_KERNEL); 563 param = kzalloc(sizeof(*param), GFP_KERNEL);
@@ -580,6 +576,11 @@ int intel_gvt_init_workload_scheduler(struct intel_gvt *gvt)
580 ret = PTR_ERR(scheduler->thread[i]); 576 ret = PTR_ERR(scheduler->thread[i]);
581 goto err; 577 goto err;
582 } 578 }
579
580 gvt->shadow_ctx_notifier_block[i].notifier_call =
581 shadow_context_status_change;
582 atomic_notifier_chain_register(&engine->context_status_notifier,
583 &gvt->shadow_ctx_notifier_block[i]);
583 } 584 }
584 return 0; 585 return 0;
585err: 586err:
@@ -591,9 +592,6 @@ err:
591 592
592void intel_vgpu_clean_gvt_context(struct intel_vgpu *vgpu) 593void intel_vgpu_clean_gvt_context(struct intel_vgpu *vgpu)
593{ 594{
594 atomic_notifier_chain_unregister(&vgpu->shadow_ctx->status_notifier,
595 &vgpu->shadow_ctx_notifier_block);
596
597 i915_gem_context_put_unlocked(vgpu->shadow_ctx); 595 i915_gem_context_put_unlocked(vgpu->shadow_ctx);
598} 596}
599 597
@@ -608,10 +606,5 @@ int intel_vgpu_init_gvt_context(struct intel_vgpu *vgpu)
608 606
609 vgpu->shadow_ctx->engine[RCS].initialised = true; 607 vgpu->shadow_ctx->engine[RCS].initialised = true;
610 608
611 vgpu->shadow_ctx_notifier_block.notifier_call =
612 shadow_context_status_change;
613
614 atomic_notifier_chain_register(&vgpu->shadow_ctx->status_notifier,
615 &vgpu->shadow_ctx_notifier_block);
616 return 0; 609 return 0;
617} 610}
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 17f90c618208..e2d83b6d376b 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -311,7 +311,6 @@ __create_hw_context(struct drm_i915_private *dev_priv,
311 ctx->ring_size = 4 * PAGE_SIZE; 311 ctx->ring_size = 4 * PAGE_SIZE;
312 ctx->desc_template = GEN8_CTX_ADDRESSING_MODE(dev_priv) << 312 ctx->desc_template = GEN8_CTX_ADDRESSING_MODE(dev_priv) <<
313 GEN8_CTX_ADDRESSING_MODE_SHIFT; 313 GEN8_CTX_ADDRESSING_MODE_SHIFT;
314 ATOMIC_INIT_NOTIFIER_HEAD(&ctx->status_notifier);
315 314
316 /* GuC requires the ring to be placed above GUC_WOPCM_TOP. If GuC is not 315 /* GuC requires the ring to be placed above GUC_WOPCM_TOP. If GuC is not
317 * present or not in use we still need a small bias as ring wraparound 316 * present or not in use we still need a small bias as ring wraparound
diff --git a/drivers/gpu/drm/i915/i915_gem_context.h b/drivers/gpu/drm/i915/i915_gem_context.h
index 0ac750b90f3d..e9c008fe14b1 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.h
+++ b/drivers/gpu/drm/i915/i915_gem_context.h
@@ -160,9 +160,6 @@ struct i915_gem_context {
160 /** desc_template: invariant fields for the HW context descriptor */ 160 /** desc_template: invariant fields for the HW context descriptor */
161 u32 desc_template; 161 u32 desc_template;
162 162
163 /** status_notifier: list of callbacks for context-switch changes */
164 struct atomic_notifier_head status_notifier;
165
166 /** guilty_count: How many times this context has caused a GPU hang. */ 163 /** guilty_count: How many times this context has caused a GPU hang. */
167 unsigned int guilty_count; 164 unsigned int guilty_count;
168 /** 165 /**
diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c
index 371acf109e34..ab1be5c80ea5 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -105,6 +105,8 @@ intel_engine_setup(struct drm_i915_private *dev_priv,
105 /* Nothing to do here, execute in order of dependencies */ 105 /* Nothing to do here, execute in order of dependencies */
106 engine->schedule = NULL; 106 engine->schedule = NULL;
107 107
108 ATOMIC_INIT_NOTIFIER_HEAD(&engine->context_status_notifier);
109
108 dev_priv->engine[id] = engine; 110 dev_priv->engine[id] = engine;
109 return 0; 111 return 0;
110} 112}
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index ebf8023d21e6..471af3b480ad 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -345,7 +345,8 @@ execlists_context_status_change(struct drm_i915_gem_request *rq,
345 if (!IS_ENABLED(CONFIG_DRM_I915_GVT)) 345 if (!IS_ENABLED(CONFIG_DRM_I915_GVT))
346 return; 346 return;
347 347
348 atomic_notifier_call_chain(&rq->ctx->status_notifier, status, rq); 348 atomic_notifier_call_chain(&rq->engine->context_status_notifier,
349 status, rq);
349} 350}
350 351
351static void 352static void
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 79c2b8d72322..13dccb18cd43 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -403,6 +403,9 @@ struct intel_engine_cs {
403 */ 403 */
404 struct i915_gem_context *legacy_active_context; 404 struct i915_gem_context *legacy_active_context;
405 405
406 /* status_notifier: list of callbacks for context-switch changes */
407 struct atomic_notifier_head context_status_notifier;
408
406 struct intel_engine_hangcheck hangcheck; 409 struct intel_engine_hangcheck hangcheck;
407 410
408 bool needs_cmd_parser; 411 bool needs_cmd_parser;