Igt-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: "Laguna, Lukasz" <lukasz.laguna@intel.com>
To: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>,
	<igt-dev@lists.freedesktop.org>
Cc: "Adam Miszczak" <adam.miszczak@linux.intel.com>,
	"Jakub Kolakowski" <jakub1.kolakowski@intel.com>,
	"Michał Wajdeczko" <michal.wajdeczko@intel.com>,
	"Michał Winiarski" <michal.winiarski@intel.com>,
	"Narasimha C V" <narasimha.c.v@intel.com>,
	"Piotr Piórkowski" <piotr.piorkowski@intel.com>,
	"Satyanarayana K V P" <satyanarayana.k.v.p@intel.com>,
	"Tomasz Lis" <tomasz.lis@intel.com>
Subject: Re: [PATCH i-g-t 5/6] tests/intel/xe_sriov_flr: Implement clear-lmem subcheck
Date: Fri, 18 Oct 2024 09:17:20 +0200	[thread overview]
Message-ID: <2b0d697b-779b-45cd-a697-77eefe61d7c4@intel.com> (raw)
In-Reply-To: <20241009113018.741371-6-marcin.bernatowicz@linux.intel.com>


On 10/9/2024 13:30, Marcin Bernatowicz wrote:
> Add the clear-lmem subcheck to validate the isolation and clearing of a
> Virtual Function's (VF) local memory (LMEM) after a Functional Level
> Reset (FLR).
>
> The test maps the VF's LMEM, writes specific patterns to the memory,
> and checks whether the content is reset for the FLRed VF or retained
> for other VFs.
>
> Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>
> Cc: Adam Miszczak <adam.miszczak@linux.intel.com>
> Cc: Jakub Kolakowski <jakub1.kolakowski@intel.com>
> Cc: Lukasz Laguna <lukasz.laguna@intel.com>
> Cc: Michał Wajdeczko <michal.wajdeczko@intel.com>
> Cc: Michał Winiarski <michal.winiarski@intel.com>
> Cc: Narasimha C V <narasimha.c.v@intel.com>
> Cc: Piotr Piórkowski <piotr.piorkowski@intel.com>
> Cc: Satyanarayana K V P <satyanarayana.k.v.p@intel.com>
> Cc: Tomasz Lis <tomasz.lis@intel.com>
> ---
>   tests/intel/xe_sriov_flr.c | 213 ++++++++++++++++++++++++++++++++++++-
>   1 file changed, 212 insertions(+), 1 deletion(-)
>
> diff --git a/tests/intel/xe_sriov_flr.c b/tests/intel/xe_sriov_flr.c
> index 3bce235de..4c97c83a4 100644
> --- a/tests/intel/xe_sriov_flr.c
> +++ b/tests/intel/xe_sriov_flr.c
> @@ -3,6 +3,8 @@
>    * Copyright(c) 2024 Intel Corporation. All rights reserved.
>    */
>   
> +#include <fcntl.h>
> +#include <sys/stat.h>
>   #include "drmtest.h"
>   #include "igt_core.h"
>   #include "igt_sriov_device.h"
> @@ -505,12 +507,214 @@ static void ggtt_subcheck_cleanup(struct subcheck_data *data)
>   		xe_mmio_access_fini(gdata->mmio);
>   }
>   
> +struct lmem_data {
> +	struct subcheck_data base;
> +	size_t *vf_lmem_size;
> +};
> +
> +struct lmem_info {
> +	/* pointer to the mapped area */
> +	char *addr;
> +	/* size of mapped area */
> +	size_t size;
> +};
> +
> +const size_t STEP = SZ_1M;
> +
> +static void *mmap_vf_lmem(int pf_fd, int vf_num, size_t length, int prot, off_t offset)
> +{
> +	int open_flags = ((prot & PROT_WRITE) != 0) ? O_RDWR : O_RDONLY;
> +	struct stat st;
> +	int sysfs, fd;
> +	void *addr;
> +
> +	sysfs = igt_sriov_device_sysfs_open(pf_fd, vf_num);
> +	if (sysfs < 0) {
> +		igt_debug("Failed to open sysfs for VF%d: %s\n", vf_num, strerror(errno));
> +		return NULL;
> +	}
> +
> +	fd = openat(sysfs, "resource2", open_flags | O_SYNC);
> +	close(sysfs);
> +	if (fd < 0) {
> +		igt_debug("Failed to open resource2 for VF%d: %s\n", vf_num, strerror(errno));
> +		return NULL;
> +	}
> +
> +	if (fstat(fd, &st)) {
> +		igt_debug("Failed to stat resource2 for VF%d: %s\n", vf_num, strerror(errno));
> +		close(fd);
> +		return NULL;
> +	}
> +
> +	if (st.st_size < length) {
> +		igt_debug("Mapping length (%lu) exceeds BAR2 size (%lu)\n", length, st.st_size);
> +		close(fd);
> +		return NULL;
> +	}
> +
> +	addr = mmap(NULL, length, prot, MAP_SHARED, fd, offset);
> +	close(fd);
> +	if (addr == MAP_FAILED) {
> +		igt_debug("Failed mmap resource2 for VF%d: %s\n", vf_num, strerror(errno));
> +		return NULL;
> +	}
> +
> +	return addr;
> +}
> +
> +static uint64_t get_vf_lmem_size(int pf_fd, int vf_num)
> +{
> +	/* limit to first two pages */

When the debugfs with provisioned size is exposed I think we should 
check the whole LMEM. For now it's OK, but if we agree then maybe 
instead of this comment we can add "TODO: ... (e.g. use actual VF LMEM 
size)" to don't forget?

