Skip to content
This repository was archived by the owner on Oct 3, 2024. It is now read-only.

Commit ab9da62

Browse files
Changbin Duzhenyw
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) Signed-off-by: Changbin Du <[email protected]> Reviewed-by: Chris Wilson <[email protected]> Signed-off-by: Zhenyu Wang <[email protected]>
1 parent 505b681 commit ab9da62

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
@@ -160,7 +160,6 @@ struct intel_vgpu {
160160
atomic_t running_workload_num;
161161
DECLARE_BITMAP(tlb_handle_pending, I915_NUM_ENGINES);
162162
struct i915_gem_context *shadow_ctx;
163-
struct notifier_block shadow_ctx_notifier_block;
164163

165164
#if IS_ENABLED(CONFIG_DRM_I915_GVT_KVMGT)
166165
struct {
@@ -231,6 +230,7 @@ struct intel_gvt {
231230
struct intel_gvt_gtt gtt;
232231
struct intel_gvt_opregion opregion;
233232
struct intel_gvt_workload_scheduler scheduler;
233+
struct notifier_block shadow_ctx_notifier_block[I915_NUM_ENGINES];
234234
DECLARE_HASHTABLE(cmd_table, GVT_CMD_HASH_BITS);
235235
struct intel_vgpu_type *types;
236236
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

@@ -493,34 +491,32 @@ void intel_gvt_wait_vgpu_idle(struct intel_vgpu *vgpu)
493491
void intel_gvt_clean_workload_scheduler(struct intel_gvt *gvt)
494492
{
495493
struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler;
496-
int i;
494+
struct intel_engine_cs *engine;
495+
enum intel_engine_id i;
497496

498497
gvt_dbg_core("clean workload scheduler\n");
499498

500-
for (i = 0; i < I915_NUM_ENGINES; i++) {
501-
if (scheduler->thread[i]) {
502-
kthread_stop(scheduler->thread[i]);
503-
scheduler->thread[i] = NULL;
504-
}
499+
for_each_engine(engine, gvt->dev_priv, i) {
500+
atomic_notifier_chain_unregister(
501+
&engine->context_status_notifier,
502+
&gvt->shadow_ctx_notifier_block[i]);
503+
kthread_stop(scheduler->thread[i]);
505504
}
506505
}
507506

508507
int intel_gvt_init_workload_scheduler(struct intel_gvt *gvt)
509508
{
510509
struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler;
511510
struct workload_thread_param *param = NULL;
511+
struct intel_engine_cs *engine;
512+
enum intel_engine_id i;
512513
int ret;
513-
int i;
514514

515515
gvt_dbg_core("init workload scheduler\n");
516516

517517
init_waitqueue_head(&scheduler->workload_complete_wq);
518518

519-
for (i = 0; i < I915_NUM_ENGINES; i++) {
520-
/* check ring mask at init time */
521-
if (!HAS_ENGINE(gvt->dev_priv, i))
522-
continue;
523-
519+
for_each_engine(engine, gvt->dev_priv, i) {
524520
init_waitqueue_head(&scheduler->waitq[i]);
525521

526522
param = kzalloc(sizeof(*param), GFP_KERNEL);
@@ -539,6 +535,11 @@ int intel_gvt_init_workload_scheduler(struct intel_gvt *gvt)
539535
ret = PTR_ERR(scheduler->thread[i]);
540536
goto err;
541537
}
538+
539+
gvt->shadow_ctx_notifier_block[i].notifier_call =
540+
shadow_context_status_change;
541+
atomic_notifier_chain_register(&engine->context_status_notifier,
542+
&gvt->shadow_ctx_notifier_block[i]);
542543
}
543544
return 0;
544545
err:
@@ -550,9 +551,6 @@ int intel_gvt_init_workload_scheduler(struct intel_gvt *gvt)
550551

551552
void intel_vgpu_clean_gvt_context(struct intel_vgpu *vgpu)
552553
{
553-
atomic_notifier_chain_unregister(&vgpu->shadow_ctx->status_notifier,
554-
&vgpu->shadow_ctx_notifier_block);
555-
556554
i915_gem_context_put_unlocked(vgpu->shadow_ctx);
557555
}
558556

@@ -567,10 +565,5 @@ int intel_vgpu_init_gvt_context(struct intel_vgpu *vgpu)
567565

568566
vgpu->shadow_ctx->engine[RCS].initialised = true;
569567

570-
vgpu->shadow_ctx_notifier_block.notifier_call =
571-
shadow_context_status_change;
572-
573-
atomic_notifier_chain_register(&vgpu->shadow_ctx->status_notifier,
574-
&vgpu->shadow_ctx_notifier_block);
575568
return 0;
576569
}

drivers/gpu/drm/i915/i915_gem_context.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,6 @@ __create_hw_context(struct drm_i915_private *dev_priv,
318318
ctx->ring_size = 4 * PAGE_SIZE;
319319
ctx->desc_template =
320320
default_desc_template(dev_priv, dev_priv->mm.aliasing_ppgtt);
321-
ATOMIC_INIT_NOTIFIER_HEAD(&ctx->status_notifier);
322321

323322
/* GuC requires the ring to be placed above GUC_WOPCM_TOP. If GuC is not
324323
* 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
@@ -158,9 +158,6 @@ struct i915_gem_context {
158158
/** desc_template: invariant fields for the HW context descriptor */
159159
u32 desc_template;
160160

161-
/** status_notifier: list of callbacks for context-switch changes */
162-
struct atomic_notifier_head status_notifier;
163-
164161
/** guilty_count: How many times this context has caused a GPU hang. */
165162
unsigned int guilty_count;
166163
/**

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
@@ -306,7 +306,8 @@ execlists_context_status_change(struct drm_i915_gem_request *rq,
306306
if (!IS_ENABLED(CONFIG_DRM_I915_GVT))
307307
return;
308308

309-
atomic_notifier_call_chain(&rq->ctx->status_notifier, status, rq);
309+
atomic_notifier_call_chain(&rq->engine->context_status_notifier,
310+
status, rq);
310311
}
311312

312313
static void

drivers/gpu/drm/i915/intel_ringbuffer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,9 @@ struct intel_engine_cs {
408408
*/
409409
struct i915_gem_context *legacy_active_context;
410410

411+
/* status_notifier: list of callbacks for context-switch changes */
412+
struct atomic_notifier_head context_status_notifier;
413+
411414
struct intel_engine_hangcheck hangcheck;
412415

413416
bool needs_cmd_parser;

0 commit comments

Comments
 (0)