[Intel-gfx] [PATCH i-g-t] tests/gem_mocs_settings: Fix LNCFCMOCS testing and extract the subtests

Kalamarz, Lukasz lukasz.kalamarz at intel.com
Fri Jun 30 12:14:10 UTC 2017


On Wed, 2017-06-28 at 17:41 +0200, Michał Winiarski wrote:
> Testing LNCFCMOCS values on non-render engines is tricky. The values
> in
> those registers are lost on RC6, which means that if users of non-
> render
> engines want to see the proper values, they need to obtain a
> forcewake
> and execute something on render (relying on it to restore the values)
> before using non-render engine.
> Previous version of the test did exactly that - we were relying on
> the
> fact that we're taking forcewake (hidden by
> intel_register_access_init,
> even though the test is not doing any mmio accesses) before iterating
> through engines (and render is before other engines, so job done).
> I really hope that this is not an ABI and those registers are not
> used
> on non-render in any way. Let's limit testing LNCFCMOCS to render
> engine only.
> The other non-render issue is that when we're using I915_EXEC_BSD, we
> can't be sure which BSD ring we'll end up executing on. Let's
> explicitly select BSD1 and BSD2 in our tests.
> While we're here, let's also remove the duplicated code and add some
> structure by extracting moving more content into subtests.
> We're only doing tests that involve "dirtying" the registers for the
> render engine - since it's the only one that has those registers in
> its
> context.
> 
> Cc: Arkadiusz Hiler <arkadiusz.hiler at intel.com>
> Cc: Chris Wilson <chris at chris-wilson.co.uk>
> Cc: David Weinehall <david.weinehall at linux.intel.com>
> Cc: Łukasz Kałamarz <lukasz.kalamarz at intel.com>
> Signed-off-by: Michał Winiarski <michal.winiarski at intel.com>

Reviewed-By: Lukasz Kalamarz <lukasz.kalamarz at intel.com>

-- 
Lukasz