> +	return SZ_4M;
> +}
> +
> +static void munmap_vf_lmem(struct lmem_info *lmem)
> +{
> +	igt_debug_on_f(munmap(lmem->addr, lmem->size),
> +		       "Failed munmap %p: %s\n", lmem->addr, strerror(errno));
> +}
> +
> +static char lmem_read(const char *addr, size_t idx)
> +{
> +	return READ_ONCE(*(addr + idx));
> +}
> +
> +static char lmem_write_readback(char *addr, size_t idx, char value)
> +{
> +	WRITE_ONCE(*(addr + idx), value);
> +	return lmem_read(addr, idx);
> +}
> +
> +static bool lmem_write_pattern(struct lmem_info *lmem, char value, size_t start, size_t step)
> +{
> +	char read;
> +
> +	for (; start < lmem->size; start += step) {
> +		read = lmem_write_readback(lmem->addr, start, value);
> +		if (igt_debug_on_f(read != value, "LMEM[%lu]=%u != %u\n", start, read, value))
> +			return false;
> +	}
> +	return true;
> +}
> +
> +static bool lmem_contains_expected_values_(struct lmem_info *lmem,
> +					   char expected, size_t start,
> +					   size_t step)
> +{
> +	char read;
> +
> +	for (; start < lmem->size; start += step) {
> +		read = lmem_read(lmem->addr, start);
> +		if (igt_debug_on_f(read != expected,
> +				   "LMEM[%lu]=%u != %u\n", start, read, expected))
> +			return false;
> +	}
> +	return true;
> +}
> +
> +static bool lmem_contains_expected_values(int pf_fd, int vf_num, size_t length,
> +					  char expected)
> +{
> +	struct lmem_info lmem = { .size = length };
> +	bool result;
> +
> +	lmem.addr = mmap_vf_lmem(pf_fd, vf_num, length, PROT_READ | PROT_WRITE, 0);
> +	if (igt_debug_on(!lmem.addr))
> +		return false;
> +
> +	result = lmem_contains_expected_values_(&lmem, expected, 0, STEP);
> +	munmap_vf_lmem(&lmem);
> +
> +	return result;
> +}
> +
> +static bool lmem_mmap_write_munmap(int pf_fd, int vf_num, size_t length, char value)
> +{
> +	struct lmem_info lmem;
> +	bool result;
> +
> +	lmem.size = length;
> +	lmem.addr = mmap_vf_lmem(pf_fd, vf_num, length, PROT_READ | PROT_WRITE, 0);
> +	if (igt_debug_on(!lmem.addr))
> +		return false;
> +	result = lmem_write_pattern(&lmem, value, 0, STEP);
> +	munmap_vf_lmem(&lmem);
> +
> +	return result;
> +}
> +
> +static void lmem_subcheck_init(struct subcheck_data *data)
> +{
> +	struct lmem_data *ldata = (struct lmem_data *)data;
> +
> +	igt_assert_fd(data->pf_fd);
> +	igt_assert(data->num_vfs);
> +
> +	if (!xe_has_vram(data->pf_fd)) {
> +		igt_assert_neq(asprintf(&data->stop_reason,
> +					"%s : No LMEM", SKIP_REASON),
> +			       -1);
> +		return;
> +	}
> +
> +	ldata->vf_lmem_size = calloc(data->num_vfs, sizeof(size_t));
> +	igt_assert(ldata->vf_lmem_size);
> +
> +	for (int vf_id = 1; vf_id <= data->num_vfs; ++vf_id)
> +		ldata->vf_lmem_size[vf_id - 1] = get_vf_lmem_size(ldata->base.pf_fd, vf_id);
> +}
> +
> +static void lmem_subcheck_prepare_vf(int vf_id, struct subcheck_data *data)
> +{
> +	struct lmem_data *ldata = (struct lmem_data *)data;
> +
> +	if (data->stop_reason)
> +		return;
> +
> +	igt_assert(vf_id > 0 && vf_id <= data->num_vfs);
> +
> +	if (!lmem_mmap_write_munmap(data->pf_fd, vf_id,
> +				    ldata->vf_lmem_size[vf_id - 1], vf_id)) {
> +		igt_assert_neq(asprintf(&data->stop_reason,
> +					"Vram write failed on VF%u\n", vf_id),
> +			       -1);
> +	}
> +}
> +
> +static void lmem_subcheck_verify_vf(int vf_id, int flr_vf_id, struct subcheck_data *data)
> +{
> +	struct lmem_data *ldata = (struct lmem_data *)data;
> +	char expected = (vf_id == flr_vf_id) ? 0 : vf_id;
> +
> +	if (data->stop_reason)
> +		return;
> +
> +	if (!lmem_contains_expected_values(data->pf_fd, vf_id,
> +					   ldata->vf_lmem_size[vf_id - 1], expected)) {
> +		igt_assert_neq(asprintf(&data->stop_reason,
> +					"LMEM check after VF%u FLR failed on VF%u\n",
> +					flr_vf_id, vf_id),
> +			       -1);
> +	}
> +}
> +
> +static void lmem_subcheck_cleanup(struct subcheck_data *data)
> +{
> +	struct lmem_data *ldata = (struct lmem_data *)data;
> +
> +	free(ldata->vf_lmem_size);
> +}
> +
>   static void clear_tests(int pf_fd, int num_vfs)
>   {
>   	struct xe_mmio xemmio = { };
>   	const unsigned int num_gts = xe_number_gt(pf_fd);
>   	struct ggtt_data gdata[num_gts];
> -	const unsigned int num_checks = num_gts;
> +	struct lmem_data ldata = {
> +		.base = { .pf_fd = pf_fd, .num_vfs = num_vfs }
> +	};
> +	const unsigned int num_checks = num_gts + 1;
>   	struct subcheck checks[num_checks];
>   	int i;
>   
> @@ -528,6 +732,13 @@ static void clear_tests(int pf_fd, int num_vfs)
>   			.cleanup = ggtt_subcheck_cleanup
>   		};
>   	}
> +	checks[i++] = (struct subcheck) {
> +		.data = (struct subcheck_data *)&ldata,
> +		.name = "clear-lmem",
> +		.init = lmem_subcheck_init,
> +		.prepare_vf = lmem_subcheck_prepare_vf,
> +		.verify_vf = lmem_subcheck_verify_vf,
> +		.cleanup = lmem_subcheck_cleanup };
>   	igt_assert_eq(i, num_checks);
>   
>   	verify_flr(pf_fd, num_vfs, checks, num_checks);

  reply	other threads:[~2024-10-18  7:17 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-10-09 11:30 [PATCH i-g-t 0/6] Introduce xe_sriov_flr test Marcin Bernatowicz
2024-10-09 11:30 ` [PATCH i-g-t 1/6] lib/igt_sriov_device: add helper for opening SR-IOV device sysfs Marcin Bernatowicz
2024-10-14 13:34   ` Adam Miszczak
2024-10-09 11:30 ` [PATCH i-g-t 2/6] lib/igt_sriov_device: add helper for resetting SR-IOV device Marcin Bernatowicz
2024-10-14 13:37   ` Adam Miszczak
2024-10-09 11:30 ` [PATCH i-g-t 3/6] tests/intel/xe_sriov_flr: Add skeleton for clear and isolation tests Marcin Bernatowicz
2024-10-18  6:58   ` Laguna, Lukasz
2024-10-09 11:30 ` [PATCH i-g-t 4/6] tests/intel/xe_sriov_flr: Implement clear-ggtt subcheck Marcin Bernatowicz
2024-10-18  7:06   ` Laguna, Lukasz
2024-10-09 11:30 ` [PATCH i-g-t 5/6] tests/intel/xe_sriov_flr: Implement clear-lmem subcheck Marcin Bernatowicz
2024-10-18  7:17   ` Laguna, Lukasz [this message]
2024-10-09 11:30 ` [PATCH i-g-t 6/6] tests/intel/xe_sriov_flr: Implement clear-scratch-regs and clear-media-scratch-regs subchecks Marcin Bernatowicz
2024-10-10  0:04 ` ✓ CI.xeBAT: success for Introduce xe_sriov_flr test Patchwork
2024-10-10  0:13 ` ✓ Fi.CI.BAT: " Patchwork
2024-10-10 14:13 ` ✗ CI.xeFULL: failure " Patchwork
2024-10-11  6:35 ` ✗ Fi.CI.IGT: " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2b0d697b-779b-45cd-a697-77eefe61d7c4@intel.com \
    --to=lukasz.laguna@intel.com \
    --cc=adam.miszczak@linux.intel.com \
    --cc=igt-dev@lists.freedesktop.org \
    --cc=jakub1.kolakowski@intel.com \
    --cc=marcin.bernatowicz@linux.intel.com \
    --cc=michal.wajdeczko@intel.com \
    --cc=michal.winiarski@intel.com \
    --cc=narasimha.c.v@intel.com \
    --cc=piotr.piorkowski@intel.com \
    --cc=satyanarayana.k.v.p@intel.com \
    --cc=tomasz.lis@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox