[2/3] drm/i915/gvt: refine mocs save restore policy

Submitted by Weinan Li on Dec. 7, 2017, 4:34 a.m.

Details

Message ID 1512621279-27199-3-git-send-email-weinan.z.li@intel.com
State New
Headers show
Series "mmio save restore refine in vgpu switch" ( rev: 1 ) in Intel GFX

Not browsing as part of any series.

Commit Message

Weinan Li Dec. 7, 2017, 4:34 a.m.
Save and restore the mocs regs of one VM in GVT-g burning too much CPU
utilization. Add LRI command scan to monitor the change of mocs registers,
save the state in vreg, and use delta update policy to restore them.
It can obviously reduce the MMIO r/w count, and improve the performance
of context switch.

Signed-off-by: Weinan Li <weinan.z.li@intel.com>
---
 drivers/gpu/drm/i915/gvt/cmd_parser.c | 19 +++++++++++++++++++
 drivers/gpu/drm/i915/gvt/render.c     | 33 ++++++++++++++++++---------------
 2 files changed, 37 insertions(+), 15 deletions(-)

Patch hide | download patch | download mbox

diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c
index 18c4573..be5c519b 100644
--- a/drivers/gpu/drm/i915/gvt/cmd_parser.c
+++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c
@@ -825,6 +825,21 @@  static int force_nonpriv_reg_handler(struct parser_exec_state *s,
 	return 0;
 }
 
+static inline bool is_mocs_mmio(unsigned int offset)
+{
+	return ((offset >= 0xc800) && (offset <= 0xcff8)) ||
+		((offset >= 0xb020) && (offset <= 0xb0a0));
+}
+
+static int mocs_cmd_reg_handler(struct parser_exec_state *s,
+				unsigned int offset, unsigned int index)
+{
+	if (!is_mocs_mmio(offset))
+		return -EINVAL;
+	vgpu_vreg(s->vgpu, offset) = cmd_val(s, index + 1);
+	return 0;
+}
+
 static int cmd_reg_handler(struct parser_exec_state *s,
 	unsigned int offset, unsigned int index, char *cmd)
 {
@@ -848,6 +863,10 @@  static int cmd_reg_handler(struct parser_exec_state *s,
 		return 0;
 	}
 
+	if (is_mocs_mmio(offset) &&
+	    mocs_cmd_reg_handler(s, offset, index))
+		return -EINVAL;
+
 	if (is_force_nonpriv_mmio(offset) &&
 		force_nonpriv_reg_handler(s, offset, index))
 		return -EPERM;
diff --git a/drivers/gpu/drm/i915/gvt/render.c b/drivers/gpu/drm/i915/gvt/render.c
index ec1e60d..724f10d 100644
--- a/drivers/gpu/drm/i915/gvt/render.c
+++ b/drivers/gpu/drm/i915/gvt/render.c
@@ -195,6 +195,8 @@  static void switch_mocs(struct intel_vgpu *pre, struct intel_vgpu *next,
 {
 	struct drm_i915_private *dev_priv;
 	i915_reg_t offset, l3_offset;
+	u32 old_v, new_v;
+
 	u32 regs[] = {
 		[RCS] = 0xc800,
 		[VCS] = 0xc900,
@@ -212,16 +214,17 @@  static void switch_mocs(struct intel_vgpu *pre, struct intel_vgpu *next,
 
 	for (i = 0; i < 64; i++) {
 		if (pre)
-			vgpu_vreg(pre, offset) =
-				I915_READ_FW(offset);
+			old_v = vgpu_vreg(pre, offset);
 		else
-			gen9_render_mocs[ring_id][i] =
-				I915_READ_FW(offset);
-
+			old_v = gen9_render_mocs[ring_id][i]
+			      = I915_READ_FW(offset);
 		if (next)
-			I915_WRITE_FW(offset, vgpu_vreg(next, offset));
+			new_v = vgpu_vreg(next, offset);
 		else
-			I915_WRITE_FW(offset, gen9_render_mocs[ring_id][i]);
+			new_v = gen9_render_mocs[ring_id][i];
+
+		if (old_v != new_v)
+			I915_WRITE_FW(offset, new_v);
 
 		offset.reg += 4;
 	}
@@ -230,17 +233,17 @@  static void switch_mocs(struct intel_vgpu *pre, struct intel_vgpu *next,
 		l3_offset.reg = 0xb020;
 		for (i = 0; i < 32; i++) {
 			if (pre)
-				vgpu_vreg(pre, l3_offset) =
-					I915_READ_FW(l3_offset);
+				old_v = vgpu_vreg(pre, l3_offset);
 			else
-				gen9_render_mocs_L3[i] =
-					I915_READ_FW(l3_offset);
+				old_v = gen9_render_mocs_L3[i]
+				      = I915_READ_FW(offset);
 			if (next)
-				I915_WRITE_FW(l3_offset,
-					      vgpu_vreg(next, l3_offset));
+				new_v = vgpu_vreg(next, l3_offset);
 			else
-				I915_WRITE_FW(l3_offset,
-					      gen9_render_mocs_L3[i]);
+				new_v = gen9_render_mocs_L3[i];
+
+			if (old_v != new_v)
+				I915_WRITE_FW(l3_offset, new_v);
 
 			l3_offset.reg += 4;
 		}