[Intel-gfx] [PATCH igt] igt/gem_ctx_isolation: Check isolation of registers between contexts

Joonas Lahtinen joonas.lahtinen at linux.intel.com
Mon Dec 4 10:23:11 UTC 2017


On Fri, 2017-12-01 at 11:13 +0000, Chris Wilson wrote:
> A new context assumes that all of its registers are in the default state
> when it is created. What may happen is that a register written by one
> context may leak into the second, causing mass confusion.
> 
> v2: Extend back to Sandybridge (etc)
> v3: Check context preserves registers across suspend/hibernate and resets.
> v4: Complete the remapping onto the new class:instance
> v5: Not like that, like this, try again to use class:instance
> v6: Prepare for retrospective gen4 contexts!
> v7: Repaint register set name to nonpriv, as this is what bspec calls the
> registers that are writable by userspace.
> 
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> Cc: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>

<SNIP>

> +static uint32_t read_regs(int fd,
> +			  uint32_t ctx,
> +			  const struct intel_execution_engine2 *e,
> +			  unsigned int flags)
> +{
> +	const unsigned int gen = intel_gen(intel_get_drm_devid(fd));
> +	const unsigned int gen_bit = 1 << gen;

You did define BIT() in the beginning...

<SNIP>

> +	n = 0;
> +	for (const struct named_register *r = nonpriv_registers; r->name; r++) {
> +		if (!(r->engine_mask & engine_bit))
> +			continue;
> +		if (!(r->gen_mask & gen_bit))
> +			continue;
> +
> +		for (unsigned count = r->count ?: 1, offset = r->offset;
> +		     count--; offset += 4) {
> +			*b++ = 0x24 << 23 | (1 + r64b); /* SRM */
> +			*b++ = offset;
> +			reloc[n].target_handle = obj[0].handle;

I still kind of loathe the obj[0] vs obj[1] when it's not going to be
about comparing the two. obj_regs and obj_batch is just requires so
much fewer scroll-ups to see what was 0 and what was 1...

> +			reloc[n].presumed_offset = 0;
> +			reloc[n].offset = (b - batch) * sizeof(*b);
> +			reloc[n].delta = offset;

This might confuse somebody. At least call the variable r_offset (or
reg_offset).

> +			reloc[n].read_domains = I915_GEM_DOMAIN_RENDER;
> +			reloc[n].write_domain = I915_GEM_DOMAIN_RENDER;
> +			*b++ = offset;
> +			if (r64b)
> +				*b++ = 0;
> +			n++;

I can't see why this is not either inside the for () or bound closer to
filling the relocation, here it's bit of a "what?".

<SNIP>

> +static void restore_regs(int fd,
> +			 uint32_t ctx,
> +			 const struct intel_execution_engine2 *e,
> +			 unsigned int flags,
> +			 uint32_t regs)
> +{
> +	const unsigned int gen = intel_gen(intel_get_drm_devid(fd));
> +	const unsigned int gen_bit = 1 << gen;
> +	const unsigned int engine_bit = ENGINE(e->class, e->instance);
> +	const bool r64b = gen >= 8;
> +	struct drm_i915_gem_exec_object2 obj[2];
> +	struct drm_i915_gem_execbuffer2 execbuf;
> +	struct drm_i915_gem_relocation_entry *reloc;
> +	unsigned int batch_size, n;
> +	uint32_t *batch, *b;
> +
> +	if (gen < 7) /* no LRM */
> +		return;

Considering this restriction, would not it be possible to just CPU
mmap and have this as a bunch of LRIs?

<SNIP>

> +static void preservation(int fd,
> +			 const struct intel_execution_engine2 *e,
> +			 unsigned int flags)
> +{
> +	static const uint32_t values[] = {
> +		0x0,
> +		0xffffffff,
> +		0xcccccccc,
> +		0x33333333,
> +		0x55555555,
> +		0xaaaaaaaa,
> +		0xdeadbeef
> +	};
> +	const unsigned int num_values = ARRAY_SIZE(values);
> +	unsigned int engine =
> +		gem_class_instance_to_eb_flags(fd, e->class, e->instance);
> +	uint32_t ctx[num_values +1 ];

"+ 1"

<SNIP>

> +static unsigned int __has_context_isolation(int fd)
> +{
> +	struct drm_i915_getparam gp;
> +	int value = 0;
> +
> +	memset(&gp, 0, sizeof(gp));
> +	gp.param = 50; /* I915_PARAM_HAS_CONTEXT_ISOLATION */
> +	gp.value = &value;
> +
> +	igt_ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
> +	errno = 0;
> +
> +	return value;
> +}

<SNIP>

> +++ b/tests/gem_exec_fence.c
> @@ -698,7 +698,7 @@ static bool has_submit_fence(int fd)
>  	int value = 0;
>  
>  	memset(&gp, 0, sizeof(gp));
> -	gp.param = 50; /* I915_PARAM_HAS_EXEC_SUBMIT_FENCE */
> +	gp.param = 0xdeadbeef ^ 51; /* I915_PARAM_HAS_EXEC_SUBMIT_FENCE */
>  	gp.value = &value;
>  
>  	ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp, sizeof(gp));

Probably wan't to sort the param stuff out :)

With the params corrected, this is;

Reviewed-by: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>

Regards, Joonas
-- 
Joonas Lahtinen
Open Source Technology Center
Intel Corporation


More information about the Intel-gfx mailing list