Skip to content

Commit

Permalink
drm/i915/gvt: Wean gvt off dev_priv->engine[]
Browse files Browse the repository at this point in the history
Stop trying to escape out of the gvt layer to find the engine that we
initially setup for use with gvt. Record the engines during initialisation
and use them henceforth.

add/remove: 1/4 grow/shrink: 22/28 up/down: 341/-1410 (-1069)

[Zhenyu: rebase, fix nonpriv register check fault, fix gvt engine
thread run failure.]

Cc: Ding Zhuocheng <zhuocheng.ding@intel.com>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Zhenyu Wang <zhenyuw@linux.intel.com>
Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20200304032307.2983-2-zhenyuw@linux.intel.com
  • Loading branch information
Chris Wilson authored and Zhenyu Wang committed Mar 6, 2020
1 parent aa444fc commit 8fde410
Show file tree
Hide file tree
Showing 11 changed files with 367 additions and 412 deletions.
204 changes: 92 additions & 112 deletions drivers/gpu/drm/i915/gvt/cmd_parser.c

Large diffs are not rendered by default.

99 changes: 47 additions & 52 deletions drivers/gpu/drm/i915/gvt/execlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@
#define _EL_OFFSET_STATUS_BUF 0x370
#define _EL_OFFSET_STATUS_PTR 0x3A0

#define execlist_ring_mmio(gvt, ring_id, offset) \
(gvt->dev_priv->engine[ring_id]->mmio_base + (offset))
#define execlist_ring_mmio(e, offset) ((e)->mmio_base + (offset))

#define valid_context(ctx) ((ctx)->valid)
#define same_context(a, b) (((a)->context_id == (b)->context_id) && \
Expand All @@ -54,12 +53,12 @@ static int context_switch_events[] = {
[VECS0] = VECS_AS_CONTEXT_SWITCH,
};

static int ring_id_to_context_switch_event(unsigned int ring_id)
static int to_context_switch_event(const struct intel_engine_cs *engine)
{
if (WARN_ON(ring_id >= ARRAY_SIZE(context_switch_events)))
if (WARN_ON(engine->id >= ARRAY_SIZE(context_switch_events)))
return -EINVAL;

return context_switch_events[ring_id];
return context_switch_events[engine->id];
}

static void switch_virtual_execlist_slot(struct intel_vgpu_execlist *execlist)
Expand Down Expand Up @@ -93,9 +92,8 @@ static void emulate_execlist_status(struct intel_vgpu_execlist *execlist)
struct execlist_ctx_descriptor_format *desc = execlist->running_context;
struct intel_vgpu *vgpu = execlist->vgpu;
struct execlist_status_format status;
int ring_id = execlist->ring_id;
u32 status_reg = execlist_ring_mmio(vgpu->gvt,
ring_id, _EL_OFFSET_STATUS);
u32 status_reg =
execlist_ring_mmio(execlist->engine, _EL_OFFSET_STATUS);

status.ldw = vgpu_vreg(vgpu, status_reg);
status.udw = vgpu_vreg(vgpu, status_reg + 4);
Expand Down Expand Up @@ -124,21 +122,19 @@ static void emulate_execlist_status(struct intel_vgpu_execlist *execlist)
}

static void emulate_csb_update(struct intel_vgpu_execlist *execlist,
struct execlist_context_status_format *status,
bool trigger_interrupt_later)
struct execlist_context_status_format *status,
bool trigger_interrupt_later)
{
struct intel_vgpu *vgpu = execlist->vgpu;
int ring_id = execlist->ring_id;
struct execlist_context_status_pointer_format ctx_status_ptr;
u32 write_pointer;
u32 ctx_status_ptr_reg, ctx_status_buf_reg, offset;
unsigned long hwsp_gpa;
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;

ctx_status_ptr_reg = execlist_ring_mmio(vgpu->gvt, ring_id,
_EL_OFFSET_STATUS_PTR);
ctx_status_buf_reg = execlist_ring_mmio(vgpu->gvt, ring_id,
_EL_OFFSET_STATUS_BUF);
ctx_status_ptr_reg =
execlist_ring_mmio(execlist->engine, _EL_OFFSET_STATUS_PTR);
ctx_status_buf_reg =
execlist_ring_mmio(execlist->engine, _EL_OFFSET_STATUS_BUF);

ctx_status_ptr.dw = vgpu_vreg(vgpu, ctx_status_ptr_reg);

Expand All @@ -161,26 +157,24 @@ static void emulate_csb_update(struct intel_vgpu_execlist *execlist,

/* Update the CSB and CSB write pointer in HWSP */
hwsp_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm,
vgpu->hws_pga[ring_id]);
vgpu->hws_pga[execlist->engine->id]);
if (hwsp_gpa != INTEL_GVT_INVALID_ADDR) {
intel_gvt_hypervisor_write_gpa(vgpu,
hwsp_gpa + I915_HWS_CSB_BUF0_INDEX * 4 +
write_pointer * 8,
status, 8);
hwsp_gpa + I915_HWS_CSB_BUF0_INDEX * 4 + write_pointer * 8,
status, 8);
intel_gvt_hypervisor_write_gpa(vgpu,
hwsp_gpa +
intel_hws_csb_write_index(dev_priv) * 4,
&write_pointer, 4);
hwsp_gpa + intel_hws_csb_write_index(execlist->engine->i915) * 4,
&write_pointer, 4);
}

