drm/i915/gvt: refine mocs save restore policy
authorWeinan Li <weinan.z.li@intel.com>
Wed, 13 Dec 2017 02:47:01 +0000 (10:47 +0800)
committerZhenyu Wang <zhenyuw@linux.intel.com>
Mon, 18 Dec 2017 08:30:20 +0000 (16:30 +0800)
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>
drivers/gpu/drm/i915/gvt/cmd_parser.c
drivers/gpu/drm/i915/gvt/mmio_context.c

index 18c45734c7a271a81cd44f21c1007ba3f4025af9..be5c519b3324ddd840dd0e1b1d2faaa15b1a9261 100644 (file)
@@ -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;
index 5ad72fc0f9e7f2262a5b322a6584175710d7e001..06ea3d24e8d0ac022b9946045792f3cdf9f0b995 100644 (file)
@@ -203,6 +203,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,
@@ -220,16 +222,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;
        }
@@ -238,17 +241,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;
                }