Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f402f2d6 authored by Weinan Li's avatar Weinan Li Committed by Zhenyu Wang
Browse files

drm/i915/gvt: refine mocs save restore policy



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: default avatarWeinan Li <weinan.z.li@intel.com>
Signed-off-by: default avatarZhenyu Wang <zhenyuw@linux.intel.com>
parent e47107ad
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -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;
+18 −15
Original line number Diff line number Diff line
@@ -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;
		}