Skip to content

Commit 590379a

Browse files
Changbin Dujnikula
authored andcommitted
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: 3c7ba63 ("drm/i915: Introduce execlist context status change notification") Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=100232 Signed-off-by: Changbin Du <[email protected]> Cc: Joonas Lahtinen <[email protected]> Cc: Tvrtko Ursulin <[email protected]> Cc: Zhi Wang <[email protected]> Reviewed-by: Chris Wilson <[email protected]> Link: http://patchwork.freedesktop.org/patch/msgid/[email protected] Acked-by: Zhenyu Wang <[email protected]> Signed-off-by: Chris Wilson <[email protected]> (cherry picked from commit 3fc0306) Signed-off-by: Jani Nikula <[email protected]> Link: http://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 3d3d18f commit 590379a

File tree

7 files changed

+27
-32
lines changed

7 files changed

+27
-32
lines changed

drivers/gpu/drm/i915/gvt/gvt.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,6 @@ struct intel_vgpu {
162162
atomic_t running_workload_num;
163163
DECLARE_BITMAP(tlb_handle_pending, I915_NUM_ENGINES);
164164
struct i915_gem_context *shadow_ctx;
165-
struct notifier_block shadow_ctx_notifier_block;
166165

167166
#if IS_ENABLED(CONFIG_DRM_I915_GVT_KVMGT)
168167
struct {
@@ -233,6 +232,7 @@ struct intel_gvt {
233232
struct intel_gvt_gtt gtt;
234233
struct intel_gvt_opregion opregion;
235234
struct intel_gvt_workload_scheduler scheduler;
235+
struct notifier_block shadow_ctx_notifier_block[I915_NUM_ENGINES];
236236
DECLARE_HASHTABLE(cmd_table, GVT_CMD_HASH_BITS);
237237
struct intel_vgpu_type *types;
238238
unsigned int num_types;

drivers/gpu/drm/i915/gvt/scheduler.c

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,10 @@ static int populate_shadow_context(struct intel_vgpu_workload *workload)
130130
static int shadow_context_status_change(struct notifier_block *nb,
131131
unsigned long action, void *data)
132132
{
133-
struct intel_vgpu *vgpu = container_of(nb,
134-
struct intel_vgpu, shadow_ctx_notifier_block);
135-
struct drm_i915_gem_request *req =
136-
(struct drm_i915_gem_request *)data;
137-
struct intel_gvt_workload_scheduler *scheduler =
138-
&vgpu->gvt->scheduler;
133+
struct drm_i915_gem_request *req = (struct drm_i915_gem_request *)data;
134+
struct intel_gvt *gvt = container_of(nb, struct intel_gvt,
135+
shadow_ctx_notifier_block[req->engine->id]);
136+
struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler;
139137
struct intel_vgpu_workload *workload =
140138
scheduler->current_workload[req->engine->id];
141139

@@ -534,34 +532,32 @@ void intel_gvt_wait_vgpu_idle(struct intel_vgpu *vgpu)
534532
void intel_gvt_clean_workload_scheduler(struct intel_gvt *gvt)
535533
{
536534
struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler;
537-
int i;
535+
struct intel_engine_cs *engine;
536+
enum intel_engine_id i;
538537

539538
gvt_dbg_core("clean workload scheduler\n");
540539

541-
for (i = 0; i < I915_NUM_ENGINES; i++) {
542-
if (scheduler->thread[i]) {
543-
kthread_stop(scheduler->thread[i]);
544-
scheduler->thread[i] = NULL;
545-
}
540+
for_each_engine(engine, gvt->dev_priv, i) {
541+
atomic_notifier_chain_unregister(
542+
&engine->context_status_notifier,
543+
&gvt->shadow_ctx_notifier_block[i]);
544+
kthread_stop(scheduler->thread[i]);
546545
}
547546
}
548547

549548
int intel_gvt_init_workload_scheduler(struct intel_gvt *gvt)
550549
{
551550
struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler;
552551
struct workload_thread_param *param = NULL;
552+
struct intel_engine_cs *engine;
553+
enum intel_engine_id i;
553554
int ret;
554-
int i;
555555

556556
gvt_dbg_core("init workload scheduler\n");
557557

558558
init_waitqueue_head(&scheduler->workload_complete_wq);
559559

560-
for (i = 0; i < I915_NUM_ENGINES; i++) {
561-
/* check ring mask at init time */
562-
if (!HAS_ENGINE(gvt->dev_priv, i))
563-
continue;
564-
560+
for_each_engine(engine, gvt->dev_priv, i) {
565561
init_waitqueue_head(&scheduler->waitq[i]);
566562

567563
param = kzalloc(sizeof(*param), GFP_KERNEL);
@@ -580,6 +576,11 @@ int intel_gvt_init_workload_scheduler(struct intel_gvt *gvt)
580576
ret = PTR_ERR(scheduler->thread[i]);
581577
goto err;
582578
}
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]);
583584
}
584585
return 0;
585586
err:
@@ -591,9 +592,6 @@ int intel_gvt_init_workload_scheduler(struct intel_gvt *gvt)
591592

592593
void intel_vgpu_clean_gvt_context(struct intel_vgpu *vgpu)
593594
{
594-
atomic_notifier_chain_unregister(&vgpu->shadow_ctx->status_notifier,
595-
&vgpu->shadow_ctx_notifier_block);
596-
597595
i915_gem_context_put_unlocked(vgpu->shadow_ctx);
598596
}
599597

@@ -608,10 +606,5 @@ int intel_vgpu_init_gvt_context(struct intel_vgpu *vgpu)
608606

609607
vgpu->shadow_ctx->engine[RCS].initialised = true;
610608

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);
616609
return 0;
617610
}

drivers/gpu/drm/i915/i915_gem_context.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,6 @@ __create_hw_context(struct drm_i915_private *dev_priv,
311311
ctx->ring_size = 4 * PAGE_SIZE;
312312
ctx->desc_template = GEN8_CTX_ADDRESSING_MODE(dev_priv) <<
313313
GEN8_CTX_ADDRESSING_MODE_SHIFT;
314-
ATOMIC_INIT_NOTIFIER_HEAD(&ctx->status_notifier);
315314

316315
/* GuC requires the ring to be placed above GUC_WOPCM_TOP. If GuC is not
317316
* present or not in use we still need a small bias as ring wraparound

drivers/gpu/drm/i915/i915_gem_context.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,6 @@ struct i915_gem_context {
160160
/** desc_template: invariant fields for the HW context descriptor */
161161
u32 desc_template;
162162

163-
/** status_notifier: list of callbacks for context-switch changes */
164-
struct atomic_notifier_head status_notifier;
165-
166163
/** guilty_count: How many times this context has caused a GPU hang. */
167164
unsigned int guilty_count;
168165
/**

drivers/gpu/drm/i915/intel_engine_cs.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ intel_engine_setup(struct drm_i915_private *dev_priv,
105105
/* Nothing to do here, execute in order of dependencies */
106106
engine->schedule = NULL;
107107

108+
ATOMIC_INIT_NOTIFIER_HEAD(&engine->context_status_notifier);
109+
108110
dev_priv->engine[id] = engine;
109111
return 0;
110112
}

drivers/gpu/drm/i915/intel_lrc.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,8 @@ execlists_context_status_change(struct drm_i915_gem_request *rq,
345345
if (!IS_ENABLED(CONFIG_DRM_I915_GVT))
346346
return;
347347

348-
atomic_notifier_call_chain(&rq->ctx->status_notifier, status, rq);
348+
atomic_notifier_call_chain(&rq->engine->context_status_notifier,
349+
status, rq);
349350
}
350351

351352
static void

drivers/gpu/drm/i915/intel_ringbuffer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,9 @@ struct intel_engine_cs {
403403
*/
404404
struct i915_gem_context *legacy_active_context;
405405

406+
/* status_notifier: list of callbacks for context-switch changes */
407+
struct atomic_notifier_head context_status_notifier;
408+
406409
struct intel_engine_hangcheck hangcheck;
407410

408411
bool needs_cmd_parser;

0 commit comments

Comments
 (0)