Blob Blame History Raw
From f402f2d6c3c5a5192869ffbdc079b782ef32dd01 Mon Sep 17 00:00:00 2001
From: Weinan Li <weinan.z.li@intel.com>
Date: Wed, 13 Dec 2017 10:47:01 +0800
Subject: [PATCH] drm/i915/gvt: refine mocs save restore policy
Git-commit: f402f2d6c3c5a5192869ffbdc079b782ef32dd01
Patch-mainline: v4.16-rc1
References: FATE#322643 bsc#1055900

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>
Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
Acked-by: Takashi Iwai <tiwai@suse.de>

---
 drivers/gpu/drm/i915/gvt/cmd_parser.c   |   19 ++++++++++++++++++
 drivers/gpu/drm/i915/gvt/mmio_context.c |   33 +++++++++++++++++---------------
 2 files changed, 37 insertions(+), 15 deletions(-)

--- 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(str
 	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
 		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;
--- a/drivers/gpu/drm/i915/gvt/mmio_context.c
+++ b/drivers/gpu/drm/i915/gvt/mmio_context.c
@@ -203,6 +203,8 @@ static void switch_mocs(struct intel_vgp
 {
 	struct drm_i915_private *dev_priv;
 	i915_reg_t offset, l3_offset;
+	u32 old_v, new_v;
+
 	u32 regs[] = {
 		[RCS] = 0xc800,
 		[VCS] = 0xc900,
@@ -220,16 +222,17 @@ static void switch_mocs(struct intel_vgp
 
 	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;
 	}
@@ -238,17 +241,17 @@ static void switch_mocs(struct intel_vgp
 		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;
 		}