Skip to content

Commit 1be8f34

Browse files
Merge tag 'gvt-next-2020-05-12' of https://github.com/intel/gvt-linux into drm-intel-next-queued
gvt-next-2020-05-12 - Support PPGTT update via LRI cmd (Zhenyu) - Remove extra kmap for shadow ctx update (Zhenyu) - Move workload cleanup out of execlist handling code (Zhenyu) Signed-off-by: Joonas Lahtinen <[email protected]> From: Zhenyu Wang <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
2 parents 7a00e68 + 47e5183 commit 1be8f34

File tree

7 files changed

+155
-12
lines changed

7 files changed

+155
-12
lines changed

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

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -882,6 +882,47 @@ static int mocs_cmd_reg_handler(struct parser_exec_state *s,
882882
return 0;
883883
}
884884

885+
static int is_cmd_update_pdps(unsigned int offset,
886+
struct parser_exec_state *s)
887+
{
888+
u32 base = s->workload->engine->mmio_base;
889+
return i915_mmio_reg_equal(_MMIO(offset), GEN8_RING_PDP_UDW(base, 0));
890+
}
891+
892+
static int cmd_pdp_mmio_update_handler(struct parser_exec_state *s,
893+
unsigned int offset, unsigned int index)
894+
{
895+
struct intel_vgpu *vgpu = s->vgpu;
896+
struct intel_vgpu_mm *shadow_mm = s->workload->shadow_mm;
897+
struct intel_vgpu_mm *mm;
898+
u64 pdps[GEN8_3LVL_PDPES];
899+
900+
if (shadow_mm->ppgtt_mm.root_entry_type ==
901+
GTT_TYPE_PPGTT_ROOT_L4_ENTRY) {
902+
pdps[0] = (u64)cmd_val(s, 2) << 32;
903+
pdps[0] |= cmd_val(s, 4);
904+
905+
mm = intel_vgpu_find_ppgtt_mm(vgpu, pdps);
906+
if (!mm) {
907+
gvt_vgpu_err("failed to get the 4-level shadow vm\n");
908+
return -EINVAL;
909+
}
910+
intel_vgpu_mm_get(mm);
911+
list_add_tail(&mm->ppgtt_mm.link,
912+
&s->workload->lri_shadow_mm);
913+
*cmd_ptr(s, 2) = upper_32_bits(mm->ppgtt_mm.shadow_pdps[0]);
914+
*cmd_ptr(s, 4) = lower_32_bits(mm->ppgtt_mm.shadow_pdps[0]);
915+
} else {
916+
/* Currently all guests use PML4 table and now can't
917+
* have a guest with 3-level table but uses LRI for
918+
* PPGTT update. So this is simply un-testable. */
919+
GEM_BUG_ON(1);
920+
gvt_vgpu_err("invalid shared shadow vm type\n");
921+
return -EINVAL;
922+
}
923+
return 0;
924+
}
925+
885926
static int cmd_reg_handler(struct parser_exec_state *s,
886927
unsigned int offset, unsigned int index, char *cmd)
887928
{
@@ -920,6 +961,10 @@ static int cmd_reg_handler(struct parser_exec_state *s,
920961
patch_value(s, cmd_ptr(s, index), VGT_PVINFO_PAGE);
921962
}
922963

964+
if (is_cmd_update_pdps(offset, s) &&
965+
cmd_pdp_mmio_update_handler(s, offset, index))
966+
return -EINVAL;
967+
923968
/* TODO
924969
* In order to let workload with inhibit context to generate
925970
* correct image data into memory, vregs values will be loaded to

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -424,8 +424,6 @@ static int complete_execlist_workload(struct intel_vgpu_workload *workload)
424424

425425
ret = emulate_execlist_ctx_schedule_out(execlist, &workload->ctx_desc);
426426
out:
427-
intel_vgpu_unpin_mm(workload->shadow_mm);
428-
intel_vgpu_destroy_workload(workload);
429427
return ret;
430428
}
431429

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1900,6 +1900,7 @@ struct intel_vgpu_mm *intel_vgpu_create_ppgtt_mm(struct intel_vgpu *vgpu,
19001900

19011901
INIT_LIST_HEAD(&mm->ppgtt_mm.list);
19021902
INIT_LIST_HEAD(&mm->ppgtt_mm.lru_list);
1903+
INIT_LIST_HEAD(&mm->ppgtt_mm.link);
19031904

19041905
if (root_entry_type == GTT_TYPE_PPGTT_ROOT_L4_ENTRY)
19051906
mm->ppgtt_mm.guest_pdps[0] = pdps[0];

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ struct intel_vgpu_mm {
160160

161161
struct list_head list;
162162
struct list_head lru_list;
163+
struct list_head link; /* possible LRI shadow mm list */
163164
} ppgtt_mm;
164165
struct {
165166
void *virtual_ggtt;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2812,7 +2812,7 @@ static int init_bdw_mmio_info(struct intel_gvt *gvt)
28122812
MMIO_D(GAMTARBMODE, D_BDW_PLUS);
28132813

28142814
#define RING_REG(base) _MMIO((base) + 0x270)
2815-
MMIO_RING_F(RING_REG, 32, 0, 0, 0, D_BDW_PLUS, NULL, NULL);
2815+
MMIO_RING_F(RING_REG, 32, F_CMD_ACCESS, 0, 0, D_BDW_PLUS, NULL, NULL);
28162816
#undef RING_REG
28172817

28182818
MMIO_RING_GM_RDR(RING_HWS_PGA, D_BDW_PLUS, NULL, hws_pga_write);

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

Lines changed: 106 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,22 +58,18 @@ static void set_context_pdp_root_pointer(
5858

5959
static void update_shadow_pdps(struct intel_vgpu_workload *workload)
6060
{
61-
struct drm_i915_gem_object *ctx_obj =
62-
workload->req->context->state->obj;
6361
struct execlist_ring_context *shadow_ring_context;
64-
struct page *page;
62+
struct intel_context *ctx = workload->req->context;
6563

6664
if (WARN_ON(!workload->shadow_mm))
6765
return;
6866

6967
if (WARN_ON(!atomic_read(&workload->shadow_mm->pincount)))
7068
return;
7169

72-
page = i915_gem_object_get_page(ctx_obj, LRC_STATE_PN);
73-
shadow_ring_context = kmap(page);
70+
shadow_ring_context = (struct execlist_ring_context *)ctx->lrc_reg_state;
7471
set_context_pdp_root_pointer(shadow_ring_context,
7572
(void *)workload->shadow_mm->ppgtt_mm.shadow_pdps);
76-
kunmap(page);
7773
}
7874

7975
/*
@@ -646,10 +642,11 @@ static void release_shadow_batch_buffer(struct intel_vgpu_workload *workload)
646642
}
647643
}
648644

649-
static int prepare_workload(struct intel_vgpu_workload *workload)
645+
static int
646+
intel_vgpu_shadow_mm_pin(struct intel_vgpu_workload *workload)
650647
{
651648
struct intel_vgpu *vgpu = workload->vgpu;
652-
struct intel_vgpu_submission *s = &vgpu->submission;
649+
struct intel_vgpu_mm *m;
653650
int ret = 0;
654651

655652
ret = intel_vgpu_pin_mm(workload->shadow_mm);
@@ -664,6 +661,52 @@ static int prepare_workload(struct intel_vgpu_workload *workload)
664661
return -EINVAL;
665662
}
666663

664+
if (!list_empty(&workload->lri_shadow_mm)) {
665+
list_for_each_entry(m, &workload->lri_shadow_mm,
666+
ppgtt_mm.link) {
667+
ret = intel_vgpu_pin_mm(m);
668+
if (ret) {
669+
list_for_each_entry_from_reverse(m,
670+
&workload->lri_shadow_mm,
671+
ppgtt_mm.link)
672+
intel_vgpu_unpin_mm(m);
673+
gvt_vgpu_err("LRI shadow ppgtt fail to pin\n");
674+
break;
675+
}
676+
}
677+
}
678+
679+
if (ret)
680+
intel_vgpu_unpin_mm(workload->shadow_mm);
681+
682+
return ret;
683+
}
684+
685+
static void
686+
intel_vgpu_shadow_mm_unpin(struct intel_vgpu_workload *workload)
687+
{
688+
struct intel_vgpu_mm *m;
689+
690+
if (!list_empty(&workload->lri_shadow_mm)) {
691+
list_for_each_entry(m, &workload->lri_shadow_mm,
692+
ppgtt_mm.link)
693+
intel_vgpu_unpin_mm(m);
694+
}
695+
intel_vgpu_unpin_mm(workload->shadow_mm);
696+
}
697+
698+
static int prepare_workload(struct intel_vgpu_workload *workload)
699+
{
700+
struct intel_vgpu *vgpu = workload->vgpu;
701+
struct intel_vgpu_submission *s = &vgpu->submission;
702+
int ret = 0;
703+
704+
ret = intel_vgpu_shadow_mm_pin(workload);
705+
if (ret) {
706+
gvt_vgpu_err("fail to pin shadow mm\n");
707+
return ret;
708+
}
709+
667710
update_shadow_pdps(workload);
668711

669712
set_context_ppgtt_from_shadow(workload, s->shadow[workload->engine->id]);
@@ -710,7 +753,7 @@ static int prepare_workload(struct intel_vgpu_workload *workload)
710753
err_shadow_batch:
711754
release_shadow_batch_buffer(workload);
712755
err_unpin_mm:
713-
intel_vgpu_unpin_mm(workload->shadow_mm);
756+
intel_vgpu_shadow_mm_unpin(workload);
714757
return ret;
715758
}
716759

@@ -820,6 +863,37 @@ pick_next_workload(struct intel_gvt *gvt, struct intel_engine_cs *engine)
820863
return workload;
821864
}
822865

866+
static void update_guest_pdps(struct intel_vgpu *vgpu,
867+
u64 ring_context_gpa, u32 pdp[8])
868+
{
869+
u64 gpa;
870+
int i;
871+
872+
gpa = ring_context_gpa + RING_CTX_OFF(pdps[0].val);
873+
874+
for (i = 0; i < 8; i++)
875+
intel_gvt_hypervisor_write_gpa(vgpu,
876+
gpa + i * 8, &pdp[7 - i], 4);
877+
}
878+
879+
static bool
880+
check_shadow_context_ppgtt(struct execlist_ring_context *c, struct intel_vgpu_mm *m)
881+
{
882+
if (m->ppgtt_mm.root_entry_type == GTT_TYPE_PPGTT_ROOT_L4_ENTRY) {
883+
u64 shadow_pdp = c->pdps[7].val | (u64) c->pdps[6].val << 32;
884+
885+
if (shadow_pdp != m->ppgtt_mm.shadow_pdps[0]) {
886+
gvt_dbg_mm("4-level context ppgtt not match LRI command\n");
887+
return false;
888+
}
889+
return true;
890+
} else {
891+
/* see comment in LRI handler in cmd_parser.c */
892+
gvt_dbg_mm("invalid shadow mm type\n");
893+
return false;
894+
}
895+
}
896+
823897
static void update_guest_context(struct intel_vgpu_workload *workload)
824898
{
825899
struct i915_request *rq = workload->req;
@@ -905,6 +979,15 @@ static void update_guest_context(struct intel_vgpu_workload *workload)
905979

906980
shadow_ring_context = (void *) ctx->lrc_reg_state;
907981

982+
if (!list_empty(&workload->lri_shadow_mm)) {
983+
struct intel_vgpu_mm *m = list_last_entry(&workload->lri_shadow_mm,
984+
struct intel_vgpu_mm,
985+
ppgtt_mm.link);
986+
GEM_BUG_ON(!check_shadow_context_ppgtt(shadow_ring_context, m));
987+
update_guest_pdps(vgpu, workload->ring_context_gpa,
988+
(void *)m->ppgtt_mm.guest_pdps);
989+
}
990+
908991
#define COPY_REG(name) \
909992
intel_gvt_hypervisor_write_gpa(vgpu, workload->ring_context_gpa + \
910993
RING_CTX_OFF(name.val), &shadow_ring_context->name.val, 4)
@@ -1013,6 +1096,9 @@ static void complete_current_workload(struct intel_gvt *gvt, int ring_id)
10131096

10141097
workload->complete(workload);
10151098

1099+
intel_vgpu_shadow_mm_unpin(workload);
1100+
intel_vgpu_destroy_workload(workload);
1101+
10161102
atomic_dec(&s->running_workload_num);
10171103
wake_up(&scheduler->workload_complete_wq);
10181104

@@ -1406,6 +1492,16 @@ void intel_vgpu_destroy_workload(struct intel_vgpu_workload *workload)
14061492
release_shadow_batch_buffer(workload);
14071493
release_shadow_wa_ctx(&workload->wa_ctx);
14081494

1495+
if (!list_empty(&workload->lri_shadow_mm)) {
1496+
struct intel_vgpu_mm *m, *mm;
1497+
list_for_each_entry_safe(m, mm, &workload->lri_shadow_mm,
1498+
ppgtt_mm.link) {
1499+
list_del(&m->ppgtt_mm.link);
1500+
intel_vgpu_mm_put(m);
1501+
}
1502+
}
1503+
1504+
GEM_BUG_ON(!list_empty(&workload->lri_shadow_mm));
14091505
if (workload->shadow_mm)
14101506
intel_vgpu_mm_put(workload->shadow_mm);
14111507

@@ -1424,6 +1520,7 @@ alloc_workload(struct intel_vgpu *vgpu)
14241520

14251521
INIT_LIST_HEAD(&workload->list);
14261522
INIT_LIST_HEAD(&workload->shadow_bb);
1523+
INIT_LIST_HEAD(&workload->lri_shadow_mm);
14271524

14281525
init_waitqueue_head(&workload->shadow_ctx_status_wq);
14291526
atomic_set(&workload->shadow_ctx_active, 0);

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ struct intel_vgpu_workload {
8787
int status;
8888

8989
struct intel_vgpu_mm *shadow_mm;
90+
struct list_head lri_shadow_mm; /* For PPGTT load cmd */
9091

9192
/* different submission model may need different handler */
9293
int (*prepare)(struct intel_vgpu_workload *);

0 commit comments

Comments
 (0)