gvt_dbg_el("vgpu%d: w pointer %u reg %x csb l %x csb h %x\n",
vgpu->id, write_pointer, offset, status->ldw, status->udw);
vgpu->id, write_pointer, offset, status->ldw, status->udw);

if (trigger_interrupt_later)
return;

intel_vgpu_trigger_virtual_event(vgpu,
ring_id_to_context_switch_event(execlist->ring_id));
to_context_switch_event(execlist->engine));
}

static int emulate_execlist_ctx_schedule_out(
Expand Down Expand Up @@ -261,9 +255,8 @@ static struct intel_vgpu_execlist_slot *get_next_execlist_slot(
struct intel_vgpu_execlist *execlist)
{
struct intel_vgpu *vgpu = execlist->vgpu;
int ring_id = execlist->ring_id;
u32 status_reg = execlist_ring_mmio(vgpu->gvt, ring_id,
_EL_OFFSET_STATUS);
u32 status_reg =
execlist_ring_mmio(execlist->engine, _EL_OFFSET_STATUS);
struct execlist_status_format status;

status.ldw = vgpu_vreg(vgpu, status_reg);
Expand Down Expand Up @@ -379,7 +372,6 @@ static int prepare_execlist_workload(struct intel_vgpu_workload *workload)
struct intel_vgpu *vgpu = workload->vgpu;
struct intel_vgpu_submission *s = &vgpu->submission;
struct execlist_ctx_descriptor_format ctx[2];
int ring_id = workload->ring_id;
int ret;

if (!workload->emulate_schedule_in)
Expand All @@ -388,7 +380,8 @@ static int prepare_execlist_workload(struct intel_vgpu_workload *workload)
ctx[0] = *get_desc_from_elsp_dwords(&workload->elsp_dwords, 0);
ctx[1] = *get_desc_from_elsp_dwords(&workload->elsp_dwords, 1);

ret = emulate_execlist_schedule_in(&s->execlist[ring_id], ctx);
ret = emulate_execlist_schedule_in(&s->execlist[workload->engine->id],
ctx);
if (ret) {
gvt_vgpu_err("fail to emulate execlist schedule in\n");
return ret;
Expand All @@ -399,21 +392,21 @@ static int prepare_execlist_workload(struct intel_vgpu_workload *workload)
static int complete_execlist_workload(struct intel_vgpu_workload *workload)
{
struct intel_vgpu *vgpu = workload->vgpu;
int ring_id = workload->ring_id;
struct intel_vgpu_submission *s = &vgpu->submission;
struct intel_vgpu_execlist *execlist = &s->execlist[ring_id];
struct intel_vgpu_execlist *execlist =
&s->execlist[workload->engine->id];
struct intel_vgpu_workload *next_workload;
struct list_head *next = workload_q_head(vgpu, ring_id)->next;
struct list_head *next = workload_q_head(vgpu, workload->engine)->next;
bool lite_restore = false;
int ret = 0;

gvt_dbg_el("complete workload %p status %d\n", workload,
workload->status);
gvt_dbg_el("complete workload %p status %d\n",
workload, workload->status);

if (workload->status || (vgpu->resetting_eng & BIT(ring_id)))
if (workload->status || vgpu->resetting_eng & workload->engine->mask)
goto out;

if (!list_empty(workload_q_head(vgpu, ring_id))) {
if (!list_empty(workload_q_head(vgpu, workload->engine))) {
struct execlist_ctx_descriptor_format *this_desc, *next_desc;

next_workload = container_of(next,
Expand All @@ -436,14 +429,15 @@ static int complete_execlist_workload(struct intel_vgpu_workload *workload)
return ret;
}

static int submit_context(struct intel_vgpu *vgpu, int ring_id,
struct execlist_ctx_descriptor_format *desc,
bool emulate_schedule_in)
static int submit_context(struct intel_vgpu *vgpu,
const struct intel_engine_cs *engine,
struct execlist_ctx_descriptor_format *desc,
bool emulate_schedule_in)
{
struct intel_vgpu_submission *s = &vgpu->submission;
struct intel_vgpu_workload *workload = NULL;

workload = intel_vgpu_create_workload(vgpu, ring_id, desc);
workload = intel_vgpu_create_workload(vgpu, engine, desc);
if (IS_ERR(workload))
return PTR_ERR(workload);

Expand All @@ -452,19 +446,20 @@ static int submit_context(struct intel_vgpu *vgpu, int ring_id,
workload->emulate_schedule_in = emulate_schedule_in;

if (emulate_schedule_in)
workload->elsp_dwords = s->execlist[ring_id].elsp_dwords;
workload->elsp_dwords = s->execlist[engine->id].elsp_dwords;

gvt_dbg_el("workload %p emulate schedule_in %d\n", workload,
emulate_schedule_in);
emulate_schedule_in);

intel_vgpu_queue_workload(workload);
return 0;
}

int intel_vgpu_submit_execlist(struct intel_vgpu *vgpu, int ring_id)
int intel_vgpu_submit_execlist(struct intel_vgpu *vgpu,
const struct intel_engine_cs *engine)
{
struct intel_vgpu_submission *s = &vgpu->submission;
struct intel_vgpu_execlist *execlist = &s->execlist[ring_id];
struct intel_vgpu_execlist *execlist = &s->execlist[engine->id];
struct execlist_ctx_descriptor_format *desc[2];
int i, ret;

Expand All @@ -489,7 +484,7 @@ int intel_vgpu_submit_execlist(struct intel_vgpu *vgpu, int ring_id)
for (i = 0; i < ARRAY_SIZE(desc); i++) {
if (!desc[i]->valid)
continue;
ret = submit_context(vgpu, ring_id, desc[i], i == 0);
ret = submit_context(vgpu, engine, desc[i], i == 0);
if (ret) {
gvt_vgpu_err("failed to submit desc %d\n", i);
return ret;
Expand All @@ -504,22 +499,22 @@ int intel_vgpu_submit_execlist(struct intel_vgpu *vgpu, int ring_id)
return -EINVAL;
}

static void init_vgpu_execlist(struct intel_vgpu *vgpu, int ring_id)
static void init_vgpu_execlist(struct intel_vgpu *vgpu,
const struct intel_engine_cs *engine)
{
struct intel_vgpu_submission *s = &vgpu->submission;
struct intel_vgpu_execlist *execlist = &s->execlist[ring_id];
struct intel_vgpu_execlist *execlist = &s->execlist[engine->id];
struct execlist_context_status_pointer_format ctx_status_ptr;
u32 ctx_status_ptr_reg;

memset(execlist, 0, sizeof(*execlist));

execlist->vgpu = vgpu;
execlist->ring_id = ring_id;
execlist->engine = engine;
execlist->slot[0].index = 0;
execlist->slot[1].index = 1;

ctx_status_ptr_reg = execlist_ring_mmio(vgpu->gvt, ring_id,
_EL_OFFSET_STATUS_PTR);
ctx_status_ptr_reg = execlist_ring_mmio(engine, _EL_OFFSET_STATUS_PTR);
ctx_status_ptr.dw = vgpu_vreg(vgpu, ctx_status_ptr_reg);
ctx_status_ptr.read_ptr = 0;
ctx_status_ptr.write_ptr = 0x7;
Expand Down Expand Up @@ -549,7 +544,7 @@ static void reset_execlist(struct intel_vgpu *vgpu,
intel_engine_mask_t tmp;

for_each_engine_masked(engine, &dev_priv->gt, engine_mask, tmp)
init_vgpu_execlist(vgpu, engine->id);
init_vgpu_execlist(vgpu, engine);
}

static int init_execlist(struct intel_vgpu *vgpu,
Expand Down
5 changes: 3 additions & 2 deletions drivers/gpu/drm/i915/gvt/execlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,16 +170,17 @@ struct intel_vgpu_execlist {
struct intel_vgpu_execlist_slot *running_slot;
struct intel_vgpu_execlist_slot *pending_slot;
struct execlist_ctx_descriptor_format *running_context;
int ring_id;
struct intel_vgpu *vgpu;
struct intel_vgpu_elsp_dwords elsp_dwords;
const struct intel_engine_cs *engine;
};

void intel_vgpu_clean_execlist(struct intel_vgpu *vgpu);

int intel_vgpu_init_execlist(struct intel_vgpu *vgpu);

int intel_vgpu_submit_execlist(struct intel_vgpu *vgpu, int ring_id);
int intel_vgpu_submit_execlist(struct intel_vgpu *vgpu,
const struct intel_engine_cs *engine);

void intel_vgpu_reset_execlist(struct intel_vgpu *vgpu,
intel_engine_mask_t engine_mask);
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/i915/gvt/gvt.c
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ int intel_gvt_init_device(struct drm_i915_private *dev_priv)
mutex_init(&gvt->lock);
mutex_init(&gvt->sched_lock);
gvt->dev_priv = dev_priv;
dev_priv->gvt = gvt;

init_device_info(gvt);

Expand Down Expand Up @@ -376,7 +377,6 @@ int intel_gvt_init_device(struct drm_i915_private *dev_priv)
intel_gvt_debugfs_init(gvt);

gvt_dbg_core("gvt device initialization is done\n");
dev_priv->gvt = gvt;
intel_gvt_host.dev = &dev_priv->drm.pdev->dev;
intel_gvt_host.initialized = true;
return 0;
Expand All @@ -402,6 +402,7 @@ int intel_gvt_init_device(struct drm_i915_private *dev_priv)
out_clean_idr:
idr_destroy(&gvt->vgpu_idr);
kfree(gvt);
dev_priv->gvt = NULL;
return ret;
}

Expand Down
Loading

0 comments on commit 8fde410

Please sign in to comment.