All of lore.kernel.org
 help / color / mirror / Atom feed
* [igt-dev] [RFC,i-g-t] tests/device_reset: Test device sysfs reset
@ 2020-06-26  6:30 Marcin Bernatowicz
  2020-06-26  8:47 ` [igt-dev] [RFC, i-g-t] " Katarzyna Dec
  2020-06-26 13:49 ` [igt-dev] ✓ Fi.CI.BAT: success for " Patchwork
  0 siblings, 2 replies; 9+ messages in thread
From: Marcin Bernatowicz @ 2020-06-26  6:30 UTC (permalink / raw)
  To: igt-dev; +Cc: michal.winiarski, rodrigo.vivi, marcin.bernatowicz

Device reset is initiated by writing "1" to reset sysfs file,
which should initiatie device FLR if supported by device.

Test scenarios:
1. unbind driver from device then rebind
2. unbind driver from device, initiate sysfs reset, rebind driver to
device
3. device reset with bound driver

Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@intel.com>
---
 tests/device_reset.c | 298 +++++++++++++++++++++++++++++++++++++++++++
 tests/meson.build    |   1 +
 2 files changed, 299 insertions(+)
 create mode 100644 tests/device_reset.c

diff --git a/tests/device_reset.c b/tests/device_reset.c
new file mode 100644
index 000000000..bafe9fd41
--- /dev/null
+++ b/tests/device_reset.c
@@ -0,0 +1,298 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright(c) 2020 Intel Corporation. All rights reserved.
+ */
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include "igt.h"
+#include "igt_device_scan.h"
+#include "igt_sysfs.h"
+
+IGT_TEST_DESCRIPTION("Examine behavior of a driver on device sysfs reset");
+
+
+#define DEV_PATH_LEN 80
+#define DEV_BUS_ADDR_LEN 13 /* addr has form 0000:00:00.0 */
+
+/**
+ * Helper structure containing sysfs file descriptors
+ * and path related to tested device
+ */
+struct sysfs_fds {
+	struct {
+		int dev;
+		int dev_dir;
+		int drv_dir;
+	} fds;
+	char dev_bus_addr[DEV_BUS_ADDR_LEN];
+};
+
+static int __open_sysfs_dir(int fd, const char* path)
+{
+	int sysfs;
+
+	sysfs = igt_sysfs_open(fd);
+	if (sysfs < 0) {
+		return -1;
+	}
+
+	return openat(sysfs, path, O_DIRECTORY);
+}
+
+static int open_device_sysfs_dir(int fd)
+{
+	return __open_sysfs_dir(fd, "device");
+}
+
+static int open_driver_sysfs_dir(int fd)
+{
+	return __open_sysfs_dir(fd, "device/driver");
+}
+
+/**
+ * device_sysfs_path:
+ * @fd: opened device file descriptor
+ * @path: buffer to store sysfs path to device directory
+ *
+ * Returns:
+ * On successfull path resolution sysfs path to device directory,
+ * NULL otherwise
+ */
+static char *device_sysfs_path(int fd, char *path)
+{
+	char sysfs[DEV_PATH_LEN];
+
+	if (!igt_sysfs_path(fd, sysfs, sizeof(sysfs)))
+		return NULL;
+
+	if (DEV_PATH_LEN <= (strlen(sysfs) + strlen("/device")))
+		return NULL;
+
+	strcat(sysfs, "/device");
+
+	return realpath(sysfs, path);
+}
+
+static void init_sysfs_fds(struct sysfs_fds *sysfs)
+{
+	char dev_path[PATH_MAX];
+	char *addr_pos;
+
+	igt_debug("open device\n");
+	/**
+	 * As subtests must be able to close examined devices
+	 * completely, don't use drm_open_driver() as it keeps
+	 * a device file descriptor open for exit handler use.
+	 */
+	sysfs->fds.dev = __drm_open_driver(DRIVER_ANY);
+	igt_assert_fd(sysfs->fds.dev);
+
+	igt_assert(device_sysfs_path(sysfs->fds.dev, dev_path));
+	addr_pos = strrchr(dev_path, '/');
+	snprintf(sysfs->dev_bus_addr, sizeof(sysfs->dev_bus_addr),
+		 "%s", (addr_pos ? addr_pos + 1 : ""));
+	igt_assert(sysfs->dev_bus_addr[0]);
+
+	sysfs->fds.dev_dir = open_device_sysfs_dir(sysfs->fds.dev);
+	igt_assert_fd(sysfs->fds.dev_dir);
+
+	sysfs->fds.drv_dir = open_driver_sysfs_dir(sysfs->fds.dev);
+	igt_assert_fd(sysfs->fds.drv_dir);
+}
+
+static int close_if_opened(int *fd)
+{
+	int rc = 0;
+	if (fd && *fd != -1) {
+		rc = close(*fd);
+		*fd = -1;
+	}
+	return rc;
+}
+
+static void open_if_closed(struct sysfs_fds *sysfs)
+{
+	if (sysfs->fds.dev == -1) {
+		/* refresh device list */
+		igt_devices_scan(true);
+		igt_debug("reopen the device\n");
+		sysfs->fds.dev = __drm_open_driver(DRIVER_ANY);
+	}
+	igt_assert_fd(sysfs->fds.dev);
+}
+
+static void cleanup_sysfs_fds(struct sysfs_fds *sysfs)
+{
+	close_if_opened(&sysfs->fds.dev);
+	close_if_opened(&sysfs->fds.dev_dir);
+	close_if_opened(&sysfs->fds.drv_dir);
+	sysfs->dev_bus_addr[0] = '\0';
+}
+
+
+/**
+ * is_sysfs_reset_supported:
+ * @fd: opened device file descriptor
+ *
+ * Check if device supports reset based on sysfs file presence.
+ *
+ * Returns:
+ * True if device supports reset, false otherwise.
+ */
+static bool is_sysfs_reset_supported(int fd)
+{
+	struct stat st;
+	int rc;
+	int sysfs;
+	int reset_fd = -1;
+
+	sysfs = igt_sysfs_open(fd);
+
+	if (sysfs >= 0) {
+		reset_fd = openat(sysfs, "device/reset", O_WRONLY);
+		close(sysfs);
+	}
+
+	if (reset_fd < 0)
+		return false;
+
+	rc = fstat(reset_fd, &st);
+	close(reset_fd);
+
+	if (rc || !S_ISREG(st.st_mode))
+		return false;
+
+	return true;
+}
+
+/* Unbind the driver from the device */
+static void driver_unbind(struct sysfs_fds *sysfs)
+{
+	igt_debug("unbind the driver from the device\n");
+	igt_assert(igt_sysfs_set(sysfs->fds.drv_dir, "unbind",
+		   sysfs->dev_bus_addr));
+}
+
+/* Re-bind the driver to the device */
+static void driver_bind(struct sysfs_fds *sysfs)
+{
+	igt_debug("rebind the driver to the device\n");
+	igt_abort_on_f(!igt_sysfs_set(sysfs->fds.drv_dir, "bind",
+		       sysfs->dev_bus_addr), "driver rebind failed");
+}
+
+/* Initiate device reset */
+static void initiate_device_reset(struct sysfs_fds *sysfs)
+{
+	igt_debug("reset device\n");
+	igt_assert(igt_sysfs_set(sysfs->fds.dev_dir, "reset", "1"));
+}
+
+/**
+ * healthcheck:
+ * @sysfs: structure with device descriptor, if descriptor equals -1
+ * 	   the device is reopened
+ */
+static void healthcheck(struct sysfs_fds *sysfs)
+{
+	open_if_closed(sysfs);
+	gem_test_engine(sysfs->fds.dev, ALL_ENGINES);
+}
+
+/**
+ * set_device_filter:
+ *
+ * Sets device filter to ensure subtests always reopen the same device
+ *
+ * @dev_path: path to device under tests
+ */
+static void set_device_filter(const char* dev_path)
+{
+	char filter[strlen("sys:") + strlen(dev_path) + 1];
+
+	snprintf(filter, sizeof(filter), "sys:%s", dev_path);
+	igt_device_filter_free_all();
+	igt_assert_eq(igt_device_filter_add(filter), 1);
+}
+
+static void unbind_rebind(struct sysfs_fds *sysfs)
+{
+	igt_debug("close the device\n");
+	close_if_opened(&sysfs->fds.dev);
+
+	driver_unbind(sysfs);
+
+	driver_bind(sysfs);
+}
+
+static void unbind_reset_rebind(struct sysfs_fds *sysfs)
+{
+	igt_debug("close the device\n");
+	close_if_opened(&sysfs->fds.dev);
+
+	driver_unbind(sysfs);
+
+	initiate_device_reset(sysfs);
+
+	driver_bind(sysfs);
+}
+
+igt_main
+{
+	struct sysfs_fds sysfs;
+
+	igt_fixture {
+		char dev_path[PATH_MAX];
+
+		igt_debug("opening device\n");
+		init_sysfs_fds(&sysfs);
+
+		/* Make sure subtests always reopen the same device */
+		igt_assert(device_sysfs_path(sysfs.fds.dev, dev_path));
+		set_device_filter(dev_path);
+
+		igt_skip_on(!is_sysfs_reset_supported(sysfs.fds.dev));
+
+		igt_set_timeout(60, "device reset tests timed out after 60s");
+	}
+
+	igt_describe("Tests driver unbind from/rebind to device sequence");
+	igt_subtest("unbind-rebind")
+		unbind_rebind(&sysfs);
+
+	igt_describe("Unbinds driver from device, initiates reset"
+		     " then rebinds driver to device");
+	igt_subtest("unbind-reset-rebind")
+		unbind_reset_rebind(&sysfs);
+
+	igt_describe("Resets device with bound driver");
+	igt_subtest("reset-bound")
+		initiate_device_reset(&sysfs);
+
+	igt_describe("Subtests with additional healthchecks");
+	igt_subtest_group {
+		igt_fixture {
+			open_if_closed(&sysfs);
+			igt_require_intel(sysfs.fds.dev);
+		}
+
+		igt_subtest("healthcheck")
+			healthcheck(&sysfs);
+
+		igt_subtest("unbind-reset-rebind-healthcheck") {
+			unbind_reset_rebind(&sysfs);
+			healthcheck(&sysfs);
+		}
+
+		igt_subtest("reset-bound-healthcheck") {
+			initiate_device_reset(&sysfs);
+			healthcheck(&sysfs);
+		}
+	}
+
+	igt_fixture {
+		igt_reset_timeout();
+		cleanup_sysfs_fds(&sysfs);
+	}
+}
diff --git a/tests/meson.build b/tests/meson.build
index 28091794f..b0acdf7c0 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -8,6 +8,7 @@ test_progs = [
 	'core_setmaster_vs_auth',
 	'debugfs_test',
 	'dmabuf',
+	'device_reset',
 	'drm_import_export',
 	'drm_mm',
 	'drm_read',
-- 
2.25.1

---------------------------------------------------------------------
Intel Technology Poland sp. z o.o.
ul. Sowackiego 173 | 80-298 Gdask | Sd Rejonowy Gdask Pnoc | VII Wydzia Gospodarczy Krajowego Rejestru Sdowego - KRS 101882 | NIP 957-07-52-316 | Kapita zakadowy 200.000 PLN.
Ta wiadomo wraz z zacznikami jest przeznaczona dla okrelonego adresata i moe zawiera informacje poufne. W razie przypadkowego otrzymania tej wiadomoci, prosimy o powiadomienie nadawcy oraz trwae jej usunicie; jakiekolwiek przegldanie lub rozpowszechnianie jest zabronione.
This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). If you are not the intended recipient, please contact the sender and delete all copies; any review or distribution by others is strictly prohibited.
 

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [igt-dev] [RFC, i-g-t] tests/device_reset: Test device sysfs reset
  2020-06-26  6:30 [igt-dev] [RFC,i-g-t] tests/device_reset: Test device sysfs reset Marcin Bernatowicz
