Skip to content

Commit ba25d97

Browse files
coxuintelzhenyw
authored andcommitted
drm/i915/gvt: Do not destroy ppgtt_mm during vGPU D3->D0.
When system enters S3 state, device enters D3 state while RAM remains powered. From vGPU/GVT perspective, ppgtt_mm is residual in guest memory during vGPU in D3 state, so that when guest state transits from S3->S0, ppgtt_mm can be re-used and no need rebuild. Previous implementation invalidate and destroy ppgtt_mm at DMLR, regardless the power state transition is S0->S3->S0 (guest suspend or resume) or OFF->S0 (normal boot/reboot), invalidate and destroy ppgtt_mm is unnecessary in the former transition case. The patch saves the vGPU D3/D0 transition state when guest writes the PCI_PM_CTRL in vGPU's configure space, then in later DMLR, GVT can decide whether or not invalidate and destroy ppgtt_mm is required. The d3_entered flags is reset after DMLR. To test this feature, make sure S3 is enabled in QEMU parameters: i440fx: PIIX4_PM.disable_s3=0 q35: ICH9-LPC.disable_s3=0 Also need enable sleep option in guest OS if it's disabled. v2: - Revise commit message to more accurate description. (Kevin) - Split patch by logic. (Zhenyu) Reviewed-by: Zhenyu Wang <[email protected]> Signed-off-by: Hang Yuan <[email protected]> Signed-off-by: Colin Xu <[email protected]> Signed-off-by: Zhenyu Wang <[email protected]> Link: http://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent e57bd05 commit ba25d97

File tree

5 files changed

+45
-3
lines changed

5 files changed