> ---
>  tests/gem_mocs_settings.c | 353 ++++++++++++++--------------------
> ------------
>  1 file changed, 108 insertions(+), 245 deletions(-)
> 
> diff --git a/tests/gem_mocs_settings.c b/tests/gem_mocs_settings.c
> index a96aa66..9760c0e 100644
> --- a/tests/gem_mocs_settings.c
> +++ b/tests/gem_mocs_settings.c
> @@ -32,14 +32,28 @@
>  #include "igt_sysfs.h"
>  
>  #define MAX_NUMBER_MOCS_REGISTERS	(64)
> -
>  enum {
>  	NONE,
>  	RESET,
> +	RC6,
>  	SUSPEND,
> -	HIBERNATE
> +	HIBERNATE,
> +	MAX_MOCS_TEST_MODES
> +};
> +
> +static const char * const test_modes[] = {
> +	[NONE] = "settings",
> +	[RESET] = "reset",
> +	[RC6] = "rc6",
> +	[SUSPEND] = "suspend",
> +	[HIBERNATE] = "hibernate"
>  };
>  
> +#define MOCS_NON_DEFAULT_CTX	(1<<0)
> +#define MOCS_DIRTY_VALUES	(1<<1)
> +#define ALL_MOCS_FLAGS		(MOCS_NON_DEFAULT_CTX | \
> +				 MOCS_DIRTY_VALUES)
> +
>  #define GEN9_LNCFCMOCS0		(0xB020)	/* L3 Cache
> Control base */
>  #define GEN9_GFX_MOCS_0		(0xc800)	/* Graphics
> MOCS base register*/
>  #define GEN9_MFX0_MOCS_0	(0xc900)	/* Media 0 MOCS base
> register*/
> @@ -117,19 +131,18 @@ static bool get_mocs_settings(int fd, struct
> mocs_table *table, bool dirty)
>  	return result;
>  }
>  
> +#define LOCAL_I915_EXEC_BSD1 (I915_EXEC_BSD | (1<<13))
> +#define LOCAL_I915_EXEC_BSD2 (I915_EXEC_BSD | (2<<13))
> +
>  static uint32_t get_engine_base(uint32_t engine)
>  {
> -	/* Note we cannot test BSD1 or BSD2 due to limitations of
> current ANI */
>  	switch (engine) {
> -	case I915_EXEC_BSD:	return GEN9_MFX0_MOCS_0;
> -/*
> -	case I915_EXEC_BSD1:	return GEN9_MFX0_MOCS_0;
> -	case I915_EXEC_BSD2:	return GEN9_MFX1_MOCS_0;
> -*/
> -	case I915_EXEC_RENDER:	return GEN9_GFX_MOCS_0;
> -	case I915_EXEC_BLT:	return GEN9_BLT_MOCS_0;
> -	case I915_EXEC_VEBOX:	return GEN9_VEBOX_MOCS_0;
> -	default:		return 0;
> +	case LOCAL_I915_EXEC_BSD1:	return GEN9_MFX0_MOCS_0;
> +	case LOCAL_I915_EXEC_BSD2:	return GEN9_MFX1_MOCS_0;
> +	case I915_EXEC_RENDER:		return
> GEN9_GFX_MOCS_0;
> +	case I915_EXEC_BLT:		return GEN9_BLT_MOCS_0;
> +	case I915_EXEC_VEBOX:		return
> GEN9_VEBOX_MOCS_0;
> +	default:			return 0;
>  	}
>  }
>  
> @@ -252,7 +265,7 @@ static void check_control_registers(int fd,
>  				    uint32_t ctx_id,
>  				    bool dirty)
>  {
> -	const uint32_t reg_base  = get_engine_base(engine);
> +	const uint32_t reg_base = get_engine_base(engine);
>  	uint32_t dst_handle = gem_create(fd, 4096);
>  	uint32_t *read_regs;
>  	struct mocs_table table;
> @@ -299,6 +312,7 @@ static void check_l3cc_registers(int fd,
>  	read_regs = gem_mmap__cpu(fd, dst_handle, 0, 4096,
> PROT_READ);
>  
>  	gem_set_domain(fd, dst_handle, I915_GEM_DOMAIN_CPU, 0);
> +
>  	for (index = 0; index < table.size / 2; index++) {
>  		igt_assert_eq_u32(read_regs[index] & 0xffff,
>  				  table.table[index *
> 2].l3cc_value);
> @@ -314,183 +328,65 @@ static void check_l3cc_registers(int fd,
>  	gem_close(fd, dst_handle);
>  }
>  
> -static void test_context_mocs_values(int fd, unsigned engine)
> -{
> -	int local_fd;
> -	uint32_t ctx_id = 0;
> -
> -	local_fd = fd;
> -	if (local_fd == -1)
> -		local_fd = drm_open_driver_master(DRIVER_INTEL);
> -
> -	check_control_registers(local_fd, engine, ctx_id, false);
> -	check_l3cc_registers(local_fd, engine, ctx_id, false);
> -
> -	if (engine == I915_EXEC_RENDER) {
> -		ctx_id = gem_context_create(local_fd);
> -
> -		check_control_registers(local_fd, engine, ctx_id,
> false);
> -		check_l3cc_registers(local_fd, engine, ctx_id,
> false);
> -
> -		gem_context_destroy(local_fd, ctx_id);
> -	}
> -
> -	if (local_fd != fd)
> -		close(local_fd);
> -}
>  
> -static bool local_has_ring(int fd, unsigned engine)
> +static uint32_t rc6_residency(int dir)
>  {
> -	bool has_ring;
> -	int local_fd;
> -
> -	if (get_engine_base(engine) == 0)
> -		return false;
> -
> -	if (fd == -1)
> -		local_fd = drm_open_driver_master(DRIVER_INTEL);
> -	else
> -		local_fd = fd;
> -
> -	has_ring = gem_has_ring(local_fd, engine);
> -	if (local_fd != fd)
> -		close(local_fd);
> -
> -	return has_ring;
> +	return igt_sysfs_get_u32(dir, "power/rc6_residency_ms");
>  }
>  
> -static void test_mocs_values(int fd)
> +static void rc6_wait(int fd)
>  {
> -	const struct intel_execution_engine *e;
> +	int sysfs;
> +	uint32_t residency;
>  
> -	for (e = intel_execution_engines; e->name; e++) {
> -		unsigned engine = e->exec_id | e->flags;
> +	sysfs = igt_sysfs_open(fd, NULL);
> +	igt_assert_lte(0, sysfs);
>  
> -		if (!local_has_ring(fd, engine))
> -			continue;
> +	residency = rc6_residency(sysfs);
> +	igt_require(igt_wait(rc6_residency(sysfs) != residency,
> 10000, 2));
>  
> -		igt_debug("Testing %s\n", e->name);
> -		test_context_mocs_values(fd, engine);
> -	}
> +	close(sysfs);
>  }
>  
> -static void default_context_tests(unsigned mode)
> +static void check_mocs_values(int fd, unsigned engine, uint32_t
> ctx_id, bool dirty)
>  {
> -	int fd = drm_open_driver_master(DRIVER_INTEL);
> +	check_control_registers(fd, engine, ctx_id, dirty);
>  
> -	igt_debug("Testing Non/Default Context Engines\n");
> -	test_mocs_values(fd);
> -
> -	switch (mode) {
> -	case NONE:	break;
> -	case RESET:	igt_force_gpu_reset(fd);	break;
> -	case SUSPEND:	igt_system_suspend_autoresume(SUSPEND_S
> TATE_MEM,
> -						      SUSPEND_TEST_N
> ONE); break;
> -	case HIBERNATE:	igt_system_suspend_autoresume(SUSPEND
> _STATE_DISK,
> -						      SUSPEND_TEST_N
> ONE); break;
> -	}
> -
> -	test_mocs_values(fd);
> -	close(fd);
> -
> -	igt_debug("Testing Pristine Defaults\n");
> -	test_mocs_values(-1);
> +	if (engine == I915_EXEC_RENDER)
> +		check_l3cc_registers(fd, engine, ctx_id, dirty);
>  }
>  
> -static void default_dirty_tests(unsigned mode)
> +static void write_dirty_mocs(int fd, unsigned engine, uint32_t
> ctx_id)
>  {
> -	const struct intel_execution_engine *e;
> -	int fd = drm_open_driver_master(DRIVER_INTEL);
> -
> -	igt_debug("Testing Dirty Default Context Engines\n");
> -	test_mocs_values(fd);
> -
> -	for (e = intel_execution_engines; e->name; e++) {
> -		unsigned engine = e->exec_id | e->flags;
> +	write_registers(fd, ctx_id, get_engine_base(engine),
> +			write_values, ARRAY_SIZE(write_values),
> +			engine);
>  
> -		if (!local_has_ring(fd, engine))
> -			continue;
> -
> -		write_registers(fd, 0,
> -				GEN9_GFX_MOCS_0,
> +	if (engine == I915_EXEC_RENDER)
> +		write_registers(fd, ctx_id, GEN9_LNCFCMOCS0,
>  				write_values,
> ARRAY_SIZE(write_values),
>  				engine);
> -
> -		write_registers(fd, 0,
> -				GEN9_LNCFCMOCS0,
> -				write_values,
> ARRAY_SIZE(write_values),
> -				engine);
> -	}
> -
> -	switch (mode) {
> -	case NONE:	break;
> -	case RESET:	igt_force_gpu_reset(fd);	break;
> -	case SUSPEND:	igt_system_suspend_autoresume(SUSPEND_S
> TATE_MEM,
> -						      SUSPEND_TEST_N
> ONE); break;
> -	case HIBERNATE:	igt_system_suspend_autoresume(SUSPEND
> _STATE_DISK,
> -						      SUSPEND_TEST_N
> ONE); break;
> -	}
> -
> -	close(fd);
> -
> -	igt_debug("Testing Pristine after Dirty Defaults\n");
> -	test_mocs_values(-1);
>  }
>  
> -static void context_save_restore_test(unsigned mode)
> +static void run_test(int fd, unsigned engine, unsigned flags,
> unsigned mode)
>  {
> -	int fd = drm_open_driver_master(DRIVER_INTEL);
> -	uint32_t ctx_id = gem_context_create(fd);
> +	uint32_t ctx_id = 0;
> +	uint32_t ctx_clean_id;
> +	uint32_t ctx_dirty_id;
>  
> -	igt_debug("Testing Save Restore\n");
> +	/* Skip if we don't know where the registers are for this
> engine */
> +	igt_require(get_engine_base(engine));
>  
> -	check_control_registers(fd, I915_EXEC_RENDER, ctx_id,
> false);
> -	check_l3cc_registers(fd, I915_EXEC_RENDER, ctx_id, false);
> +	if (flags & MOCS_NON_DEFAULT_CTX)
> +		ctx_id = gem_context_create(fd);
>  
> -	switch (mode) {
> -	case NONE:	break;
> -	case RESET:	igt_force_gpu_reset(fd);	break;
> -	case SUSPEND:	igt_system_suspend_autoresume(SUSPEND_S
> TATE_MEM,
> -						      SUSPEND_TEST_N
> ONE); break;
> -	case HIBERNATE:	igt_system_suspend_autoresume(SUSPEND
> _STATE_DISK,
> -						      SUSPEND_TEST_N
> ONE); break;
> +	if (flags & MOCS_DIRTY_VALUES) {
> +		ctx_dirty_id = gem_context_create(fd);
> +		write_dirty_mocs(fd, engine, ctx_dirty_id);
> +		check_mocs_values(fd, engine, ctx_dirty_id, true);
>  	}
>  
> -	check_control_registers(fd, I915_EXEC_RENDER, ctx_id,
> false);
> -	check_l3cc_registers(fd, I915_EXEC_RENDER, ctx_id, false);
> -
> -	close(fd);
> -}
> -
> -static void context_dirty_test(unsigned mode)
> -{
> -	int fd = drm_open_driver_master(DRIVER_INTEL);
> -	uint32_t ctx_id = gem_context_create(fd);
> -
> -	igt_debug("Testing Dirty Context\n");
> -	test_mocs_values(fd);
> -
> -	check_control_registers(fd, I915_EXEC_RENDER, ctx_id,
> false);
> -	check_l3cc_registers(fd, I915_EXEC_RENDER, ctx_id, false);
> -
> -	/* XXX !RCS as well */
> -
> -	write_registers(fd,
> -			ctx_id,
> -			GEN9_GFX_MOCS_0,
> -			write_values,
> -			ARRAY_SIZE(write_values),
> -			I915_EXEC_RENDER);
> -
> -	write_registers(fd,
> -			ctx_id,
> -			GEN9_LNCFCMOCS0,
> -			write_values,
> -			ARRAY_SIZE(write_values),
> -			I915_EXEC_RENDER);
> -
> -	check_control_registers(fd, I915_EXEC_RENDER, ctx_id, true);
> -	check_l3cc_registers(fd, I915_EXEC_RENDER, ctx_id, true);
> +	check_mocs_values(fd, engine, ctx_id, false);
>  
>  	switch (mode) {
>  	case NONE:	break;
> @@ -499,99 +395,66 @@ static void context_dirty_test(unsigned mode)
>  						      SUSPEND_TEST_N
> ONE); break;
>  	case HIBERNATE:	igt_system_suspend_autoresume(SUSPEND
> _STATE_DISK,
>  						      SUSPEND_TEST_N
> ONE); break;
> +	case RC6:	rc6_wait(fd);			break;
>  	}
>  
> -	check_control_registers(fd, I915_EXEC_RENDER, ctx_id, true);
> -	check_l3cc_registers(fd, I915_EXEC_RENDER, ctx_id, true);
> -
> -	close(fd);
> -
> -	/* Check that unmodified contexts are pristine */
> -	igt_debug("Testing Prestine Context (after dirty)\n");
> -	test_mocs_values(-1);
> -}
> -
> -static void run_tests(unsigned mode)
> -{
> -	struct pci_device *pci_dev;
> -	int fd;
> -
> -	pci_dev = intel_get_pci_device();
> -	igt_require(pci_dev);
> -
> -	fd = drm_open_driver_master(DRIVER_INTEL);
> -	intel_register_access_init(pci_dev, 0, fd);
> -	close(fd);
> -
> -	default_context_tests(mode);
> -	default_dirty_tests(mode);
> -	context_save_restore_test(mode);
> -	context_dirty_test(mode);
> +	check_mocs_values(fd, engine, ctx_id, false);
>  
> -	intel_register_access_fini();
> -}
> -
> -static int rc6_residency(int dir)
> -{
> -	return igt_sysfs_get_u32(dir, "power/rc6_residency_ms");
> -}
> -
> -static void context_rc6_test(void)
> -{
> -	int fd = drm_open_driver(DRIVER_INTEL);
> -	uint32_t ctx_id = gem_context_create(fd);
> -	int residency;
> -	int timeout;
> -	int sysfs;
> -
> -	igt_debug("RC6 Context Test\n");
> -	check_control_registers(fd, I915_EXEC_RENDER, ctx_id,
> false);
> -	check_l3cc_registers(fd, I915_EXEC_RENDER, ctx_id, false);
> -
> -	sysfs = igt_sysfs_open(fd, NULL);
> -
> -	timeout = 3000 / 2;
> -	residency = rc6_residency(sysfs);
> -	while (rc6_residency(sysfs) == residency && --timeout)
> -		usleep(2000);
> -	igt_require(timeout);
> -
> -	close(sysfs);
> +	if (flags & MOCS_DIRTY_VALUES) {
> +		ctx_clean_id = gem_context_create(fd);
> +		check_mocs_values(fd, engine, ctx_dirty_id, true);
> +		check_mocs_values(fd, engine, ctx_clean_id, false);
> +		gem_context_destroy(fd, ctx_dirty_id);
> +		gem_context_destroy(fd, ctx_clean_id);
> +	}
>  
> -	check_control_registers(fd, I915_EXEC_RENDER, ctx_id,
> false);
> -	check_l3cc_registers(fd, I915_EXEC_RENDER, ctx_id, false);
> -	close(fd);
> +	if (ctx_id)
> +		gem_context_destroy(fd, ctx_id);
>  }
>  
> -
> -static void test_requirements(void)
> +igt_main
>  {
> -	int fd = drm_open_driver_master(DRIVER_INTEL);
> +	const struct intel_execution_engine *e;
>  	struct mocs_table table;
> +	int fd = -1;
>  
> -	gem_require_mocs_registers(fd);
> -	igt_require(get_mocs_settings(fd, &table, false));
> -	close(fd);
> -}
> -
> -igt_main
> -{
>  	igt_fixture {
> -		test_requirements();
> +		fd = drm_open_driver(DRIVER_INTEL);
> +		igt_require_gem(fd);
> +		gem_require_mocs_registers(fd);
> +		igt_require(get_mocs_settings(fd, &table, false));
>  	}
>  
> -	igt_subtest("mocs-settings")
> -		run_tests(NONE);
> -
> -	igt_subtest("mocs-rc6")
> -		context_rc6_test();
> -
> -	igt_subtest("mocs-reset")
> -		run_tests(RESET);
> +	for (e = intel_execution_engines; e->name; e++) {
> +		/* We don't know which engine will be assigned to us
> if we're
> +		 * using plain I915_EXEC_BSD, I915_EXEC_DEFAULT is
> just
> +		 * duplicating render
> +		 */
> +		if (e->exec_id == I915_EXEC_BSD ||
> +		    e->exec_id == I915_EXEC_DEFAULT)
> +			continue;
>  
> -	igt_subtest("mocs-suspend")
> -		run_tests(SUSPEND);
> +		for (unsigned mode = NONE; mode <
> MAX_MOCS_TEST_MODES; mode++) {
> +			for (unsigned flags = 0; flags <
> ALL_MOCS_FLAGS + 1; flags++) {
> +				/* Trying to test non-render engines
> for dirtying MOCS
> +				 * values from one context having
> effect on different
> +				 * context is bound to fail - only
> render engine is
> +				 * doing context save/restore of
> MOCS registers
> +				 */
> +				if (flags & MOCS_DIRTY_VALUES && e-
> >exec_id != I915_EXEC_RENDER)
> +					continue;
> +
> +				igt_subtest_f("mocs-%s%s%s-%s",
> +					      test_modes[mode],
> +					      flags &
> MOCS_NON_DEFAULT_CTX ? "-ctx": "",
> +					      flags &
> MOCS_DIRTY_VALUES ? "-dirty" : "",
> +					      e->name) {
> +					run_test(fd, e->exec_id | e-
> >flags, flags, mode);
> +				}
> +			}
> +		}
> +	}
>  
> -	igt_subtest("mocs-hibernate")
> -		run_tests(HIBERNATE);
> +	igt_fixture
> +		close(fd);
>  }


More information about the Intel-gfx mailing list