@ 2020-06-26  8:47 ` Katarzyna Dec
  2020-06-26  8:55   ` Bernatowicz, Marcin
  2020-06-26 13:49 ` [igt-dev] ✓ Fi.CI.BAT: success for " Patchwork
  1 sibling, 1 reply; 9+ messages in thread
From: Katarzyna Dec @ 2020-06-26  8:47 UTC (permalink / raw)
  To: Marcin Bernatowicz, igt-dev; +Cc: michal.winiarski, rodrigo.vivi

On Fri, Jun 26, 2020 at 08:30:45AM +0200, Marcin Bernatowicz wrote:
> Device reset is initiated by writing "1" to reset sysfs file,
> which should initiatie device FLR if supported by device.
> 
> Test scenarios:
> 1. unbind driver from device then rebind
> 2. unbind driver from device, initiate sysfs reset, rebind driver to
> device
> 3. device reset with bound driver
> 
> Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@intel.com>
> ---
>  tests/device_reset.c | 298 +++++++++++++++++++++++++++++++++++++++++++
>  tests/meson.build    |   1 +
>  2 files changed, 299 insertions(+)
>  create mode 100644 tests/device_reset.c
> 
> diff --git a/tests/device_reset.c b/tests/device_reset.c
> new file mode 100644
> index 000000000..bafe9fd41
> --- /dev/null
> +++ b/tests/device_reset.c
> @@ -0,0 +1,298 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright(c) 2020 Intel Corporation. All rights reserved.
> + */
> +
> +#include <fcntl.h>
> +#include <sys/stat.h>
> +#include "igt.h"
> +#include "igt_device_scan.h"
> +#include "igt_sysfs.h"
> +
> +IGT_TEST_DESCRIPTION("Examine behavior of a driver on device sysfs reset");
> +
> +
> +#define DEV_PATH_LEN 80
> +#define DEV_BUS_ADDR_LEN 13 /* addr has form 0000:00:00.0 */
> +
> +/**
> + * Helper structure containing sysfs file descriptors
> + * and path related to tested device
> + */
> +struct sysfs_fds {
> +	struct {
> +		int dev;
> +		int dev_dir;
> +		int drv_dir;
> +	} fds;
> +	char dev_bus_addr[DEV_BUS_ADDR_LEN];
> +};
> +
> +static int __open_sysfs_dir(int fd, const char* path)
> +{
> +	int sysfs;
> +
> +	sysfs = igt_sysfs_open(fd);
> +	if (sysfs < 0) {
> +		return -1;
> +	}
> +
> +	return openat(sysfs, path, O_DIRECTORY);
> +}
> +
> +static int open_device_sysfs_dir(int fd)
> +{
> +	return __open_sysfs_dir(fd, "device");
> +}
> +
> +static int open_driver_sysfs_dir(int fd)
> +{
> +	return __open_sysfs_dir(fd, "device/driver");
> +}
> +
> +/**
> + * device_sysfs_path:
> + * @fd: opened device file descriptor
> + * @path: buffer to store sysfs path to device directory
> + *
> + * Returns:
> + * On successfull path resolution sysfs path to device directory,
> + * NULL otherwise
> + */
> +static char *device_sysfs_path(int fd, char *path)
> +{
> +	char sysfs[DEV_PATH_LEN];
> +
> +	if (!igt_sysfs_path(fd, sysfs, sizeof(sysfs)))
> +		return NULL;
> +
> +	if (DEV_PATH_LEN <= (strlen(sysfs) + strlen("/device")))
> +		return NULL;
> +
> +	strcat(sysfs, "/device");
> +
> +	return realpath(sysfs, path);
> +}
> +
> +static void init_sysfs_fds(struct sysfs_fds *sysfs)
> +{
> +	char dev_path[PATH_MAX];
> +	char *addr_pos;
> +
> +	igt_debug("open device\n");
> +	/**
> +	 * As subtests must be able to close examined devices
> +	 * completely, don't use drm_open_driver() as it keeps
> +	 * a device file descriptor open for exit handler use.
> +	 */
> +	sysfs->fds.dev = __drm_open_driver(DRIVER_ANY);
> +	igt_assert_fd(sysfs->fds.dev);
> +
> +	igt_assert(device_sysfs_path(sysfs->fds.dev, dev_path));
> +	addr_pos = strrchr(dev_path, '/');
> +	snprintf(sysfs->dev_bus_addr, sizeof(sysfs->dev_bus_addr),
> +		 "%s", (addr_pos ? addr_pos + 1 : ""));
> +	igt_assert(sysfs->dev_bus_addr[0]);
> +
> +	sysfs->fds.dev_dir = open_device_sysfs_dir(sysfs->fds.dev);
> +	igt_assert_fd(sysfs->fds.dev_dir);
> +
> +	sysfs->fds.drv_dir = open_driver_sysfs_dir(sysfs->fds.dev);
> +	igt_assert_fd(sysfs->fds.drv_dir);
> +}
> +
> +static int close_if_opened(int *fd)
> +{
> +	int rc = 0;
> +	if (fd && *fd != -1) {
> +		rc = close(*fd);
> +		*fd = -1;
> +	}
> +	return rc;
> +}
> +
> +static void open_if_closed(struct sysfs_fds *sysfs)
> +{
> +	if (sysfs->fds.dev == -1) {
> +		/* refresh device list */
> +		igt_devices_scan(true);
> +		igt_debug("reopen the device\n");
> +		sysfs->fds.dev = __drm_open_driver(DRIVER_ANY);
> +	}
> +	igt_assert_fd(sysfs->fds.dev);
> +}
> +
> +static void cleanup_sysfs_fds(struct sysfs_fds *sysfs)
> +{
> +	close_if_opened(&sysfs->fds.dev);
> +	close_if_opened(&sysfs->fds.dev_dir);
> +	close_if_opened(&sysfs->fds.drv_dir);
> +	sysfs->dev_bus_addr[0] = '\0';
> +}
> +
> +
> +/**
> + * is_sysfs_reset_supported:
> + * @fd: opened device file descriptor
> + *
> + * Check if device supports reset based on sysfs file presence.
> + *
> + * Returns:
> + * True if device supports reset, false otherwise.
> + */
> +static bool is_sysfs_reset_supported(int fd)
> +{
> +	struct stat st;
> +	int rc;
> +	int sysfs;
> +	int reset_fd = -1;
> +
> +	sysfs = igt_sysfs_open(fd);
> +
> +	if (sysfs >= 0) {
> +		reset_fd = openat(sysfs, "device/reset", O_WRONLY);
> +		close(sysfs);
> +	}
> +
> +	if (reset_fd < 0)
> +		return false;
> +
> +	rc = fstat(reset_fd, &st);
> +	close(reset_fd);
> +
> +	if (rc || !S_ISREG(st.st_mode))
> +		return false;
> +
> +	return true;
> +}
> +
> +/* Unbind the driver from the device */
> +static void driver_unbind(struct sysfs_fds *sysfs)
> +{
> +	igt_debug("unbind the driver from the device\n");
> +	igt_assert(igt_sysfs_set(sysfs->fds.drv_dir, "unbind",
> +		   sysfs->dev_bus_addr));
> +}
> +
> +/* Re-bind the driver to the device */
> +static void driver_bind(struct sysfs_fds *sysfs)
> +{
> +	igt_debug("rebind the driver to the device\n");
> +	igt_abort_on_f(!igt_sysfs_set(sysfs->fds.drv_dir, "bind",
> +		       sysfs->dev_bus_addr), "driver rebind failed");
> +}
> +
> +/* Initiate device reset */
> +static void initiate_device_reset(struct sysfs_fds *sysfs)
> +{
> +	igt_debug("reset device\n");
> +	igt_assert(igt_sysfs_set(sysfs->fds.dev_dir, "reset", "1"));
> +}
> +
> +/**
> + * healthcheck:
> + * @sysfs: structure with device descriptor, if descriptor equals -1
> + * 	   the device is reopened
> + */
> +static void healthcheck(struct sysfs_fds *sysfs)
> +{
> +	open_if_closed(sysfs);
> +	gem_test_engine(sysfs->fds.dev, ALL_ENGINES);
This test is located in tests/ and looks like could be applicable to any
device. If that is true - gem_test_engine is from i915 familiy. Is there a way
to test engines for any driver? Naming is one thing, but what if amd card will
try to execute engines with i915 functions?

Kasia
> +}
> +
> +/**
> + * set_device_filter:
> + *
> + * Sets device filter to ensure subtests always reopen the same device
> + *
> + * @dev_path: path to device under tests
> + */
> +static void set_device_filter(const char* dev_path)
> +{
> +	char filter[strlen("sys:") + strlen(dev_path) + 1];
> +
> +	snprintf(filter, sizeof(filter), "sys:%s", dev_path);
> +	igt_device_filter_free_all();
> +	igt_assert_eq(igt_device_filter_add(filter), 1);
> +}
> +
> +static void unbind_rebind(struct sysfs_fds *sysfs)
> +{
> +	igt_debug("close the device\n");
> +	close_if_opened(&sysfs->fds.dev);
> +
> +	driver_unbind(sysfs);
> +
> +	driver_bind(sysfs);
> +}
> +
> +static void unbind_reset_rebind(struct sysfs_fds *sysfs)
> +{
> +	igt_debug("close the device\n");
> +	close_if_opened(&sysfs->fds.dev);
> +
> +	driver_unbind(sysfs);
> +
> +	initiate_device_reset(sysfs);
> +
> +	driver_bind(sysfs);
> +}
> +
> +igt_main
> +{
> +	struct sysfs_fds sysfs;
> +
> +	igt_fixture {
> +		char dev_path[PATH_MAX];
> +
> +		igt_debug("opening device\n");
> +		init_sysfs_fds(&sysfs);
> +
> +		/* Make sure subtests always reopen the same device */
> +		igt_assert(device_sysfs_path(sysfs.fds.dev, dev_path));
> +		set_device_filter(dev_path);
> +
> +		igt_skip_on(!is_sysfs_reset_supported(sysfs.fds.dev));
> +
> +		igt_set_timeout(60, "device reset tests timed out after 60s");
> +	}
> +
> +	igt_describe("Tests driver unbind from/rebind to device sequence");
> +	igt_subtest("unbind-rebind")
> +		unbind_rebind(&sysfs);
> +
> +	igt_describe("Unbinds driver from device, initiates reset"
> +		     " then rebinds driver to device");
> +	igt_subtest("unbind-reset-rebind")
> +		unbind_reset_rebind(&sysfs);
> +
> +	igt_describe("Resets device with bound driver");
> +	igt_subtest("reset-bound")
> +		initiate_device_reset(&sysfs);
> +
> +	igt_describe("Subtests with additional healthchecks");
> +	igt_subtest_group {
> +		igt_fixture {
> +			open_if_closed(&sysfs);
> +			igt_require_intel(sysfs.fds.dev);
> +		}
> +
> +		igt_subtest("healthcheck")
> +			healthcheck(&sysfs);
> +
> +		igt_subtest("unbind-reset-rebind-healthcheck") {
> +			unbind_reset_rebind(&sysfs);
> +			healthcheck(&sysfs);
> +		}
> +
> +		igt_subtest("reset-bound-healthcheck") {
> +			initiate_device_reset(&sysfs);
> +			healthcheck(&sysfs);
> +		}
> +	}
> +
> +	igt_fixture {
> +		igt_reset_timeout();
> +		cleanup_sysfs_fds(&sysfs);
> +	}
> +}
> diff --git a/tests/meson.build b/tests/meson.build
> index 28091794f..b0acdf7c0 100644
> --- a/tests/meson.build
> +++ b/tests/meson.build
> @@ -8,6 +8,7 @@ test_progs = [
>  	'core_setmaster_vs_auth',
>  	'debugfs_test',
>  	'dmabuf',
> +	'device_reset',
>  	'drm_import_export',
>  	'drm_mm',
>  	'drm_read',
> -- 
> 2.25.1
> 
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [igt-dev] [RFC, i-g-t] tests/device_reset: Test device sysfs reset
  2020-06-26  8:47 ` [igt-dev] [RFC, i-g-t] " Katarzyna Dec
@ 2020-06-26  8:55   ` Bernatowicz, Marcin
  2020-06-26  9:19     ` Katarzyna Dec
  0 siblings, 1 reply; 9+ messages in thread
From: Bernatowicz, Marcin @ 2020-06-26  8:55 UTC (permalink / raw)
  To: Dec, Katarzyna, igt-dev; +Cc: Winiarski, Michal, Vivi, Rodrigo