+45
-3
lines changed

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ static void vgpu_pci_cfg_mem_write(struct intel_vgpu *vgpu, unsigned int off,
7070
{
7171
u8 *cfg_base = vgpu_cfg_space(vgpu);
7272
u8 mask, new, old;
73+
pci_power_t pwr;
7374
int i = 0;
7475

7576
for (; i < bytes && (off + i < sizeof(pci_cfg_space_rw_bmp)); i++) {
@@ -91,6 +92,15 @@ static void vgpu_pci_cfg_mem_write(struct intel_vgpu *vgpu, unsigned int off,
9192
/* For other configuration space directly copy as it is. */
9293
if (i < bytes)
9394
memcpy(cfg_base + off + i, src + i, bytes - i);
95+
96+
if (off == vgpu->cfg_space.pmcsr_off && vgpu->cfg_space.pmcsr_off) {
97+
pwr = (pci_power_t __force)(*(u16*)(&vgpu_cfg_space(vgpu)[off])
98+
& PCI_PM_CTRL_STATE_MASK);
99+
if (pwr == PCI_D3hot)
100+
vgpu->d3_entered = true;
101+
gvt_dbg_core("vgpu-%d power status changed to %d\n",
102+
vgpu->id, pwr);
103+
}
94104
}
95105

96106
/**
@@ -366,6 +376,7 @@ void intel_vgpu_init_cfg_space(struct intel_vgpu *vgpu,
366376
struct intel_gvt *gvt = vgpu->gvt;
367377
const struct intel_gvt_device_info *info = &gvt->device_info;
368378
u16 *gmch_ctl;
379+
u8 next;
369380

370381
memcpy(vgpu_cfg_space(vgpu), gvt->firmware.cfg_space,
371382
info->cfg_space_size);
@@ -401,6 +412,19 @@ void intel_vgpu_init_cfg_space(struct intel_vgpu *vgpu,
401412
pci_resource_len(gvt->gt->i915->drm.pdev, 2);
402413

403414
memset(vgpu_cfg_space(vgpu) + PCI_ROM_ADDRESS, 0, 4);
415+
416+
/* PM Support */
417+
vgpu->cfg_space.pmcsr_off = 0;
418+
if (vgpu_cfg_space(vgpu)[PCI_STATUS] & PCI_STATUS_CAP_LIST) {
419+
next = vgpu_cfg_space(vgpu)[PCI_CAPABILITY_LIST];
420+
do {
421+
if (vgpu_cfg_space(vgpu)[next + PCI_CAP_LIST_ID] == PCI_CAP_ID_PM) {
422+
vgpu->cfg_space.pmcsr_off = next + PCI_PM_CTRL;
423+
break;
424+
}
425+
next = vgpu_cfg_space(vgpu)[next + PCI_CAP_LIST_NEXT];
426+
} while (next);
427+
}
404428
}
405429

406430
/**

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2501,7 +2501,7 @@ int intel_vgpu_init_gtt(struct intel_vgpu *vgpu)
25012501
return create_scratch_page_tree(vgpu);
25022502
}
25032503

2504-
static void intel_vgpu_destroy_all_ppgtt_mm(struct intel_vgpu *vgpu)
2504+
void intel_vgpu_destroy_all_ppgtt_mm(struct intel_vgpu *vgpu)
25052505
{
25062506
struct list_head *pos, *n;
25072507
struct intel_vgpu_mm *mm;

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,4 +279,6 @@ int intel_vgpu_emulate_ggtt_mmio_read(struct intel_vgpu *vgpu,
279279
int intel_vgpu_emulate_ggtt_mmio_write(struct intel_vgpu *vgpu,
280280
unsigned int off, void *p_data, unsigned int bytes);
281281

282+
void intel_vgpu_destroy_all_ppgtt_mm(struct intel_vgpu *vgpu);
283+
282284
#endif /* _GVT_GTT_H_ */

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ struct intel_vgpu_pci_bar {
106106
struct intel_vgpu_cfg_space {
107107
unsigned char virtual_cfg_space[PCI_CFG_SPACE_EXP_SIZE];
108108
struct intel_vgpu_pci_bar bar[INTEL_GVT_MAX_BAR_NUM];
109+
u32 pmcsr_off;
109110
};
110111

111112
#define vgpu_cfg_space(vgpu) ((vgpu)->cfg_space.virtual_cfg_space)
@@ -198,6 +199,8 @@ struct intel_vgpu {
198199
struct intel_vgpu_submission submission;
199200
struct radix_tree_root page_track_tree;
200201
u32 hws_pga[I915_NUM_ENGINES];
202+
/* Set on PCI_D3, reset on DMLR, not reflecting the actual PM state */
203+
bool d3_entered;
201204

202205
struct dentry *debugfs;
203206

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

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ void intel_gvt_release_vgpu(struct intel_vgpu *vgpu)
257257
intel_gvt_deactivate_vgpu(vgpu);
258258

259259
mutex_lock(&vgpu->vgpu_lock);
260+
vgpu->d3_entered = false;
260261
intel_vgpu_clean_workloads(vgpu, ALL_ENGINES);
261262
intel_vgpu_dmabuf_cleanup(vgpu);
262263
mutex_unlock(&vgpu->vgpu_lock);
@@ -393,6 +394,7 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt,
393394
INIT_RADIX_TREE(&vgpu->page_track_tree, GFP_KERNEL);
394395
idr_init(&vgpu->object_idr);
395396
intel_vgpu_init_cfg_space(vgpu, param->primary);
397+
vgpu->d3_entered = false;
396398

397399
ret = intel_vgpu_init_mmio(vgpu);
398400
if (ret)
@@ -557,10 +559,15 @@ void intel_gvt_reset_vgpu_locked(struct intel_vgpu *vgpu, bool dmlr,
557559
/* full GPU reset or device model level reset */
558560
if (engine_mask == ALL_ENGINES || dmlr) {
559561
intel_vgpu_select_submission_ops(vgpu, ALL_ENGINES, 0);
560-
intel_vgpu_invalidate_ppgtt(vgpu);
562+
if (engine_mask == ALL_ENGINES)
563+
intel_vgpu_invalidate_ppgtt(vgpu);
561564
/*fence will not be reset during virtual reset */
562565
if (dmlr) {
563-
intel_vgpu_reset_gtt(vgpu);
566+
if(!vgpu->d3_entered) {
567+
intel_vgpu_invalidate_ppgtt(vgpu);
568+
intel_vgpu_destroy_all_ppgtt_mm(vgpu);
569+
}
570+
intel_vgpu_reset_ggtt(vgpu, true);
564571
intel_vgpu_reset_resource(vgpu);
565572
}
566573

@@ -573,6 +580,12 @@ void intel_gvt_reset_vgpu_locked(struct intel_vgpu *vgpu, bool dmlr,
573580
/* only reset the failsafe mode when dmlr reset */
574581
vgpu->failsafe = false;
575582
vgpu->pv_notified = false;
583+
/*
584+
* PCI_D0 is set before dmlr, so reset d3_entered here
585+
* after done using.
586+
*/
587+
if(vgpu->d3_entered)
588+
vgpu->d3_entered = false;
576589
}
577590
}
578591

0 commit comments

Comments
 (0)