On Fri, 2020-06-26 at 10:47 +0200, Katarzyna Dec wrote:
> On Fri, Jun 26, 2020 at 08:30:45AM +0200, Marcin Bernatowicz wrote:
> > Device reset is initiated by writing "1" to reset sysfs file,
> > which should initiatie device FLR if supported by device.
> > 
> > Test scenarios:
> > 1. unbind driver from device then rebind
> > 2. unbind driver from device, initiate sysfs reset, rebind driver
> > to
> > device
> > 3. device reset with bound driver
> > 
> > Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@intel.com>
> > ---
> >  tests/device_reset.c | 298
> > +++++++++++++++++++++++++++++++++++++++++++
> >  tests/meson.build    |   1 +
> >  2 files changed, 299 insertions(+)
> >  create mode 100644 tests/device_reset.c
> > 
> > diff --git a/tests/device_reset.c b/tests/device_reset.c
> > new file mode 100644
> > index 000000000..bafe9fd41
> > --- /dev/null
> > +++ b/tests/device_reset.c
> > @@ -0,0 +1,298 @@
> > +// SPDX-License-Identifier: MIT
> > +/*
> > + * Copyright(c) 2020 Intel Corporation. All rights reserved.
> > + */
> > +
> > +#include <fcntl.h>
> > +#include <sys/stat.h>
> > +#include "igt.h"
> > +#include "igt_device_scan.h"
> > +#include "igt_sysfs.h"
> > +
> > +IGT_TEST_DESCRIPTION("Examine behavior of a driver on device sysfs
> > reset");
> > +
> > +
> > +#define DEV_PATH_LEN 80
> > +#define DEV_BUS_ADDR_LEN 13 /* addr has form 0000:00:00.0 */
> > +
> > +/**
> > + * Helper structure containing sysfs file descriptors
> > + * and path related to tested device
> > + */
> > +struct sysfs_fds {
> > +	struct {
> > +		int dev;
> > +		int dev_dir;
> > +		int drv_dir;
> > +	} fds;
> > +	char dev_bus_addr[DEV_BUS_ADDR_LEN];
> > +};
> > +
> > +static int __open_sysfs_dir(int fd, const char* path)
> > +{
> > +	int sysfs;
> > +
> > +	sysfs = igt_sysfs_open(fd);
> > +	if (sysfs < 0) {
> > +		return -1;
> > +	}
> > +
> > +	return openat(sysfs, path, O_DIRECTORY);
> > +}
> > +
> > +static int open_device_sysfs_dir(int fd)
> > +{
> > +	return __open_sysfs_dir(fd, "device");
> > +}
> > +
> > +static int open_driver_sysfs_dir(int fd)
> > +{
> > +	return __open_sysfs_dir(fd, "device/driver");
> > +}
> > +
> > +/**
> > + * device_sysfs_path:
> > + * @fd: opened device file descriptor
> > + * @path: buffer to store sysfs path to device directory
> > + *
> > + * Returns:
> > + * On successfull path resolution sysfs path to device directory,
> > + * NULL otherwise
> > + */
> > +static char *device_sysfs_path(int fd, char *path)
> > +{
> > +	char sysfs[DEV_PATH_LEN];
> > +
> > +	if (!igt_sysfs_path(fd, sysfs, sizeof(sysfs)))
> > +		return NULL;
> > +
> > +	if (DEV_PATH_LEN <= (strlen(sysfs) + strlen("/device")))
> > +		return NULL;
> > +
> > +	strcat(sysfs, "/device");
> > +
> > +	return realpath(sysfs, path);
> > +}
> > +
> > +static void init_sysfs_fds(struct sysfs_fds *sysfs)
> > +{
> > +	char dev_path[PATH_MAX];
> > +	char *addr_pos;
> > +
> > +	igt_debug("open device\n");
> > +	/**
> > +	 * As subtests must be able to close examined devices
> > +	 * completely, don't use drm_open_driver() as it keeps
> > +	 * a device file descriptor open for exit handler use.
> > +	 */
> > +	sysfs->fds.dev = __drm_open_driver(DRIVER_ANY);
> > +	igt_assert_fd(sysfs->fds.dev);
> > +
> > +	igt_assert(device_sysfs_path(sysfs->fds.dev, dev_path));
> > +	addr_pos = strrchr(dev_path, '/');
> > +	snprintf(sysfs->dev_bus_addr, sizeof(sysfs->dev_bus_addr),
> > +		 "%s", (addr_pos ? addr_pos + 1 : ""));
> > +	igt_assert(sysfs->dev_bus_addr[0]);
> > +
> > +	sysfs->fds.dev_dir = open_device_sysfs_dir(sysfs->fds.dev);
> > +	igt_assert_fd(sysfs->fds.dev_dir);
> > +
> > +	sysfs->fds.drv_dir = open_driver_sysfs_dir(sysfs->fds.dev);
> > +	igt_assert_fd(sysfs->fds.drv_dir);
> > +}
> > +
> > +static int close_if_opened(int *fd)
> > +{
> > +	int rc = 0;
> > +	if (fd && *fd != -1) {
> > +		rc = close(*fd);
> > +		*fd = -1;
> > +	}
> > +	return rc;
> > +}
> > +
> > +static void open_if_closed(struct sysfs_fds *sysfs)
> > +{
> > +	if (sysfs->fds.dev == -1) {
> > +		/* refresh device list */
> > +		igt_devices_scan(true);
> > +		igt_debug("reopen the device\n");
> > +		sysfs->fds.dev = __drm_open_driver(DRIVER_ANY);
> > +	}
> > +	igt_assert_fd(sysfs->fds.dev);
> > +}
> > +
> > +static void cleanup_sysfs_fds(struct sysfs_fds *sysfs)
> > +{
> > +	close_if_opened(&sysfs->fds.dev);
> > +	close_if_opened(&sysfs->fds.dev_dir);
> > +	close_if_opened(&sysfs->fds.drv_dir);
> > +	sysfs->dev_bus_addr[0] = '\0';
> > +}
> > +
> > +
> > +/**
> > + * is_sysfs_reset_supported:
> > + * @fd: opened device file descriptor
> > + *
> > + * Check if device supports reset based on sysfs file presence.
> > + *
> > + * Returns:
> > + * True if device supports reset, false otherwise.
> > + */
> > +static bool is_sysfs_reset_supported(int fd)
> > +{
> > +	struct stat st;
> > +	int rc;
> > +	int sysfs;
> > +	int reset_fd = -1;
> > +
> > +	sysfs = igt_sysfs_open(fd);
> > +
> > +	if (sysfs >= 0) {
> > +		reset_fd = openat(sysfs, "device/reset", O_WRONLY);
> > +		close(sysfs);
> > +	}
> > +
> > +	if (reset_fd < 0)
> > +		return false;
> > +
> > +	rc = fstat(reset_fd, &st);
> > +	close(reset_fd);
> > +
> > +	if (rc || !S_ISREG(st.st_mode))
> > +		return false;
> > +
> > +	return true;
> > +}
> > +
> > +/* Unbind the driver from the device */
> > +static void driver_unbind(struct sysfs_fds *sysfs)
> > +{
> > +	igt_debug("unbind the driver from the device\n");
> > +	igt_assert(igt_sysfs_set(sysfs->fds.drv_dir, "unbind",
> > +		   sysfs->dev_bus_addr));
> > +}
> > +
> > +/* Re-bind the driver to the device */
> > +static void driver_bind(struct sysfs_fds *sysfs)
> > +{
> > +	igt_debug("rebind the driver to the device\n");
> > +	igt_abort_on_f(!igt_sysfs_set(sysfs->fds.drv_dir, "bind",
> > +		       sysfs->dev_bus_addr), "driver rebind failed");
> > +}
> > +
> > +/* Initiate device reset */
> > +static void initiate_device_reset(struct sysfs_fds *sysfs)
> > +{
> > +	igt_debug("reset device\n");
> > +	igt_assert(igt_sysfs_set(sysfs->fds.dev_dir, "reset", "1"));
> > +}
> > +
> > +/**
> > + * healthcheck:
> > + * @sysfs: structure with device descriptor, if descriptor equals
> > -1
> > + * 	   the device is reopened
> > + */
> > +static void healthcheck(struct sysfs_fds *sysfs)
> > +{
> > +	open_if_closed(sysfs);
> > +	gem_test_engine(sysfs->fds.dev, ALL_ENGINES);
> 
> This test is located in tests/ and looks like could be applicable to
> any
> device. If that is true - gem_test_engine is from i915 familiy. Is
> there a way
> to test engines for any driver? Naming is one thing, but what if amd
> card will
> try to execute engines with i915 functions?
> 
> Kasia

healthcheck is used in subtest_group where igt_require_intel is
prerequisite, so the tests will be skipped on non intel platforms

> > +}
> > +
> > +/**
> > + * set_device_filter:
> > + *
> > + * Sets device filter to ensure subtests always reopen the same
> > device
> > + *
> > + * @dev_path: path to device under tests
> > + */
> > +static void set_device_filter(const char* dev_path)
> > +{
> > +	char filter[strlen("sys:") + strlen(dev_path) + 1];
> > +
> > +	snprintf(filter, sizeof(filter), "sys:%s", dev_path);
> > +	igt_device_filter_free_all();
> > +	igt_assert_eq(igt_device_filter_add(filter), 1);
> > +}
> > +
> > +static void unbind_rebind(struct sysfs_fds *sysfs)
> > +{
> > +	igt_debug("close the device\n");
> > +	close_if_opened(&sysfs->fds.dev);
> > +
> > +	driver_unbind(sysfs);
> > +
> > +	driver_bind(sysfs);
> > +}
> > +
> > +static void unbind_reset_rebind(struct sysfs_fds *sysfs)
> > +{
> > +	igt_debug("close the device\n");
> > +	close_if_opened(&sysfs->fds.dev);
> > +
> > +	driver_unbind(sysfs);
> > +
> > +	initiate_device_reset(sysfs);
> > +
> > +	driver_bind(sysfs);
> > +}
> > +
> > +igt_main
> > +{
> > +	struct sysfs_fds sysfs;
> > +
> > +	igt_fixture {
> > +		char dev_path[PATH_MAX];
> > +
> > +		igt_debug("opening device\n");
> > +		init_sysfs_fds(&sysfs);
> > +
> > +		/* Make sure subtests always reopen the same device */
> > +		igt_assert(device_sysfs_path(sysfs.fds.dev, dev_path));
> > +		set_device_filter(dev_path);
> > +
> > +		igt_skip_on(!is_sysfs_reset_supported(sysfs.fds.dev));
> > +
> > +		igt_set_timeout(60, "device reset tests timed out after
> > 60s");
> > +	}
> > +
> > +	igt_describe("Tests driver unbind from/rebind to device
> > sequence");
> > +	igt_subtest("unbind-rebind")
> > +		unbind_rebind(&sysfs);
> > +
> > +	igt_describe("Unbinds driver from device, initiates reset"
> > +		     " then rebinds driver to device");
> > +	igt_subtest("unbind-reset-rebind")
> > +		unbind_reset_rebind(&sysfs);
> > +
> > +	igt_describe("Resets device with bound driver");
> > +	igt_subtest("reset-bound")
> > +		initiate_device_reset(&sysfs);
> > +
> > +	igt_describe("Subtests with additional healthchecks");
> > +	igt_subtest_group {
> > +		igt_fixture {
> > +			open_if_closed(&sysfs);
> > +			igt_require_intel(sysfs.fds.dev);
> > +		}
> > +
> > +		igt_subtest("healthcheck")
> > +			healthcheck(&sysfs);
> > +
> > +		igt_subtest("unbind-reset-rebind-healthcheck") {
> > +			unbind_reset_rebind(&sysfs);
> > +			healthcheck(&sysfs);
> > +		}
> > +
> > +		igt_subtest("reset-bound-healthcheck") {
> > +			initiate_device_reset(&sysfs);
> > +			healthcheck(&sysfs);
> > +		}
> > +	}
> > +
> > +	igt_fixture {
> > +		igt_reset_timeout();
> > +		cleanup_sysfs_fds(&sysfs);
> > +	}
> > +}
> > diff --git a/tests/meson.build b/tests/meson.build
> > index 28091794f..b0acdf7c0 100644
> > --- a/tests/meson.build
> > +++ b/tests/meson.build
> > @@ -8,6 +8,7 @@ test_progs = [
> >  	'core_setmaster_vs_auth',
> >  	'debugfs_test',
> >  	'dmabuf',
> > +	'device_reset',
> >  	'drm_import_export',
> >  	'drm_mm',
> >  	'drm_read',
> > -- 
> > 2.25.1
> > 
---------------------------------------------------------------------
Intel Technology Poland sp. z o.o.
ul. Sowackiego 173 | 80-298 Gdask | Sd Rejonowy Gdask Pnoc | VII Wydzia Gospodarczy Krajowego Rejestru Sdowego - KRS 101882 | NIP 957-07-52-316 | Kapita zakadowy 200.000 PLN.
Ta wiadomo wraz z zacznikami jest przeznaczona dla okrelonego adresata i moe zawiera informacje poufne. W razie przypadkowego otrzymania tej wiadomoci, prosimy o powiadomienie nadawcy oraz trwae jej usunicie; jakiekolwiek przegldanie lub rozpowszechnianie jest zabronione.
This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). If you are not the intended recipient, please contact the sender and delete all copies; any review or distribution by others is strictly prohibited.
 
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [igt-dev] [RFC, i-g-t] tests/device_reset: Test device sysfs reset
  2020-06-26  8:55   ` Bernatowicz, Marcin
@ 2020-06-26  9:19     ` Katarzyna Dec
  2020-06-26 10:23       ` Bernatowicz, Marcin
  0 siblings, 1 reply; 9+ messages in thread
From: Katarzyna Dec @ 2020-06-26  9:19 UTC (permalink / raw)
  To: Bernatowicz, Marcin, igt-dev; +Cc: Winiarski, Michal, Vivi, Rodrigo

On Fri, Jun 26, 2020 at 09:55:09AM +0100, Bernatowicz, Marcin wrote:
> On Fri, 2020-06-26 at 10:47 +0200, Katarzyna Dec wrote:
> > On Fri, Jun 26, 2020 at 08:30:45AM +0200, Marcin Bernatowicz wrote:
> > > Device reset is initiated by writing "1" to reset sysfs file,
> > > which should initiatie device FLR if supported by device.
> > >
> > > Test scenarios:
> > > 1. unbind driver from device then rebind
> > > 2. unbind driver from device, initiate sysfs reset, rebind driver
> > > to
> > > device
> > > 3. device reset with bound driver
> > >
> > > Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@intel.com>
> > > ---
> > >  tests/device_reset.c | 298
> > > +++++++++++++++++++++++++++++++++++++++++++
> > >  tests/meson.build    |   1 +
> > >  2 files changed, 299 insertions(+)
> > >  create mode 100644 tests/device_reset.c
> > >
> > > diff --git a/tests/device_reset.c b/tests/device_reset.c
> > > new file mode 100644
> > > index 000000000..bafe9fd41
> > > --- /dev/null
> > > +++ b/tests/device_reset.c
> > > @@ -0,0 +1,298 @@
> > > +// SPDX-License-Identifier: MIT
> > > +/*
> > > + * Copyright(c) 2020 Intel Corporation. All rights reserved.
> > > + */
> > > +
> > > +#include <fcntl.h>
> > > +#include <sys/stat.h>
> > > +#include "igt.h"
> > > +#include "igt_device_scan.h"
> > > +#include "igt_sysfs.h"
> > > +
> > > +IGT_TEST_DESCRIPTION("Examine behavior of a driver on device sysfs
> > > reset");
> > > +
> > > +
> > > +#define DEV_PATH_LEN 80
> > > +#define DEV_BUS_ADDR_LEN 13 /* addr has form 0000:00:00.0 */
> > > +
> > > +/**
> > > + * Helper structure containing sysfs file descriptors
> > > + * and path related to tested device
> > > + */
> > > +struct sysfs_fds {
> > > +struct {
> > > +int dev;
> > > +int dev_dir;
> > > +int drv_dir;
> > > +} fds;
> > > +char dev_bus_addr[DEV_BUS_ADDR_LEN];
> > > +};
> > > +
> > > +static int __open_sysfs_dir(int fd, const char* path)
> > > +{
> > > +int sysfs;
> > > +
> > > +sysfs = igt_sysfs_open(fd);
> > > +if (sysfs < 0) {
> > > +return -1;
> > > +}
> > > +
> > > +return openat(sysfs, path, O_DIRECTORY);
> > > +}
> > > +
> > > +static int open_device_sysfs_dir(int fd)
> > > +{
> > > +return __open_sysfs_dir(fd, "device");
> > > +}
> > > +
> > > +static int open_driver_sysfs_dir(int fd)
> > > +{
> > > +return __open_sysfs_dir(fd, "device/driver");
> > > +}
> > > +
> > > +/**
> > > + * device_sysfs_path:
> > > + * @fd: opened device file descriptor
> > > + * @path: buffer to store sysfs path to device directory
> > > + *
> > > + * Returns:
> > > + * On successfull path resolution sysfs path to device directory,
> > > + * NULL otherwise
> > > + */
> > > +static char *device_sysfs_path(int fd, char *path)
> > > +{
> > > +char sysfs[DEV_PATH_LEN];
> > > +
> > > +if (!igt_sysfs_path(fd, sysfs, sizeof(sysfs)))
> > > +return NULL;
> > > +
> > > +if (DEV_PATH_LEN <= (strlen(sysfs) + strlen("/device")))
> > > +return NULL;
> > > +
> > > +strcat(sysfs, "/device");
> > > +
> > > +return realpath(sysfs, path);
> > > +}
> > > +
> > > +static void init_sysfs_fds(struct sysfs_fds *sysfs)
> > > +{
> > > +char dev_path[PATH_MAX];
> > > +char *addr_pos;
> > > +
> > > +igt_debug("open device\n");
> > > +/**
> > > + * As subtests must be able to close examined devices
> > > + * completely, don't use drm_open_driver() as it keeps
> > > + * a device file descriptor open for exit handler use.
> > > + */
> > > +sysfs->fds.dev = __drm_open_driver(DRIVER_ANY);
> > > +igt_assert_fd(sysfs->fds.dev);
> > > +
> > > +igt_assert(device_sysfs_path(sysfs->fds.dev, dev_path));
> > > +addr_pos = strrchr(dev_path, '/');
> > > +snprintf(sysfs->dev_bus_addr, sizeof(sysfs->dev_bus_addr),
> > > + "%s", (addr_pos ? addr_pos + 1 : ""));
> > > +igt_assert(sysfs->dev_bus_addr[0]);
> > > +
> > > +sysfs->fds.dev_dir = open_device_sysfs_dir(sysfs->fds.dev);
> > > +igt_assert_fd(sysfs->fds.dev_dir);
> > > +
> > > +sysfs->fds.drv_dir = open_driver_sysfs_dir(sysfs->fds.dev);
> > > +igt_assert_fd(sysfs->fds.drv_dir);
> > > +}
> > > +
> > > +static int close_if_opened(int *fd)
> > > +{
> > > +int rc = 0;
> > > +if (fd && *fd != -1) {
> > > +rc = close(*fd);
> > > +*fd = -1;
> > > +}
> > > +return rc;
> > > +}
> > > +
> > > +static void open_if_closed(struct sysfs_fds *sysfs)
> > > +{
> > > +if (sysfs->fds.dev == -1) {
> > > +/* refresh device list */
> > > +igt_devices_scan(true);
> > > +igt_debug("reopen the device\n");
> > > +sysfs->fds.dev = __drm_open_driver(DRIVER_ANY);
> > > +}
> > > +igt_assert_fd(sysfs->fds.dev);
> > > +}
> > > +
> > > +static void cleanup_sysfs_fds(struct sysfs_fds *sysfs)
> > > +{
> > > +close_if_opened(&sysfs->fds.dev);
> > > +close_if_opened(&sysfs->fds.dev_dir);
> > > +close_if_opened(&sysfs->fds.drv_dir);
> > > +sysfs->dev_bus_addr[0] = '\0';
> > > +}
> > > +
> > > +
> > > +/**
> > > + * is_sysfs_reset_supported:
> > > + * @fd: opened device file descriptor
> > > + *
> > > + * Check if device supports reset based on sysfs file presence.
> > > + *
> > > + * Returns:
> > > + * True if device supports reset, false otherwise.
> > > + */
> > > +static bool is_sysfs_reset_supported(int fd)
> > > +{
> > > +struct stat st;
> > > +int rc;
> > > +int sysfs;
> > > +int reset_fd = -1;
> > > +
> > > +sysfs = igt_sysfs_open(fd);
> > > +
> > > +if (sysfs >= 0) {
> > > +reset_fd = openat(sysfs, "device/reset", O_WRONLY);
> > > +close(sysfs);
> > > +}
> > > +
> > > +if (reset_fd < 0)
> > > +return false;
> > > +
> > > +rc = fstat(reset_fd, &st);
> > > +close(reset_fd);
> > > +
> > > +if (rc || !S_ISREG(st.st_mode))
> > > +return false;
> > > +
> > > +return true;
> > > +}
> > > +
> > > +/* Unbind the driver from the device */
> > > +static void driver_unbind(struct sysfs_fds *sysfs)
> > > +{
> > > +igt_debug("unbind the driver from the device\n");
> > > +igt_assert(igt_sysfs_set(sysfs->fds.drv_dir, "unbind",
> > > +   sysfs->dev_bus_addr));
> > > +}
> > > +
> > > +/* Re-bind the driver to the device */
> > > +static void driver_bind(struct sysfs_fds *sysfs)
> > > +{
> > > +igt_debug("rebind the driver to the device\n");
> > > +igt_abort_on_f(!igt_sysfs_set(sysfs->fds.drv_dir, "bind",
> > > +       sysfs->dev_bus_addr), "driver rebind failed");
> > > +}
> > > +
> > > +/* Initiate device reset */
> > > +static void initiate_device_reset(struct sysfs_fds *sysfs)
> > > +{
> > > +igt_debug("reset device\n");
> > > +igt_assert(igt_sysfs_set(sysfs->fds.dev_dir, "reset", "1"));
> > > +}
> > > +
> > > +/**
> > > + * healthcheck:
> > > + * @sysfs: structure with device descriptor, if descriptor equals
> > > -1
> > > + *    the device is reopened
> > > + */
> > > +static void healthcheck(struct sysfs_fds *sysfs)
> > > +{
> > > +open_if_closed(sysfs);
> > > +gem_test_engine(sysfs->fds.dev, ALL_ENGINES);
> >
> > This test is located in tests/ and looks like could be applicable to
> > any
> > device. If that is true - gem_test_engine is from i915 familiy. Is
> > there a way
> > to test engines for any driver? Naming is one thing, but what if amd
> > card will
> > try to execute engines with i915 functions?
> >
> > Kasia
> 
> healthcheck is used in subtest_group where igt_require_intel is
> prerequisite, so the tests will be skipped on non intel platforms
In that case test should be moved to tests/i915 dir than?
Kasia
> 
> > > +}
> > > +
> > > +/**
> > > + * set_device_filter:
> > > + *
> > > + * Sets device filter to ensure subtests always reopen the same
> > > device
> > > + *
> > > + * @dev_path: path to device under tests
> > > + */
> > > +static void set_device_filter(const char* dev_path)
> > > +{
> > > +char filter[strlen("sys:") + strlen(dev_path) + 1];
> > > +
> > > +snprintf(filter, sizeof(filter), "sys:%s", dev_path);
> > > +igt_device_filter_free_all();
> > > +igt_assert_eq(igt_device_filter_add(filter), 1);
> > > +}
> > > +
> > > +static void unbind_rebind(struct sysfs_fds *sysfs)
> > > +{
> > > +igt_debug("close the device\n");
> > > +close_if_opened(&sysfs->fds.dev);
> > > +
> > > +driver_unbind(sysfs);
> > > +
> > > +driver_bind(sysfs);
> > > +}
> > > +
> > > +static void unbind_reset_rebind(struct sysfs_fds *sysfs)
> > > +{
> > > +igt_debug("close the device\n");
> > > +close_if_opened(&sysfs->fds.dev);
> > > +
> > > +driver_unbind(sysfs);
> > > +
> > > +initiate_device_reset(sysfs);
> > > +
> > > +driver_bind(sysfs);
> > > +}
> > > +
> > > +igt_main
> > > +{
> > > +struct sysfs_fds sysfs;
> > > +
> > > +igt_fixture {
> > > +char dev_path[PATH_MAX];
> > > +
> > > +igt_debug("opening device\n");
> > > +init_sysfs_fds(&sysfs);
> > > +
> > > +/* Make sure subtests always reopen the same device */
> > > +igt_assert(device_sysfs_path(sysfs.fds.dev, dev_path));
> > > +set_device_filter(dev_path);
> > > +
> > > +igt_skip_on(!is_sysfs_reset_supported(sysfs.fds.dev));
> > > +
> > > +igt_set_timeout(60, "device reset tests timed out after
> > > 60s");
> > > +}
> > > +
> > > +igt_describe("Tests driver unbind from/rebind to device
> > > sequence");
> > > +igt_subtest("unbind-rebind")
> > > +unbind_rebind(&sysfs);
> > > +
> > > +igt_describe("Unbinds driver from device, initiates reset"
> > > +     " then rebinds driver to device");
> > > +igt_subtest("unbind-reset-rebind")
> > > +unbind_reset_rebind(&sysfs);
> > > +
> > > +igt_describe("Resets device with bound driver");
> > > +igt_subtest("reset-bound")
> > > +initiate_device_reset(&sysfs);
> > > +
> > > +igt_describe("Subtests with additional healthchecks");
> > > +igt_subtest_group {
> > > +igt_fixture {
> > > +open_if_closed(&sysfs);
> > > +igt_require_intel(sysfs.fds.dev);
> > > +}
> > > +
> > > +igt_subtest("healthcheck")
> > > +healthcheck(&sysfs);
> > > +
> > > +igt_subtest("unbind-reset-rebind-healthcheck") {
> > > +unbind_reset_rebind(&sysfs);
> > > +healthcheck(&sysfs);
> > > +}
> > > +
> > > +igt_subtest("reset-bound-healthcheck") {
> > > +initiate_device_reset(&sysfs);
> > > +healthcheck(&sysfs);
> > > +}
> > > +}
> > > +
> > > +igt_fixture {
> > > +igt_reset_timeout();
> > > +cleanup_sysfs_fds(&sysfs);
> > > +}
> > > +}
> > > diff --git a/tests/meson.build b/tests/meson.build
> > > index 28091794f..b0acdf7c0 100644
> > > --- a/tests/meson.build
> > > +++ b/tests/meson.build
> > > @@ -8,6 +8,7 @@ test_progs = [
> > >  'core_setmaster_vs_auth',
> > >  'debugfs_test',
> > >  'dmabuf',
> > > +'device_reset',
> > >  'drm_import_export',
> > >  'drm_mm',
> > >  'drm_read',
> > > --
> > > 2.25.1
> > >
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [igt-dev] [RFC, i-g-t] tests/device_reset: Test device sysfs reset
  2020-06-26  9:19     ` Katarzyna Dec
@ 2020-06-26 10:23       ` Bernatowicz, Marcin
  2020-06-26 10:48         ` Katarzyna Dec
  2020-06-26 11:35         ` Janusz Krzysztofik
  0 siblings, 2 replies; 9+ messages in thread
From: Bernatowicz, Marcin @ 2020-06-26 10:23 UTC (permalink / raw)
  To: Dec, Katarzyna, igt-dev; +Cc: Winiarski, Michal, Vivi, Rodrigo

On Fri, 2020-06-26 at 11:19 +0200, Katarzyna Dec wrote:
> On Fri, Jun 26, 2020 at 09:55:09AM +0100, Bernatowicz, Marcin wrote:
> > On Fri, 2020-06-26 at 10:47 +0200, Katarzyna Dec wrote:
> > > On Fri, Jun 26, 2020 at 08:30:45AM +0200, Marcin Bernatowicz
> > > wrote:
> > > > Device reset is initiated by writing "1" to reset sysfs file,
> > > > which should initiatie device FLR if supported by device.
> > > > 
> > > > Test scenarios:
> > > > 1. unbind driver from device then rebind
> > > > 2. unbind driver from device, initiate sysfs reset, rebind
> > > > driver
> > > > to
> > > > device
> > > > 3. device reset with bound driver
> > > > 
> > > > Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@intel.com
> > > > >
> > > > ---
> > > >  tests/device_reset.c | 298
> > > > +++++++++++++++++++++++++++++++++++++++++++
> > > >  tests/meson.build    |   1 +
> > > >  2 files changed, 299 insertions(+)
> > > >  create mode 100644 tests/device_reset.c
> > > > 
> > > > diff --git a/tests/device_reset.c b/tests/device_reset.c
> > > > new file mode 100644
> > > > index 000000000..bafe9fd41
> > > > --- /dev/null
> > > > +++ b/tests/device_reset.c
> > > > @@ -0,0 +1,298 @@
> > > > +// SPDX-License-Identifier: MIT
> > > > +/*
> > > > + * Copyright(c) 2020 Intel Corporation. All rights reserved.
> > > > + */
> > > > +
> > > > +#include <fcntl.h>
> > > > +#include <sys/stat.h>
> > > > +#include "igt.h"
> > > > +#include "igt_device_scan.h"
> > > > +#include "igt_sysfs.h"
> > > > +
> > > > +IGT_TEST_DESCRIPTION("Examine behavior of a driver on device
> > > > sysfs
> > > > reset");
> > > > +
> > > > +
> > > > +#define DEV_PATH_LEN 80
> > > > +#define DEV_BUS_ADDR_LEN 13 /* addr has form 0000:00:00.0 */
> > > > +
> > > > +/**
> > > > + * Helper structure containing sysfs file descriptors
> > > > + * and path related to tested device
> > > > + */
> > > > +struct sysfs_fds {
> > > > +struct {
> > > > +int dev;
> > > > +int dev_dir;
> > > > +int drv_dir;
> > > > +} fds;
> > > > +char dev_bus_addr[DEV_BUS_ADDR_LEN];
> > > > +};
> > > > +
> > > > +static int __open_sysfs_dir(int fd, const char* path)
> > > > +{
> > > > +int sysfs;
> > > > +
> > > > +sysfs = igt_sysfs_open(fd);
> > > > +if (sysfs < 0) {
> > > > +return -1;
> > > > +}
> > > > +
> > > > +return openat(sysfs, path, O_DIRECTORY);
> > > > +}
> > > > +
> > > > +static int open_device_sysfs_dir(int fd)
> > > > +{
> > > > +return __open_sysfs_dir(fd, "device");
> > > > +}
> > > > +
> > > > +static int open_driver_sysfs_dir(int fd)
> > > > +{
> > > > +return __open_sysfs_dir(fd, "device/driver");
> > > > +}
> > > > +
> > > > +/**
> > > > + * device_sysfs_path:
> > > > + * @fd: opened device file descriptor
> > > > + * @path: buffer to store sysfs path to device directory
> > > > + *
> > > > + * Returns:
> > > > + * On successfull path resolution sysfs path to device
> > > > directory,
> > > > + * NULL otherwise
> > > > + */
> > > > +static char *device_sysfs_path(int fd, char *path)
> > > > +{
> > > > +char sysfs[DEV_PATH_LEN];
> > > > +
> > > > +if (!igt_sysfs_path(fd, sysfs, sizeof(sysfs)))
> > > > +return NULL;
> > > > +
> > > > +if (DEV_PATH_LEN <= (strlen(sysfs) + strlen("/device")))
> > > > +return NULL;
> > > > +
> > > > +strcat(sysfs, "/device");
> > > > +
> > > > +return realpath(sysfs, path);
> > > > +}
> > > > +
> > > > +static void init_sysfs_fds(struct sysfs_fds *sysfs)
> > > > +{
> > > > +char dev_path[PATH_MAX];
> > > > +char *addr_pos;
> > > > +
> > > > +igt_debug("open device\n");
> > > > +/**
> > > > + * As subtests must be able to close examined devices
> > > > + * completely, don't use drm_open_driver() as it keeps
> > > > + * a device file descriptor open for exit handler use.
> > > > + */
> > > > +sysfs->fds.dev = __drm_open_driver(DRIVER_ANY);
> > > > +igt_assert_fd(sysfs->fds.dev);
> > > > +
> > > > +igt_assert(device_sysfs_path(sysfs->fds.dev, dev_path));
> > > > +addr_pos = strrchr(dev_path, '/');
> > > > +snprintf(sysfs->dev_bus_addr, sizeof(sysfs->dev_bus_addr),
> > > > + "%s", (addr_pos ? addr_pos + 1 : ""));
> > > > +igt_assert(sysfs->dev_bus_addr[0]);
> > > > +
> > > > +sysfs->fds.dev_dir = open_device_sysfs_dir(sysfs->fds.dev);
> > > > +igt_assert_fd(sysfs->fds.dev_dir);
> > > > +
> > > > +sysfs->fds.drv_dir = open_driver_sysfs_dir(sysfs->fds.dev);
> > > > +igt_assert_fd(sysfs->fds.drv_dir);
> > > > +}
> > > > +
> > > > +static int close_if_opened(int *fd)
> > > > +{
> > > > +int rc = 0;
> > > > +if (fd && *fd != -1) {
> > > > +rc = close(*fd);
> > > > +*fd = -1;
> > > > +}
> > > > +return rc;
> > > > +}
> > > > +
> > > > +static void open_if_closed(struct sysfs_fds *sysfs)
> > > > +{
> > > > +if (sysfs->fds.dev == -1) {
> > > > +/* refresh device list */
> > > > +igt_devices_scan(true);
> > > > +igt_debug("reopen the device\n");
> > > > +sysfs->fds.dev = __drm_open_driver(DRIVER_ANY);
> > > > +}
> > > > +igt_assert_fd(sysfs->fds.dev);
> > > > +}
> > > > +
> > > > +static void cleanup_sysfs_fds(struct sysfs_fds *sysfs)
> > > > +{
> > > > +close_if_opened(&sysfs->fds.dev);
> > > > +close_if_opened(&sysfs->fds.dev_dir);
> > > > +close_if_opened(&sysfs->fds.drv_dir);
> > > > +sysfs->dev_bus_addr[0] = '\0';
> > > > +}
> > > > +
> > > > +
> > > > +/**
> > > > + * is_sysfs_reset_supported:
> > > > + * @fd: opened device file descriptor
> > > > + *
> > > > + * Check if device supports reset based on sysfs file
> > > > presence.
> > > > + *
> > > > + * Returns:
> > > > + * True if device supports reset, false otherwise.
> > > > + */
> > > > +static bool is_sysfs_reset_supported(int fd)
> > > > +{
> > > > +struct stat st;
> > > > +int rc;
> > > > +int sysfs;
> > > > +int reset_fd = -1;
> > > > +
> > > > +sysfs = igt_sysfs_open(fd);
> > > > +
> > > > +if (sysfs >= 0) {
> > > > +reset_fd = openat(sysfs, "device/reset", O_WRONLY);
> > > > +close(sysfs);
> > > > +}
> > > > +
> > > > +if (reset_fd < 0)
> > > > +return false;
> > > > +
> > > > +rc = fstat(reset_fd, &st);
> > > > +close(reset_fd);
> > > > +
> > > > +if (rc || !S_ISREG(st.st_mode))
> > > > +return false;
> > > > +
> > > > +return true;
> > > > +}
> > > > +
> > > > +/* Unbind the driver from the device */
> > > > +static void driver_unbind(struct sysfs_fds *sysfs)
> > > > +{
> > > > +igt_debug("unbind the driver from the device\n");
> > > > +igt_assert(igt_sysfs_set(sysfs->fds.drv_dir, "unbind",
> > > > +   sysfs->dev_bus_addr));
> > > > +}
> > > > +
> > > > +/* Re-bind the driver to the device */
> > > > +static void driver_bind(struct sysfs_fds *sysfs)
> > > > +{
> > > > +igt_debug("rebind the driver to the device\n");
> > > > +igt_abort_on_f(!igt_sysfs_set(sysfs->fds.drv_dir, "bind",
> > > > +       sysfs->dev_bus_addr), "driver rebind failed");
> > > > +}
> > > > +
> > > > +/* Initiate device reset */
> > > > +static void initiate_device_reset(struct sysfs_fds *sysfs)
> > > > +{
> > > > +igt_debug("reset device\n");
> > > > +igt_assert(igt_sysfs_set(sysfs->fds.dev_dir, "reset", "1"));
> > > > +}
> > > > +
> > > > +/**
> > > > + * healthcheck:
> > > > + * @sysfs: structure with device descriptor, if descriptor
> > > > equals
> > > > -1
> > > > + *    the device is reopened
> > > > + */
> > > > +static void healthcheck(struct sysfs_fds *sysfs)
> > > > +{
> > > > +open_if_closed(sysfs);
> > > > +gem_test_engine(sysfs->fds.dev, ALL_ENGINES);
> > > 
> > > This test is located in tests/ and looks like could be applicable
> > > to
> > > any
> > > device. If that is true - gem_test_engine is from i915 familiy.
> > > Is
> > > there a way
> > > to test engines for any driver? Naming is one thing, but what if
> > > amd
> > > card will
> > > try to execute engines with i915 functions?
> > > 
> > > Kasia
> > 
> > healthcheck is used in subtest_group where igt_require_intel is
> > prerequisite, so the tests will be skipped on non intel platforms
> 
> In that case test should be moved to tests/i915 dir than?
> Kasia

Following tests may be executed on ANY_DEVICE:
unbind-rebind
unbind-reset-rebind
reset-bound

the versions with *-healthcheck will skip on non intel platfroms.

Should I move them to separate binary under tests/i915 dir ?

> > 
> > > > +}
> > > > +
> > > > +/**
> > > > + * set_device_filter:
> > > > + *
> > > > + * Sets device filter to ensure subtests always reopen the
> > > > same
> > > > device
> > > > + *
> > > > + * @dev_path: path to device under tests
> > > > + */
> > > > +static void set_device_filter(const char* dev_path)
> > > > +{
> > > > +char filter[strlen("sys:") + strlen(dev_path) + 1];
> > > > +
> > > > +snprintf(filter, sizeof(filter), "sys:%s", dev_path);
> > > > +igt_device_filter_free_all();
> > > > +igt_assert_eq(igt_device_filter_add(filter), 1);
> > > > +}
> > > > +
> > > > +static void unbind_rebind(struct sysfs_fds *sysfs)
> > > > +{
> > > > +igt_debug("close the device\n");
> > > > +close_if_opened(&sysfs->fds.dev);
> > > > +
> > > > +driver_unbind(sysfs);
> > > > +
> > > > +driver_bind(sysfs);
> > > > +}
> > > > +
> > > > +static void unbind_reset_rebind(struct sysfs_fds *sysfs)
> > > > +{
> > > > +igt_debug("close the device\n");
> > > > +close_if_opened(&sysfs->fds.dev);
> > > > +
> > > > +driver_unbind(sysfs);
> > > > +
> > > > +initiate_device_reset(sysfs);
> > > > +
> > > > +driver_bind(sysfs);
> > > > +}
> > > > +
> > > > +igt_main
> > > > +{
> > > > +struct sysfs_fds sysfs;
> > > > +
> > > > +igt_fixture {
> > > > +char dev_path[PATH_MAX];
> > > > +
> > > > +igt_debug("opening device\n");
> > > > +init_sysfs_fds(&sysfs);
> > > > +
> > > > +/* Make sure subtests always reopen the same device */
> > > > +igt_assert(device_sysfs_path(sysfs.fds.dev, dev_path));
> > > > +set_device_filter(dev_path);
> > > > +
> > > > +igt_skip_on(!is_sysfs_reset_supported(sysfs.fds.dev));
> > > > +
> > > > +igt_set_timeout(60, "device reset tests timed out after
> > > > 60s");
> > > > +}
> > > > +
> > > > +igt_describe("Tests driver unbind from/rebind to device
> > > > sequence");
> > > > +igt_subtest("unbind-rebind")
> > > > +unbind_rebind(&sysfs);
> > > > +
> > > > +igt_describe("Unbinds driver from device, initiates reset"
> > > > +     " then rebinds driver to device");
> > > > +igt_subtest("unbind-reset-rebind")
> > > > +unbind_reset_rebind(&sysfs);
> > > > +
> > > > +igt_describe("Resets device with bound driver");
> > > > +igt_subtest("reset-bound")
> > > > +initiate_device_reset(&sysfs);
> > > > +
> > > > +igt_describe("Subtests with additional healthchecks");
> > > > +igt_subtest_group {
> > > > +igt_fixture {
> > > > +open_if_closed(&sysfs);
> > > > +igt_require_intel(sysfs.fds.dev);
> > > > +}
> > > > +
> > > > +igt_subtest("healthcheck")
> > > > +healthcheck(&sysfs);
> > > > +
> > > > +igt_subtest("unbind-reset-rebind-healthcheck") {
> > > > +unbind_reset_rebind(&sysfs);
> > > > +healthcheck(&sysfs);
> > > > +}
> > > > +
> > > > +igt_subtest("reset-bound-healthcheck") {
> > > > +initiate_device_reset(&sysfs);
> > > > +healthcheck(&sysfs);
> > > > +}
> > > > +}
> > > > +
> > > > +igt_fixture {
> > > > +igt_reset_timeout();
> > > > +cleanup_sysfs_fds(&sysfs);
> > > > +}
> > > > +}
> > > > diff --git a/tests/meson.build b/tests/meson.build
> > > > index 28091794f..b0acdf7c0 100644
> > > > --- a/tests/meson.build
> > > > +++ b/tests/meson.build
> > > > @@ -8,6 +8,7 @@ test_progs = [
> > > >  'core_setmaster_vs_auth',
> > > >  'debugfs_test',
> > > >  'dmabuf',
> > > > +'device_reset',
> > > >  'drm_import_export',
> > > >  'drm_mm',
> > > >  'drm_read',
> > > > --
> > > > 2.25.1
> > > > 
---------------------------------------------------------------------
Intel Technology Poland sp. z o.o.
ul. Sowackiego 173 | 80-298 Gdask | Sd Rejonowy Gdask Pnoc | VII Wydzia Gospodarczy Krajowego Rejestru Sdowego - KRS 101882 | NIP 957-07-52-316 | Kapita zakadowy 200.000 PLN.
Ta wiadomo wraz z zacznikami jest przeznaczona dla okrelonego adresata i moe zawiera informacje poufne. W razie przypadkowego otrzymania tej wiadomoci, prosimy o powiadomienie nadawcy oraz trwae jej usunicie; jakiekolwiek przegldanie lub rozpowszechnianie jest zabronione.
This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). If you are not the intended recipient, please contact the sender and delete all copies; any review or distribution by others is strictly prohibited.
 
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [igt-dev] [RFC, i-g-t] tests/device_reset: Test device sysfs reset
  2020-06-26 10:23       ` Bernatowicz, Marcin
@ 2020-06-26 10:48         ` Katarzyna Dec
  2020-06-26 11:35         ` Janusz Krzysztofik
  1 sibling, 0 replies; 9+ messages in thread
From: Katarzyna Dec @ 2020-06-26 10:48 UTC (permalink / raw)
  To: Bernatowicz, Marcin, igt-dev; +Cc: Winiarski, Michal, Vivi, Rodrigo

On Fri, Jun 26, 2020 at 11:23:08AM +0100, Bernatowicz, Marcin wrote:
> On Fri, 2020-06-26 at 11:19 +0200, Katarzyna Dec wrote:
> > On Fri, Jun 26, 2020 at 09:55:09AM +0100, Bernatowicz, Marcin wrote:
> > > On Fri, 2020-06-26 at 10:47 +0200, Katarzyna Dec wrote:
> > > > On Fri, Jun 26, 2020 at 08:30:45AM +0200, Marcin Bernatowicz
> > > > wrote:
> > > > > Device reset is initiated by writing "1" to reset sysfs file,
> > > > > which should initiatie device FLR if supported by device.
> > > > >
> > > > > Test scenarios:
> > > > > 1. unbind driver from device then rebind
> > > > > 2. unbind driver from device, initiate sysfs reset, rebind
> > > > > driver
> > > > > to
> > > > > device
> > > > > 3. device reset with bound driver
> > > > >
> > > > > Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@intel.com
> > > > > >
> > > > > ---
> > > > >  tests/device_reset.c | 298
> > > > > +++++++++++++++++++++++++++++++++++++++++++
> > > > >  tests/meson.build    |   1 +
> > > > >  2 files changed, 299 insertions(+)
> > > > >  create mode 100644 tests/device_reset.c
> > > > >
> > > > > diff --git a/tests/device_reset.c b/tests/device_reset.c
> > > > > new file mode 100644
> > > > > index 000000000..bafe9fd41
> > > > > --- /dev/null
> > > > > +++ b/tests/device_reset.c
> > > > > @@ -0,0 +1,298 @@
> > > > > +// SPDX-License-Identifier: MIT
> > > > > +/*
> > > > > + * Copyright(c) 2020 Intel Corporation. All rights reserved.
> > > > > + */
> > > > > +
> > > > > +#include <fcntl.h>
> > > > > +#include <sys/stat.h>
> > > > > +#include "igt.h"
> > > > > +#include "igt_device_scan.h"
> > > > > +#include "igt_sysfs.h"
> > > > > +
> > > > > +IGT_TEST_DESCRIPTION("Examine behavior of a driver on device
> > > > > sysfs
> > > > > reset");
> > > > > +
> > > > > +
> > > > > +#define DEV_PATH_LEN 80
> > > > > +#define DEV_BUS_ADDR_LEN 13 /* addr has form 0000:00:00.0 */
> > > > > +
> > > > > +/**
> > > > > + * Helper structure containing sysfs file descriptors
> > > > > + * and path related to tested device
> > > > > + */
> > > > > +struct sysfs_fds {
> > > > > +struct {
> > > > > +int dev;
> > > > > +int dev_dir;
> > > > > +int drv_dir;
> > > > > +} fds;
> > > > > +char dev_bus_addr[DEV_BUS_ADDR_LEN];
> > > > > +};
> > > > > +
> > > > > +static int __open_sysfs_dir(int fd, const char* path)
> > > > > +{
> > > > > +int sysfs;
> > > > > +
> > > > > +sysfs = igt_sysfs_open(fd);
> > > > > +if (sysfs < 0) {
> > > > > +return -1;
> > > > > +}
> > > > > +
> > > > > +return openat(sysfs, path, O_DIRECTORY);
> > > > > +}
> > > > > +
> > > > > +static int open_device_sysfs_dir(int fd)
> > > > > +{
> > > > > +return __open_sysfs_dir(fd, "device");
> > > > > +}
> > > > > +
> > > > > +static int open_driver_sysfs_dir(int fd)
> > > > > +{
> > > > > +return __open_sysfs_dir(fd, "device/driver");
> > > > > +}
> > > > > +
> > > > > +/**
> > > > > + * device_sysfs_path:
> > > > > + * @fd: opened device file descriptor
> > > > > + * @path: buffer to store sysfs path to device directory
> > > > > + *
> > > > > + * Returns:
> > > > > + * On successfull path resolution sysfs path to device
> > > > > directory,
> > > > > + * NULL otherwise
> > > > > + */
> > > > > +static char *device_sysfs_path(int fd, char *path)
> > > > > +{
> > > > > +char sysfs[DEV_PATH_LEN];
> > > > > +
> > > > > +if (!igt_sysfs_path(fd, sysfs, sizeof(sysfs)))
> > > > > +return NULL;
> > > > > +
> > > > > +if (DEV_PATH_LEN <= (strlen(sysfs) + strlen("/device")))
> > > > > +return NULL;
> > > > > +
> > > > > +strcat(sysfs, "/device");
> > > > > +
> > > > > +return realpath(sysfs, path);
> > > > > +}
> > > > > +
> > > > > +static void init_sysfs_fds(struct sysfs_fds *sysfs)
> > > > > +{
> > > > > +char dev_path[PATH_MAX];
> > > > > +char *addr_pos;
> > > > > +
> > > > > +igt_debug("open device\n");
> > > > > +/**
> > > > > + * As subtests must be able to close examined devices
> > > > > + * completely, don't use drm_open_driver() as it keeps
> > > > > + * a device file descriptor open for exit handler use.
> > > > > + */
> > > > > +sysfs->fds.dev = __drm_open_driver(DRIVER_ANY);
> > > > > +igt_assert_fd(sysfs->fds.dev);
> > > > > +
> > > > > +igt_assert(device_sysfs_path(sysfs->fds.dev, dev_path));
> > > > > +addr_pos = strrchr(dev_path, '/');
> > > > > +snprintf(sysfs->dev_bus_addr, sizeof(sysfs->dev_bus_addr),
> > > > > + "%s", (addr_pos ? addr_pos + 1 : ""));
> > > > > +igt_assert(sysfs->dev_bus_addr[0]);
> > > > > +
> > > > > +sysfs->fds.dev_dir = open_device_sysfs_dir(sysfs->fds.dev);
> > > > > +igt_assert_fd(sysfs->fds.dev_dir);
> > > > > +
> > > > > +sysfs->fds.drv_dir = open_driver_sysfs_dir(sysfs->fds.dev);
> > > > > +igt_assert_fd(sysfs->fds.drv_dir);
> > > > > +}
> > > > > +
> > > > > +static int close_if_opened(int *fd)
> > > > > +{
> > > > > +int rc = 0;
> > > > > +if (fd && *fd != -1) {
> > > > > +rc = close(*fd);
> > > > > +*fd = -1;
> > > > > +}
> > > > > +return rc;
> > > > > +}
> > > > > +
> > > > > +static void open_if_closed(struct sysfs_fds *sysfs)
> > > > > +{
> > > > > +if (sysfs->fds.dev == -1) {
> > > > > +/* refresh device list */
> > > > > +igt_devices_scan(true);
> > > > > +igt_debug("reopen the device\n");
> > > > > +sysfs->fds.dev = __drm_open_driver(DRIVER_ANY);
> > > > > +}
> > > > > +igt_assert_fd(sysfs->fds.dev);
> > > > > +}
> > > > > +
> > > > > +static void cleanup_sysfs_fds(struct sysfs_fds *sysfs)
> > > > > +{
> > > > > +close_if_opened(&sysfs->fds.dev);
> > > > > +close_if_opened(&sysfs->fds.dev_dir);
> > > > > +close_if_opened(&sysfs->fds.drv_dir);
> > > > > +sysfs->dev_bus_addr[0] = '\0';
> > > > > +}
> > > > > +
> > > > > +
> > > > > +/**
> > > > > + * is_sysfs_reset_supported:
> > > > > + * @fd: opened device file descriptor
> > > > > + *
> > > > > + * Check if device supports reset based on sysfs file
> > > > > presence.
> > > > > + *
> > > > > + * Returns:
> > > > > + * True if device supports reset, false otherwise.
> > > > > + */
> > > > > +static bool is_sysfs_reset_supported(int fd)
> > > > > +{
> > > > > +struct stat st;
> > > > > +int rc;
> > > > > +int sysfs;
> > > > > +int reset_fd = -1;
> > > > > +
> > > > > +sysfs = igt_sysfs_open(fd);
> > > > > +
> > > > > +if (sysfs >= 0) {
> > > > > +reset_fd = openat(sysfs, "device/reset", O_WRONLY);
> > > > > +close(sysfs);
> > > > > +}
> > > > > +
> > > > > +if (reset_fd < 0)
> > > > > +return false;
> > > > > +
> > > > > +rc = fstat(reset_fd, &st);
> > > > > +close(reset_fd);
> > > > > +
> > > > > +if (rc || !S_ISREG(st.st_mode))
> > > > > +return false;
> > > > > +
> > > > > +return true;
> > > > > +}
> > > > > +
> > > > > +/* Unbind the driver from the device */
> > > > > +static void driver_unbind(struct sysfs_fds *sysfs)
> > > > > +{
> > > > > +igt_debug("unbind the driver from the device\n");
> > > > > +igt_assert(igt_sysfs_set(sysfs->fds.drv_dir, "unbind",
> > > > > +   sysfs->dev_bus_addr));
> > > > > +}
> > > > > +
> > > > > +/* Re-bind the driver to the device */
> > > > > +static void driver_bind(struct sysfs_fds *sysfs)
> > > > > +{
> > > > > +igt_debug("rebind the driver to the device\n");
> > > > > +igt_abort_on_f(!igt_sysfs_set(sysfs->fds.drv_dir, "bind",
> > > > > +       sysfs->dev_bus_addr), "driver rebind failed");
> > > > > +}
> > > > > +
> > > > > +/* Initiate device reset */
> > > > > +static void initiate_device_reset(struct sysfs_fds *sysfs)
> > > > > +{
> > > > > +igt_debug("reset device\n");
> > > > > +igt_assert(igt_sysfs_set(sysfs->fds.dev_dir, "reset", "1"));
> > > > > +}
> > > > > +
> > > > > +/**
> > > > > + * healthcheck:
> > > > > + * @sysfs: structure with device descriptor, if descriptor
> > > > > equals
> > > > > -1
> > > > > + *    the device is reopened
> > > > > + */
> > > > > +static void healthcheck(struct sysfs_fds *sysfs)
> > > > > +{
> > > > > +open_if_closed(sysfs);
> > > > > +gem_test_engine(sysfs->fds.dev, ALL_ENGINES);
> > > >
> > > > This test is located in tests/ and looks like could be applicable
> > > > to
> > > > any
> > > > device. If that is true - gem_test_engine is from i915 familiy.
> > > > Is
> > > > there a way
> > > > to test engines for any driver? Naming is one thing, but what if
> > > > amd
> > > > card will
> > > > try to execute engines with i915 functions?
> > > >
> > > > Kasia
> > >
> > > healthcheck is used in subtest_group where igt_require_intel is
> > > prerequisite, so the tests will be skipped on non intel platforms
> >
> > In that case test should be moved to tests/i915 dir than?
> > Kasia
> 
> Following tests may be executed on ANY_DEVICE:
> unbind-rebind
> unbind-reset-rebind
> reset-bound
> 
> the versions with *-healthcheck will skip on non intel platfroms.
> 
> Should I move them to separate binary under tests/i915 dir ?
It seems resonable, but I would ask on IRC first to clarify that :)
I am not so active on this ML lately :)
Kasia
> 
> > >
> > > > > +}
> > > > > +
> > > > > +/**
> > > > > + * set_device_filter:
> > > > > + *
> > > > > + * Sets device filter to ensure subtests always reopen the
> > > > > same
> > > > > device
> > > > > + *
> > > > > + * @dev_path: path to device under tests
> > > > > + */
> > > > > +static void set_device_filter(const char* dev_path)
> > > > > +{
> > > > > +char filter[strlen("sys:") + strlen(dev_path) + 1];
> > > > > +
> > > > > +snprintf(filter, sizeof(filter), "sys:%s", dev_path);
> > > > > +igt_device_filter_free_all();
> > > > > +igt_assert_eq(igt_device_filter_add(filter), 1);
> > > > > +}
> > > > > +
> > > > > +static void unbind_rebind(struct sysfs_fds *sysfs)
> > > > > +{
> > > > > +igt_debug("close the device\n");
> > > > > +close_if_opened(&sysfs->fds.dev);
> > > > > +
> > > > > +driver_unbind(sysfs);
> > > > > +
> > > > > +driver_bind(sysfs);
> > > > > +}
> > > > > +
> > > > > +static void unbind_reset_rebind(struct sysfs_fds *sysfs)
> > > > > +{
> > > > > +igt_debug("close the device\n");
> > > > > +close_if_opened(&sysfs->fds.dev);
> > > > > +
> > > > > +driver_unbind(sysfs);
> > > > > +
> > > > > +initiate_device_reset(sysfs);
> > > > > +
> > > > > +driver_bind(sysfs);
> > > > > +}
> > > > > +
> > > > > +igt_main
> > > > > +{
> > > > > +struct sysfs_fds sysfs;
> > > > > +
> > > > > +igt_fixture {
> > > > > +char dev_path[PATH_MAX];
> > > > > +
> > > > > +igt_debug("opening device\n");
> > > > > +init_sysfs_fds(&sysfs);
> > > > > +
> > > > > +/* Make sure subtests always reopen the same device */
> > > > > +igt_assert(device_sysfs_path(sysfs.fds.dev, dev_path));
> > > > > +set_device_filter(dev_path);
> > > > > +
> > > > > +igt_skip_on(!is_sysfs_reset_supported(sysfs.fds.dev));
> > > > > +
> > > > > +igt_set_timeout(60, "device reset tests timed out after
> > > > > 60s");
> > > > > +}
> > > > > +
> > > > > +igt_describe("Tests driver unbind from/rebind to device
> > > > > sequence");
> > > > > +igt_subtest("unbind-rebind")
> > > > > +unbind_rebind(&sysfs);
> > > > > +
> > > > > +igt_describe("Unbinds driver from device, initiates reset"
> > > > > +     " then rebinds driver to device");
> > > > > +igt_subtest("unbind-reset-rebind")
> > > > > +unbind_reset_rebind(&sysfs);
> > > > > +
> > > > > +igt_describe("Resets device with bound driver");
> > > > > +igt_subtest("reset-bound")
> > > > > +initiate_device_reset(&sysfs);
> > > > > +
> > > > > +igt_describe("Subtests with additional healthchecks");
> > > > > +igt_subtest_group {
> > > > > +igt_fixture {
> > > > > +open_if_closed(&sysfs);
> > > > > +igt_require_intel(sysfs.fds.dev);
> > > > > +}
> > > > > +
> > > > > +igt_subtest("healthcheck")
> > > > > +healthcheck(&sysfs);
> > > > > +
> > > > > +igt_subtest("unbind-reset-rebind-healthcheck") {
> > > > > +unbind_reset_rebind(&sysfs);
> > > > > +healthcheck(&sysfs);
> > > > > +}
> > > > > +
> > > > > +igt_subtest("reset-bound-healthcheck") {
> > > > > +initiate_device_reset(&sysfs);
> > > > > +healthcheck(&sysfs);
> > > > > +}
> > > > > +}
> > > > > +
> > > > > +igt_fixture {
> > > > > +igt_reset_timeout();
> > > > > +cleanup_sysfs_fds(&sysfs);
> > > > > +}
> > > > > +}
> > > > > diff --git a/tests/meson.build b/tests/meson.build
> > > > > index 28091794f..b0acdf7c0 100644
> > > > > --- a/tests/meson.build
> > > > > +++ b/tests/meson.build
> > > > > @@ -8,6 +8,7 @@ test_progs = [
> > > > >  'core_setmaster_vs_auth',
> > > > >  'debugfs_test',
> > > > >  'dmabuf',
> > > > > +'device_reset',
> > > > >  'drm_import_export',
> > > > >  'drm_mm',
> > > > >  'drm_read',
> > > > > --
> > > > > 2.25.1
> > > > >
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [igt-dev] [RFC, i-g-t] tests/device_reset: Test device sysfs reset
  2020-06-26 10:23       ` Bernatowicz, Marcin
  2020-06-26 10:48         ` Katarzyna Dec
@ 2020-06-26 11:35         ` Janusz Krzysztofik
  2020-06-29  8:53           ` Bernatowicz, Marcin
  1 sibling, 1 reply; 9+ messages in thread
From: Janusz Krzysztofik @ 2020-06-26 11:35 UTC (permalink / raw)
  To: Bernatowicz, Marcin, Dec, Katarzyna, igt-dev
  Cc: Winiarski, Michal, Vivi, Rodrigo

On Fri, 2020-06-26 at 10:23 +0000, Bernatowicz, Marcin wrote:
> On Fri, 2020-06-26 at 11:19 +0200, Katarzyna Dec wrote:
> > On Fri, Jun 26, 2020 at 09:55:09AM +0100, Bernatowicz, Marcin wrote:
> > > On Fri, 2020-06-26 at 10:47 +0200, Katarzyna Dec wrote:
> > > > On Fri, Jun 26, 2020 at 08:30:45AM +0200, Marcin Bernatowicz
> > > > wrote:
> > > > > Device reset is initiated by writing "1" to reset sysfs file,
> > > > > which should initiatie device FLR if supported by device.
> > > > > 
> > > > > Test scenarios:
> > > > > 1. unbind driver from device then rebind
> > > > > 2. unbind driver from device, initiate sysfs reset, rebind
> > > > > driver
> > > > > to
> > > > > device
> > > > > 3. device reset with bound driver
> > > > > 
> > > > > Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@intel.com
> > > > > ---
> > > > >  tests/device_reset.c | 298
> > > > > +++++++++++++++++++++++++++++++++++++++++++
> > > > >  tests/meson.build    |   1 +
> > > > >  2 files changed, 299 insertions(+)
> > > > >  create mode 100644 tests/device_reset.c
> > > > > 
> > > > > diff --git a/tests/device_reset.c b/tests/device_reset.c
> > > > > new file mode 100644
> > > > > index 000000000..bafe9fd41
> > > > > --- /dev/null
> > > > > +++ b/tests/device_reset.c
> > > > > @@ -0,0 +1,298 @@
> > > > > +// SPDX-License-Identifier: MIT
> > > > > +/*
> > > > > + * Copyright(c) 2020 Intel Corporation. All rights reserved.
> > > > > + */
> > > > > +
> > > > > +#include <fcntl.h>
> > > > > +#include <sys/stat.h>
> > > > > +#include "igt.h"
> > > > > +#include "igt_device_scan.h"
> > > > > +#include "igt_sysfs.h"
> > > > > +
> > > > > +IGT_TEST_DESCRIPTION("Examine behavior of a driver on device
> > > > > sysfs
> > > > > reset");
> > > > > +
> > > > > +
> > > > > +#define DEV_PATH_LEN 80
> > > > > +#define DEV_BUS_ADDR_LEN 13 /* addr has form 0000:00:00.0 */
> > > > > +
> > > > > +/**
> > > > > + * Helper structure containing sysfs file descriptors
> > > > > + * and path related to tested device
> > > > > + */
> > > > > +struct sysfs_fds {
> > > > > +struct {
> > > > > +int dev;
> > > > > +int dev_dir;
> > > > > +int drv_dir;
> > > > > +} fds;
> > > > > +char dev_bus_addr[DEV_BUS_ADDR_LEN];
> > > > > +};
> > > > > +
> > > > > +static int __open_sysfs_dir(int fd, const char* path)
> > > > > +{
> > > > > +int sysfs;
> > > > > +
> > > > > +sysfs = igt_sysfs_open(fd);
> > > > > +if (sysfs < 0) {
> > > > > +return -1;
> > > > > +}
> > > > > +
> > > > > +return openat(sysfs, path, O_DIRECTORY);
> > > > > +}
> > > > > +
> > > > > +static int open_device_sysfs_dir(int fd)
> > > > > +{
> > > > > +return __open_sysfs_dir(fd, "device");
> > > > > +}
> > > > > +
> > > > > +static int open_driver_sysfs_dir(int fd)
> > > > > +{
> > > > > +return __open_sysfs_dir(fd, "device/driver");
> > > > > +}
> > > > > +
> > > > > +/**
> > > > > + * device_sysfs_path:
> > > > > + * @fd: opened device file descriptor
> > > > > + * @path: buffer to store sysfs path to device directory
> > > > > + *
> > > > > + * Returns:
> > > > > + * On successfull path resolution sysfs path to device
> > > > > directory,
> > > > > + * NULL otherwise
> > > > > + */
> > > > > +static char *device_sysfs_path(int fd, char *path)
> > > > > +{
> > > > > +char sysfs[DEV_PATH_LEN];
> > > > > +
> > > > > +if (!igt_sysfs_path(fd, sysfs, sizeof(sysfs)))
> > > > > +return NULL;
> > > > > +
> > > > > +if (DEV_PATH_LEN <= (strlen(sysfs) + strlen("/device")))
> > > > > +return NULL;
> > > > > +
> > > > > +strcat(sysfs, "/device");
> > > > > +
> > > > > +return realpath(sysfs, path);
> > > > > +}
> > > > > +
> > > > > +static void init_sysfs_fds(struct sysfs_fds *sysfs)
> > > > > +{
> > > > > +char dev_path[PATH_MAX];
> > > > > +char *addr_pos;
> > > > > +
> > > > > +igt_debug("open device\n");
> > > > > +/**
> > > > > + * As subtests must be able to close examined devices
> > > > > + * completely, don't use drm_open_driver() as it keeps
> > > > > + * a device file descriptor open for exit handler use.
> > > > > + */
> > > > > +sysfs->fds.dev = __drm_open_driver(DRIVER_ANY);
> > > > > +igt_assert_fd(sysfs->fds.dev);
> > > > > +
> > > > > +igt_assert(device_sysfs_path(sysfs->fds.dev, dev_path));
> > > > > +addr_pos = strrchr(dev_path, '/');
> > > > > +snprintf(sysfs->dev_bus_addr, sizeof(sysfs->dev_bus_addr),
> > > > > + "%s", (addr_pos ? addr_pos + 1 : ""));
> > > > > +igt_assert(sysfs->dev_bus_addr[0]);
> > > > > +
> > > > > +sysfs->fds.dev_dir = open_device_sysfs_dir(sysfs->fds.dev);
> > > > > +igt_assert_fd(sysfs->fds.dev_dir);
> > > > > +
> > > > > +sysfs->fds.drv_dir = open_driver_sysfs_dir(sysfs->fds.dev);
> > > > > +igt_assert_fd(sysfs->fds.drv_dir);
> > > > > +}
> > > > > +
> > > > > +static int close_if_opened(int *fd)
> > > > > +{
> > > > > +int rc = 0;
> > > > > +if (fd && *fd != -1) {
> > > > > +rc = close(*fd);
> > > > > +*fd = -1;
> > > > > +}
> > > > > +return rc;
> > > > > +}
> > > > > +
> > > > > +static void open_if_closed(struct sysfs_fds *sysfs)
> > > > > +{
> > > > > +if (sysfs->fds.dev == -1) {
> > > > > +/* refresh device list */
> > > > > +igt_devices_scan(true);
> > > > > +igt_debug("reopen the device\n");
> > > > > +sysfs->fds.dev = __drm_open_driver(DRIVER_ANY);
> > > > > +}
> > > > > +igt_assert_fd(sysfs->fds.dev);
> > > > > +}
> > > > > +
> > > > > +static void cleanup_sysfs_fds(struct sysfs_fds *sysfs)
> > > > > +{
> > > > > +close_if_opened(&sysfs->fds.dev);
> > > > > +close_if_opened(&sysfs->fds.dev_dir);
> > > > > +close_if_opened(&sysfs->fds.drv_dir);
> > > > > +sysfs->dev_bus_addr[0] = '\0';
> > > > > +}
> > > > > +
> > > > > +
> > > > > +/**
> > > > > + * is_sysfs_reset_supported:
> > > > > + * @fd: opened device file descriptor
> > > > > + *
> > > > > + * Check if device supports reset based on sysfs file
> > > > > presence.
> > > > > + *
> > > > > + * Returns:
> > > > > + * True if device supports reset, false otherwise.
> > > > > + */
> > > > > +static bool is_sysfs_reset_supported(int fd)
> > > > > +{
> > > > > +struct stat st;
> > > > > +int rc;
> > > > > +int sysfs;
> > > > > +int reset_fd = -1;
> > > > > +
> > > > > +sysfs = igt_sysfs_open(fd);
> > > > > +
> > > > > +if (sysfs >= 0) {
> > > > > +reset_fd = openat(sysfs, "device/reset", O_WRONLY);
> > > > > +close(sysfs);
> > > > > +}
> > > > > +
> > > > > +if (reset_fd < 0)
> > > > > +return false;
> > > > > +
> > > > > +rc = fstat(reset_fd, &st);
> > > > > +close(reset_fd);
> > > > > +
> > > > > +if (rc || !S_ISREG(st.st_mode))
> > > > > +return false;
> > > > > +
> > > > > +return true;
> > > > > +}
> > > > > +
> > > > > +/* Unbind the driver from the device */
> > > > > +static void driver_unbind(struct sysfs_fds *sysfs)
> > > > > +{
> > > > > +igt_debug("unbind the driver from the device\n");
> > > > > +igt_assert(igt_sysfs_set(sysfs->fds.drv_dir, "unbind",
> > > > > +   sysfs->dev_bus_addr));
> > > > > +}
> > > > > +
> > > > > +/* Re-bind the driver to the device */
> > > > > +static void driver_bind(struct sysfs_fds *sysfs)
> > > > > +{
> > > > > +igt_debug("rebind the driver to the device\n");
> > > > > +igt_abort_on_f(!igt_sysfs_set(sysfs->fds.drv_dir, "bind",
> > > > > +       sysfs->dev_bus_addr), "driver rebind failed");
> > > > > +}
> > > > > +
> > > > > +/* Initiate device reset */
> > > > > +static void initiate_device_reset(struct sysfs_fds *sysfs)
> > > > > +{
> > > > > +igt_debug("reset device\n");
> > > > > +igt_assert(igt_sysfs_set(sysfs->fds.dev_dir, "reset", "1"));
> > > > > +}
> > > > > +
> > > > > +/**
> > > > > + * healthcheck:
> > > > > + * @sysfs: structure with device descriptor, if descriptor
> > > > > equals
> > > > > -1
> > > > > + *    the device is reopened
> > > > > + */
> > > > > +static void healthcheck(struct sysfs_fds *sysfs)
> > > > > +{
> > > > > +open_if_closed(sysfs);
> > > > > +gem_test_engine(sysfs->fds.dev, ALL_ENGINES);
> > > > 
> > > > This test is located in tests/ and looks like could be applicable
> > > > to
> > > > any
> > > > device. If that is true - gem_test_engine is from i915 familiy.
> > > > Is
> > > > there a way
> > > > to test engines for any driver? Naming is one thing, but what if
> > > > amd
> > > > card will
> > > > try to execute engines with i915 functions?
> > > > 
> > > > Kasia
> > > 
> > > healthcheck is used in subtest_group where igt_require_intel is
> > > prerequisite, so the tests will be skipped on non intel platforms
> > 
> > In that case test should be moved to tests/i915 dir than?
> > Kasia
> 
> Following tests may be executed on ANY_DEVICE:
> unbind-rebind
> unbind-reset-rebind
> reset-bound
> 
> the versions with *-healthcheck will skip on non intel platfroms.

AFAICT, CI expects each test to leave the exercised device in a usable
state (driver bound, GPU not wedged).  If not, the test should exit via
igt_abort(), unless TAINT_WARN flag in /proc/sys/kernel/tainted is
raised by the driver on unsuccessful GPU reset.  Then, I think you
should perform a final healthcheck from each subtest. 
gem_test_engine() should be called conditionally if intel graphics is
detected, other platforms can add their specific checks as needed.

Thanks,
Janusz

> 
> Should I move them to separate binary under tests/i915 dir ?
> 
> > > > > +}
> > > > > +
> > > > > +/**
> > > > > + * set_device_filter:
> > > > > + *
> > > > > + * Sets device filter to ensure subtests always reopen the
> > > > > same
> > > > > device
> > > > > + *
> > > > > + * @dev_path: path to device under tests
> > > > > + */
> > > > > +static void set_device_filter(const char* dev_path)
> > > > > +{
> > > > > +char filter[strlen("sys:") + strlen(dev_path) + 1];
> > > > > +
> > > > > +snprintf(filter, sizeof(filter), "sys:%s", dev_path);
> > > > > +igt_device_filter_free_all();
> > > > > +igt_assert_eq(igt_device_filter_add(filter), 1);
> > > > > +}
> > > > > +
> > > > > +static void unbind_rebind(struct sysfs_fds *sysfs)
> > > > > +{
> > > > > +igt_debug("close the device\n");
> > > > > +close_if_opened(&sysfs->fds.dev);
> > > > > +
> > > > > +driver_unbind(sysfs);
> > > > > +
> > > > > +driver_bind(sysfs);
> > > > > +}
> > > > > +
> > > > > +static void unbind_reset_rebind(struct sysfs_fds *sysfs)
> > > > > +{
> > > > > +igt_debug("close the device\n");
> > > > > +close_if_opened(&sysfs->fds.dev);
> > > > > +
> > > > > +driver_unbind(sysfs);
> > > > > +
> > > > > +initiate_device_reset(sysfs);
> > > > > +
> > > > > +driver_bind(sysfs);
> > > > > +}
> > > > > +
> > > > > +igt_main
> > > > > +{
> > > > > +struct sysfs_fds sysfs;
> > > > > +
> > > > > +igt_fixture {
> > > > > +char dev_path[PATH_MAX];
> > > > > +
> > > > > +igt_debug("opening device\n");
> > > > > +init_sysfs_fds(&sysfs);
> > > > > +
> > > > > +/* Make sure subtests always reopen the same device */
> > > > > +igt_assert(device_sysfs_path(sysfs.fds.dev, dev_path));
> > > > > +set_device_filter(dev_path);
> > > > > +
> > > > > +igt_skip_on(!is_sysfs_reset_supported(sysfs.fds.dev));
> > > > > +
> > > > > +igt_set_timeout(60, "device reset tests timed out after
> > > > > 60s");
> > > > > +}
> > > > > +
> > > > > +igt_describe("Tests driver unbind from/rebind to device
> > > > > sequence");
> > > > > +igt_subtest("unbind-rebind")
> > > > > +unbind_rebind(&sysfs);
> > > > > +
> > > > > +igt_describe("Unbinds driver from device, initiates reset"
> > > > > +     " then rebinds driver to device");
> > > > > +igt_subtest("unbind-reset-rebind")
> > > > > +unbind_reset_rebind(&sysfs);
> > > > > +
> > > > > +igt_describe("Resets device with bound driver");
> > > > > +igt_subtest("reset-bound")
> > > > > +initiate_device_reset(&sysfs);
> > > > > +
> > > > > +igt_describe("Subtests with additional healthchecks");
> > > > > +igt_subtest_group {
> > > > > +igt_fixture {
> > > > > +open_if_closed(&sysfs);
> > > > > +igt_require_intel(sysfs.fds.dev);
> > > > > +}
> > > > > +
> > > > > +igt_subtest("healthcheck")
> > > > > +healthcheck(&sysfs);
> > > > > +
> > > > > +igt_subtest("unbind-reset-rebind-healthcheck") {
> > > > > +unbind_reset_rebind(&sysfs);
> > > > > +healthcheck(&sysfs);
> > > > > +}
> > > > > +
> > > > > +igt_subtest("reset-bound-healthcheck") {
> > > > > +initiate_device_reset(&sysfs);
> > > > > +healthcheck(&sysfs);
> > > > > +}
> > > > > +}
> > > > > +
> > > > > +igt_fixture {
> > > > > +igt_reset_timeout();
> > > > > +cleanup_sysfs_fds(&sysfs);
> > > > > +}
> > > > > +}
> > > > > diff --git a/tests/meson.build b/tests/meson.build
> > > > > index 28091794f..b0acdf7c0 100644
> > > > > --- a/tests/meson.build
> > > > > +++ b/tests/meson.build
> > > > > @@ -8,6 +8,7 @@ test_progs = [
> > > > >  'core_setmaster_vs_auth',
> > > > >  'debugfs_test',
> > > > >  'dmabuf',
> > > > > +'device_reset',
> > > > >  'drm_import_export',
> > > > >  'drm_mm',
> > > > >  'drm_read',
> > > > > --
> > > > > 2.25.1
> > > > > 

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [igt-dev] ✓ Fi.CI.BAT: success for tests/device_reset: Test device sysfs reset
  2020-06-26  6:30 [igt-dev] [RFC,i-g-t] tests/device_reset: Test device sysfs reset Marcin Bernatowicz
  2020-06-26  8:47 ` [igt-dev] [RFC, i-g-t] " Katarzyna Dec
@ 2020-06-26 13:49 ` Patchwork
  1 sibling, 0 replies; 9+ messages in thread
From: Patchwork @ 2020-06-26 13:49 UTC (permalink / raw)
  To: Bernatowicz, Marcin; +Cc: igt-dev

== Series Details ==

Series: tests/device_reset: Test device sysfs reset
URL   : https://patchwork.freedesktop.org/series/78849/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_8667 -> IGTPW_4707
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4707/index.html

Known issues
------------

  Here are the changes found in IGTPW_4707 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_exec_suspend@basic-s3:
    - fi-tgl-u2:          [PASS][1] -> [FAIL][2] ([i915#1888])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8667/fi-tgl-u2/igt@gem_exec_suspend@basic-s3.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4707/fi-tgl-u2/igt@gem_exec_suspend@basic-s3.html

  * igt@i915_pm_rpm@basic-pci-d3-state:
    - fi-bsw-kefka:       [PASS][3] -> [DMESG-WARN][4] ([i915#1982])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8667/fi-bsw-kefka/igt@i915_pm_rpm@basic-pci-d3-state.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4707/fi-bsw-kefka/igt@i915_pm_rpm@basic-pci-d3-state.html

  * igt@kms_cursor_legacy@basic-flip-after-cursor-atomic:
    - fi-icl-u2:          [PASS][5] -> [DMESG-WARN][6] ([i915#1982])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8667/fi-icl-u2/igt@kms_cursor_legacy@basic-flip-after-cursor-atomic.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4707/fi-icl-u2/igt@kms_cursor_legacy@basic-flip-after-cursor-atomic.html

  * igt@kms_psr@primary_mmap_gtt:
    - fi-tgl-y:           [PASS][7] -> [DMESG-WARN][8] ([i915#1982])
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8667/fi-tgl-y/igt@kms_psr@primary_mmap_gtt.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4707/fi-tgl-y/igt@kms_psr@primary_mmap_gtt.html

  * igt@vgem_basic@setversion:
    - fi-tgl-y:           [PASS][9] -> [DMESG-WARN][10] ([i915#402]) +1 similar issue
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8667/fi-tgl-y/igt@vgem_basic@setversion.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4707/fi-tgl-y/igt@vgem_basic@setversion.html

  
#### Possible fixes ####

  * igt@kms_pipe_crc_basic@read-crc-pipe-a-frame-sequence:
    - fi-tgl-u2:          [DMESG-WARN][11] ([i915#402]) -> [PASS][12] +1 similar issue
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8667/fi-tgl-u2/igt@kms_pipe_crc_basic@read-crc-pipe-a-frame-sequence.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4707/fi-tgl-u2/igt@kms_pipe_crc_basic@read-crc-pipe-a-frame-sequence.html

  * igt@prime_self_import@basic-with_two_bos:
    - fi-tgl-y:           [DMESG-WARN][13] ([i915#402]) -> [PASS][14] +2 similar issues
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8667/fi-tgl-y/igt@prime_self_import@basic-with_two_bos.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4707/fi-tgl-y/igt@prime_self_import@basic-with_two_bos.html

  
#### Warnings ####

  * igt@debugfs_test@read_all_entries:
    - fi-kbl-x1275:       [DMESG-WARN][15] ([i915#62] / [i915#92]) -> [DMESG-WARN][16] ([i915#62] / [i915#92] / [i915#95]) +3 similar issues
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8667/fi-kbl-x1275/igt@debugfs_test@read_all_entries.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4707/fi-kbl-x1275/igt@debugfs_test@read_all_entries.html

  * igt@kms_flip@basic-flip-vs-dpms@a-dp1:
    - fi-kbl-x1275:       [DMESG-WARN][17] ([i915#62] / [i915#92] / [i915#95]) -> [DMESG-WARN][18] ([i915#62] / [i915#92]) +1 similar issue
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8667/fi-kbl-x1275/igt@kms_flip@basic-flip-vs-dpms@a-dp1.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4707/fi-kbl-x1275/igt@kms_flip@basic-flip-vs-dpms@a-dp1.html

  * igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a:
    - fi-kbl-x1275:       [DMESG-WARN][19] ([i915#1982] / [i915#62] / [i915#92]) -> [DMESG-WARN][20] ([i915#62] / [i915#92])
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8667/fi-kbl-x1275/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4707/fi-kbl-x1275/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [i915#1888]: https://gitlab.freedesktop.org/drm/intel/issues/1888
  [i915#1982]: https://gitlab.freedesktop.org/drm/intel/issues/1982
  [i915#402]: https://gitlab.freedesktop.org/drm/intel/issues/402
  [i915#62]: https://gitlab.freedesktop.org/drm/intel/issues/62
  [i915#92]: https://gitlab.freedesktop.org/drm/intel/issues/92
  [i915#95]: https://gitlab.freedesktop.org/drm/intel/issues/95


Participating hosts (46 -> 39)
------------------------------

  Missing    (7): fi-ilk-m540 fi-hsw-4200u fi-byt-squawks fi-bsw-cyan fi-ctg-p8600 fi-byt-clapper fi-bdw-samus 


Build changes
-------------

  * CI: CI-20190529 -> None
  * IGT: IGT_5718 -> IGTPW_4707

  CI-20190529: 20190529
  CI_DRM_8667: 57a1fc457c260002189382a406e920465d540d53 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_4707: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4707/index.html
  IGT_5718: af1ef32bfae90bcdbaf1b5d84c61ff4e04368505 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools



== Testlist changes ==

+igt@device_reset@healthcheck
+igt@device_reset@reset-bound
+igt@device_reset@reset-bound-healthcheck
+igt@device_reset@unbind-rebind
+igt@device_reset@unbind-reset-rebind
+igt@device_reset@unbind-reset-rebind-healthcheck

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4707/index.html
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [igt-dev] [RFC, i-g-t] tests/device_reset: Test device sysfs reset
  2020-06-26 11:35         ` Janusz Krzysztofik
@ 2020-06-29  8:53           ` Bernatowicz, Marcin
  0 siblings, 0 replies; 9+ messages in thread
From: Bernatowicz, Marcin @ 2020-06-29  8:53 UTC (permalink / raw)
  To: Dec, Katarzyna, igt-dev, janusz.krzysztofik
  Cc: Winiarski, Michal, Vivi, Rodrigo

On Fri, 2020-06-26 at 13:35 +0200, Janusz Krzysztofik wrote:
> On Fri, 2020-06-26 at 10:23 +0000, Bernatowicz, Marcin wrote:
> > On Fri, 2020-06-26 at 11:19 +0200, Katarzyna Dec wrote:
> > > On Fri, Jun 26, 2020 at 09:55:09AM +0100, Bernatowicz, Marcin
> > > wrote:
> > > > On Fri, 2020-06-26 at 10:47 +0200, Katarzyna Dec wrote:
> > > > > On Fri, Jun 26, 2020 at 08:30:45AM +0200, Marcin Bernatowicz
> > > > > wrote:
> > > > > > Device reset is initiated by writing "1" to reset sysfs
> > > > > > file,
> > > > > > which should initiatie device FLR if supported by device.
> > > > > > 
> > > > > > Test scenarios:
> > > > > > 1. unbind driver from device then rebind
> > > > > > 2. unbind driver from device, initiate sysfs reset, rebind
> > > > > > driver
> > > > > > to
> > > > > > device
> > > > > > 3. device reset with bound driver
> > > > > > 
> > > > > > Signed-off-by: Marcin Bernatowicz <
> > > > > > marcin.bernatowicz@intel.com
> > > > > > ---
> > > > > >  tests/device_reset.c | 298
> > > > > > +++++++++++++++++++++++++++++++++++++++++++
> > > > > >  tests/meson.build    |   1 +
> > > > > >  2 files changed, 299 insertions(+)
> > > > > >  create mode 100644 tests/device_reset.c
> > > > > > 
> > > > > > diff --git a/tests/device_reset.c b/tests/device_reset.c
> > > > > > new file mode 100644
> > > > > > index 000000000..bafe9fd41
> > > > > > --- /dev/null
> > > > > > +++ b/tests/device_reset.c
> > > > > > @@ -0,0 +1,298 @@
> > > > > > +// SPDX-License-Identifier: MIT
> > > > > > +/*
> > > > > > + * Copyright(c) 2020 Intel Corporation. All rights
> > > > > > reserved.
> > > > > > + */
> > > > > > +
> > > > > > +#include <fcntl.h>
> > > > > > +#include <sys/stat.h>
> > > > > > +#include "igt.h"
> > > > > > +#include "igt_device_scan.h"
> > > > > > +#include "igt_sysfs.h"
> > > > > > +
> > > > > > +IGT_TEST_DESCRIPTION("Examine behavior of a driver on
> > > > > > device
> > > > > > sysfs
> > > > > > reset");
> > > > > > +
> > > > > > +
> > > > > > +#define DEV_PATH_LEN 80
> > > > > > +#define DEV_BUS_ADDR_LEN 13 /* addr has form 0000:00:00.0
> > > > > > */
> > > > > > +
> > > > > > +/**
> > > > > > + * Helper structure containing sysfs file descriptors
> > > > > > + * and path related to tested device
> > > > > > + */
> > > > > > +struct sysfs_fds {
> > > > > > +struct {
> > > > > > +int dev;
> > > > > > +int dev_dir;
> > > > > > +int drv_dir;
> > > > > > +} fds;
> > > > > > +char dev_bus_addr[DEV_BUS_ADDR_LEN];
> > > > > > +};
> > > > > > +
> > > > > > +static int __open_sysfs_dir(int fd, const char* path)
> > > > > > +{
> > > > > > +int sysfs;
> > > > > > +
> > > > > > +sysfs = igt_sysfs_open(fd);
> > > > > > +if (sysfs < 0) {
> > > > > > +return -1;
> > > > > > +}
> > > > > > +
> > > > > > +return openat(sysfs, path, O_DIRECTORY);
> > > > > > +}
> > > > > > +
> > > > > > +static int open_device_sysfs_dir(int fd)
> > > > > > +{
> > > > > > +return __open_sysfs_dir(fd, "device");
> > > > > > +}
> > > > > > +
> > > > > > +static int open_driver_sysfs_dir(int fd)
> > > > > > +{
> > > > > > +return __open_sysfs_dir(fd, "device/driver");
> > > > > > +}
> > > > > > +
> > > > > > +/**
> > > > > > + * device_sysfs_path:
> > > > > > + * @fd: opened device file descriptor
> > > > > > + * @path: buffer to store sysfs path to device directory
> > > > > > + *
> > > > > > + * Returns:
> > > > > > + * On successfull path resolution sysfs path to device
> > > > > > directory,
> > > > > > + * NULL otherwise
> > > > > > + */
> > > > > > +static char *device_sysfs_path(int fd, char *path)
> > > > > > +{
> > > > > > +char sysfs[DEV_PATH_LEN];
> > > > > > +
> > > > > > +if (!igt_sysfs_path(fd, sysfs, sizeof(sysfs)))
> > > > > > +return NULL;
> > > > > > +
> > > > > > +if (DEV_PATH_LEN <= (strlen(sysfs) + strlen("/device")))
> > > > > > +return NULL;
> > > > > > +
> > > > > > +strcat(sysfs, "/device");
> > > > > > +
> > > > > > +return realpath(sysfs, path);
> > > > > > +}
> > > > > > +
> > > > > > +static void init_sysfs_fds(struct sysfs_fds *sysfs)
> > > > > > +{
> > > > > > +char dev_path[PATH_MAX];
> > > > > > +char *addr_pos;
> > > > > > +
> > > > > > +igt_debug("open device\n");
> > > > > > +/**
> > > > > > + * As subtests must be able to close examined devices
> > > > > > + * completely, don't use drm_open_driver() as it keeps
> > > > > > + * a device file descriptor open for exit handler use.
> > > > > > + */
> > > > > > +sysfs->fds.dev = __drm_open_driver(DRIVER_ANY);
> > > > > > +igt_assert_fd(sysfs->fds.dev);
> > > > > > +
> > > > > > +igt_assert(device_sysfs_path(sysfs->fds.dev, dev_path));
> > > > > > +addr_pos = strrchr(dev_path, '/');
> > > > > > +snprintf(sysfs->dev_bus_addr, sizeof(sysfs->dev_bus_addr),
> > > > > > + "%s", (addr_pos ? addr_pos + 1 : ""));
> > > > > > +igt_assert(sysfs->dev_bus_addr[0]);
> > > > > > +
> > > > > > +sysfs->fds.dev_dir = open_device_sysfs_dir(sysfs-
> > > > > > >fds.dev);
> > > > > > +igt_assert_fd(sysfs->fds.dev_dir);
> > > > > > +
> > > > > > +sysfs->fds.drv_dir = open_driver_sysfs_dir(sysfs-
> > > > > > >fds.dev);
> > > > > > +igt_assert_fd(sysfs->fds.drv_dir);
> > > > > > +}
> > > > > > +
> > > > > > +static int close_if_opened(int *fd)
> > > > > > +{
> > > > > > +int rc = 0;
> > > > > > +if (fd && *fd != -1) {
> > > > > > +rc = close(*fd);
> > > > > > +*fd = -1;
> > > > > > +}
> > > > > > +return rc;
> > > > > > +}
> > > > > > +
> > > > > > +static void open_if_closed(struct sysfs_fds *sysfs)
> > > > > > +{
> > > > > > +if (sysfs->fds.dev == -1) {
> > > > > > +/* refresh device list */
> > > > > > +igt_devices_scan(true);
> > > > > > +igt_debug("reopen the device\n");
> > > > > > +sysfs->fds.dev = __drm_open_driver(DRIVER_ANY);
> > > > > > +}
> > > > > > +igt_assert_fd(sysfs->fds.dev);
> > > > > > +}
> > > > > > +
> > > > > > +static void cleanup_sysfs_fds(struct sysfs_fds *sysfs)
> > > > > > +{
> > > > > > +close_if_opened(&sysfs->fds.dev);
> > > > > > +close_if_opened(&sysfs->fds.dev_dir);
> > > > > > +close_if_opened(&sysfs->fds.drv_dir);
> > > > > > +sysfs->dev_bus_addr[0] = '\0';
> > > > > > +}
> > > > > > +
> > > > > > +
> > > > > > +/**
> > > > > > + * is_sysfs_reset_supported:
> > > > > > + * @fd: opened device file descriptor
> > > > > > + *
> > > > > > + * Check if device supports reset based on sysfs file
> > > > > > presence.
> > > > > > + *
> > > > > > + * Returns:
> > > > > > + * True if device supports reset, false otherwise.
> > > > > > + */
> > > > > > +static bool is_sysfs_reset_supported(int fd)
> > > > > > +{
> > > > > > +struct stat st;
> > > > > > +int rc;
> > > > > > +int sysfs;
> > > > > > +int reset_fd = -1;
> > > > > > +
> > > > > > +sysfs = igt_sysfs_open(fd);
> > > > > > +
> > > > > > +if (sysfs >= 0) {
> > > > > > +reset_fd = openat(sysfs, "device/reset", O_WRONLY);
> > > > > > +close(sysfs);
> > > > > > +}
> > > > > > +
> > > > > > +if (reset_fd < 0)
> > > > > > +return false;
> > > > > > +
> > > > > > +rc = fstat(reset_fd, &st);
> > > > > > +close(reset_fd);
> > > > > > +
> > > > > > +if (rc || !S_ISREG(st.st_mode))
> > > > > > +return false;
> > > > > > +
> > > > > > +return true;
> > > > > > +}
> > > > > > +
> > > > > > +/* Unbind the driver from the device */
> > > > > > +static void driver_unbind(struct sysfs_fds *sysfs)
> > > > > > +{
> > > > > > +igt_debug("unbind the driver from the device\n");
> > > > > > +igt_assert(igt_sysfs_set(sysfs->fds.drv_dir, "unbind",
> > > > > > +   sysfs->dev_bus_addr));
> > > > > > +}
> > > > > > +
> > > > > > +/* Re-bind the driver to the device */
> > > > > > +static void driver_bind(struct sysfs_fds *sysfs)
> > > > > > +{
> > > > > > +igt_debug("rebind the driver to the device\n");
> > > > > > +igt_abort_on_f(!igt_sysfs_set(sysfs->fds.drv_dir, "bind",
> > > > > > +       sysfs->dev_bus_addr), "driver rebind failed");
> > > > > > +}
> > > > > > +
> > > > > > +/* Initiate device reset */
> > > > > > +static void initiate_device_reset(struct sysfs_fds *sysfs)
> > > > > > +{
> > > > > > +igt_debug("reset device\n");
> > > > > > +igt_assert(igt_sysfs_set(sysfs->fds.dev_dir, "reset",
> > > > > > "1"));
> > > > > > +}
> > > > > > +
> > > > > > +/**
> > > > > > + * healthcheck:
> > > > > > + * @sysfs: structure with device descriptor, if descriptor
> > > > > > equals
> > > > > > -1
> > > > > > + *    the device is reopened
> > > > > > + */
> > > > > > +static void healthcheck(struct sysfs_fds *sysfs)
> > > > > > +{
> > > > > > +open_if_closed(sysfs);
> > > > > > +gem_test_engine(sysfs->fds.dev, ALL_ENGINES);
> > > > > 
> > > > > This test is located in tests/ and looks like could be
> > > > > applicable
> > > > > to
> > > > > any
> > > > > device. If that is true - gem_test_engine is from i915
> > > > > familiy.
> > > > > Is
> > > > > there a way
> > > > > to test engines for any driver? Naming is one thing, but what
> > > > > if
> > > > > amd
> > > > > card will
> > > > > try to execute engines with i915 functions?
> > > > > 
> > > > > Kasia
> > > > 
> > > > healthcheck is used in subtest_group where igt_require_intel is
> > > > prerequisite, so the tests will be skipped on non intel
> > > > platforms
> > > 
> > > In that case test should be moved to tests/i915 dir than?
> > > Kasia
> > 
> > Following tests may be executed on ANY_DEVICE:
> > unbind-rebind
> > unbind-reset-rebind
> > reset-bound
> > 
> > the versions with *-healthcheck will skip on non intel platfroms.
> 
> AFAICT, CI expects each test to leave the exercised device in a
> usable
> state (driver bound, GPU not wedged).  If not, the test should exit
> via
> igt_abort(), unless TAINT_WARN flag in /proc/sys/kernel/tainted is
> raised by the driver on unsuccessful GPU reset.  Then, I think you
> should perform a final healthcheck from each subtest. 
> gem_test_engine() should be called conditionally if intel graphics is
> detected, other platforms can add their specific checks as needed.
> 
> Thanks,
> Janusz

Ok, I reduced and simplified the tests to conditionally call
gem_test_engine when run on intel graphics.

Thanks,
marcin

> 
> > 
> > Should I move them to separate binary under tests/i915 dir ?
> > 
> > > > > > +}
> > > > > > +
> > > > > > +/**
> > > > > > + * set_device_filter:
> > > > > > + *
> > > > > > + * Sets device filter to ensure subtests always reopen the
> > > > > > same
> > > > > > device
> > > > > > + *
> > > > > > + * @dev_path: path to device under tests
> > > > > > + */
> > > > > > +static void set_device_filter(const char* dev_path)
> > > > > > +{
> > > > > > +char filter[strlen("sys:") + strlen(dev_path) + 1];
> > > > > > +
> > > > > > +snprintf(filter, sizeof(filter), "sys:%s", dev_path);
> > > > > > +igt_device_filter_free_all();
> > > > > > +igt_assert_eq(igt_device_filter_add(filter), 1);
> > > > > > +}
> > > > > > +
> > > > > > +static void unbind_rebind(struct sysfs_fds *sysfs)
> > > > > > +{
> > > > > > +igt_debug("close the device\n");
> > > > > > +close_if_opened(&sysfs->fds.dev);
> > > > > > +
> > > > > > +driver_unbind(sysfs);
> > > > > > +
> > > > > > +driver_bind(sysfs);
> > > > > > +}
> > > > > > +
> > > > > > +static void unbind_reset_rebind(struct sysfs_fds *sysfs)
> > > > > > +{
> > > > > > +igt_debug("close the device\n");
> > > > > > +close_if_opened(&sysfs->fds.dev);
> > > > > > +
> > > > > > +driver_unbind(sysfs);
> > > > > > +
> > > > > > +initiate_device_reset(sysfs);
> > > > > > +
> > > > > > +driver_bind(sysfs);
> > > > > > +}
> > > > > > +
> > > > > > +igt_main
> > > > > > +{
> > > > > > +struct sysfs_fds sysfs;
> > > > > > +
> > > > > > +igt_fixture {
> > > > > > +char dev_path[PATH_MAX];
> > > > > > +
> > > > > > +igt_debug("opening device\n");
> > > > > > +init_sysfs_fds(&sysfs);
> > > > > > +
> > > > > > +/* Make sure subtests always reopen the same device */
> > > > > > +igt_assert(device_sysfs_path(sysfs.fds.dev, dev_path));
> > > > > > +set_device_filter(dev_path);
> > > > > > +
> > > > > > +igt_skip_on(!is_sysfs_reset_supported(sysfs.fds.dev));
> > > > > > +
> > > > > > +igt_set_timeout(60, "device reset tests timed out after
> > > > > > 60s");
> > > > > > +}
> > > > > > +
> > > > > > +igt_describe("Tests driver unbind from/rebind to device
> > > > > > sequence");
> > > > > > +igt_subtest("unbind-rebind")
> > > > > > +unbind_rebind(&sysfs);
> > > > > > +
> > > > > > +igt_describe("Unbinds driver from device, initiates reset"
> > > > > > +     " then rebinds driver to device");
> > > > > > +igt_subtest("unbind-reset-rebind")
> > > > > > +unbind_reset_rebind(&sysfs);
> > > > > > +
> > > > > > +igt_describe("Resets device with bound driver");
> > > > > > +igt_subtest("reset-bound")
> > > > > > +initiate_device_reset(&sysfs);
> > > > > > +
> > > > > > +igt_describe("Subtests with additional healthchecks");
> > > > > > +igt_subtest_group {
> > > > > > +igt_fixture {
> > > > > > +open_if_closed(&sysfs);
> > > > > > +igt_require_intel(sysfs.fds.dev);
> > > > > > +}
> > > > > > +
> > > > > > +igt_subtest("healthcheck")
> > > > > > +healthcheck(&sysfs);
> > > > > > +
> > > > > > +igt_subtest("unbind-reset-rebind-healthcheck") {
> > > > > > +unbind_reset_rebind(&sysfs);
> > > > > > +healthcheck(&sysfs);
> > > > > > +}
> > > > > > +
> > > > > > +igt_subtest("reset-bound-healthcheck") {
> > > > > > +initiate_device_reset(&sysfs);
> > > > > > +healthcheck(&sysfs);
> > > > > > +}
> > > > > > +}
> > > > > > +
> > > > > > +igt_fixture {
> > > > > > +igt_reset_timeout();
> > > > > > +cleanup_sysfs_fds(&sysfs);
> > > > > > +}
> > > > > > +}
> > > > > > diff --git a/tests/meson.build b/tests/meson.build
> > > > > > index 28091794f..b0acdf7c0 100644
> > > > > > --- a/tests/meson.build
> > > > > > +++ b/tests/meson.build
> > > > > > @@ -8,6 +8,7 @@ test_progs = [
> > > > > >  'core_setmaster_vs_auth',
> > > > > >  'debugfs_test',
> > > > > >  'dmabuf',
> > > > > > +'device_reset',
> > > > > >  'drm_import_export',
> > > > > >  'drm_mm',
> > > > > >  'drm_read',
> > > > > > --
> > > > > > 2.25.1
> > > > > > 
> 
> 
---------------------------------------------------------------------
Intel Technology Poland sp. z o.o.
ul. Sowackiego 173 | 80-298 Gdask | Sd Rejonowy Gdask Pnoc | VII Wydzia Gospodarczy Krajowego Rejestru Sdowego - KRS 101882 | NIP 957-07-52-316 | Kapita zakadowy 200.000 PLN.
Ta wiadomo wraz z zacznikami jest przeznaczona dla okrelonego adresata i moe zawiera informacje poufne. W razie przypadkowego otrzymania tej wiadomoci, prosimy o powiadomienie nadawcy oraz trwae jej usunicie; jakiekolwiek przegldanie lub rozpowszechnianie jest zabronione.
This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). If you are not the intended recipient, please contact the sender and delete all copies; any review or distribution by others is strictly prohibited.
 
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2020-06-29  8:54 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-26  6:30 [igt-dev] [RFC,i-g-t] tests/device_reset: Test device sysfs reset Marcin Bernatowicz
2020-06-26  8:47 ` [igt-dev] [RFC, i-g-t] " Katarzyna Dec
2020-06-26  8:55   ` Bernatowicz, Marcin
2020-06-26  9:19     ` Katarzyna Dec
2020-06-26 10:23       ` Bernatowicz, Marcin
2020-06-26 10:48         ` Katarzyna Dec
2020-06-26 11:35         ` Janusz Krzysztofik
2020-06-29  8:53           ` Bernatowicz, Marcin
2020-06-26 13:49 ` [igt-dev] ✓ Fi.CI.BAT: success for " Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.