[PATCH v2 1/2] lib: Add DRM driver sysfs profiling knob toggling functions

Adrián Larumbe adrian.larumbe at collabora.com
Tue Apr 2 22:27:44 UTC 2024


Some DRM drivers need to have their accounting HW toggled on demand from
user space so that fdinfo's drm-engine and drm-cycles tags can be updated
upon job completion.

A profiler such as gputop should be able to check which DRM devices have
such a sysfs knob, record its original state, toggle-enable it and revert
this operation right before exiting.

A new igt library igt_profiling.c file was added because using igt lib's
sysfs access functions would've triggered a cascade of linking dependencies
in intel_gpu_top, which only statically links a very small subset of the
igt library.

Cc: Tvrtko Ursulin <tursulin at ursulin.net>
Cc: Daniel Vetter <daniel at ffwll.ch>
Cc: Boris Brezillon <boris.brezillon at collabora.com>
Cc: Zbigniew Kempczyński <zbigniew.kempczynski at intel.com>
Signed-off-by: Adrián Larumbe <adrian.larumbe at collabora.com>
---
 lib/igt_device_scan.c | 45 +++++++++++++++++++++++++++++++++++++++++++
 lib/igt_device_scan.h |  7 +++++++
 lib/igt_profiling.c   | 28 +++++++++++++++++++++++++++
 lib/igt_profiling.h   | 17 ++++++++++++++++
 lib/meson.build       |  1 +
 5 files changed, 98 insertions(+)
 create mode 100644 lib/igt_profiling.c
 create mode 100644 lib/igt_profiling.h

diff --git a/lib/igt_device_scan.c b/lib/igt_device_scan.c
index fbf3fa482e21..e5b126cc5448 100644
--- a/lib/igt_device_scan.c
+++ b/lib/igt_device_scan.c
@@ -1105,6 +1105,51 @@ void igt_devices_scan(bool force)
 	igt_devs.devs_scanned = true;
 }
 
+struct igt_profiled_device *igt_devices_profiled(void)
+{
+	struct igt_profiled_device *profiled_devices;
+	struct igt_device *dev;
+	unsigned int devlist_len;
+	unsigned int i = 0;
+
+	if (!igt_devs.devs_scanned)
+		return NULL;
+
+	devlist_len = igt_list_length(&igt_devs.all);
+	if (devlist_len == 0)
+		return NULL;
+
+	profiled_devices = malloc(devlist_len * sizeof(struct igt_profiled_device));
+	if (!profiled_devices)
+		return NULL;
+
+	memset(profiled_devices, 0, devlist_len * sizeof(struct igt_profiled_device));
+
+	igt_list_for_each_entry(dev, &igt_devs.all, link) {
+		char path[PATH_MAX];
+		int sysfs_fd;
+
+		if (!get_attr(dev, "profiling"))
+			continue;
+
+		snprintf(path, sizeof(path), "%s/%s", dev->syspath, "profiling");
+		sysfs_fd = open(path, O_RDONLY);
+		if (sysfs_fd < 0)
+			continue;
+
+		profiled_devices[i].syspath = dev->syspath;
+		profiled_devices[i++].original_state =
+			strtoul(get_attr(dev, "profiling"), NULL, 10);
+	}
+
+	if (i == 0) {
+		free(profiled_devices);
+		profiled_devices = NULL;
+	}
+
+	return profiled_devices;
+}
+
 static inline void _pr_simple(const char *k, const char *v)
 {
 	printf("    %-16s: %s\n", k, v);
diff --git a/lib/igt_device_scan.h b/lib/igt_device_scan.h
index 48690e236c01..6c725d9081b2 100644
--- a/lib/igt_device_scan.h
+++ b/lib/igt_device_scan.h
@@ -63,8 +63,15 @@ struct igt_device_card {
 	uint16_t pci_vendor, pci_device;
 };
 
+struct igt_profiled_device {
+	char *syspath;
+	bool original_state;
+};
+
 void igt_devices_scan(bool force);
 
+struct igt_profiled_device *igt_devices_profiled(void);
+
 void igt_devices_print(const struct igt_devices_print_format *fmt);
 void igt_devices_print_vendors(void);
 void igt_device_print_filter_types(void);
diff --git a/lib/igt_profiling.c b/lib/igt_profiling.c
new file mode 100644
index 000000000000..9ba114b4d78d
--- /dev/null
+++ b/lib/igt_profiling.c
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2024 Collabora Ltd.
+ * Copyright © 2024 Adrian Larumbe <adrian.larumbe at collabora.com>
+ * Copyright © 2024 Amazon.com, Inc. or its affiliates.
+ *
+ */
+
+#include <fcntl.h>
+
+#include "igt_device_scan.h"
+#include "igt_profiling.h"
+#include "igt_sysfs.h"
+
+void igt_devices_toggle_profiling(struct igt_profiled_device *devices, bool enable)
+{
+	for (unsigned int i = 0; devices[i].syspath; i++) {
+		int sysfs_fd = open(devices[i].syspath, O_RDONLY);
+
+		if (sysfs_fd < 0)
+			continue;
+
+		igt_sysfs_set_boolean(sysfs_fd, "profiling",
+				      enable ? true : devices[i].original_state);
+
+		close(sysfs_fd);
+	}
+}
diff --git a/lib/igt_profiling.h b/lib/igt_profiling.h
new file mode 100644
index 000000000000..af0b9366b797
--- /dev/null
+++ b/lib/igt_profiling.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2024 Collabora Ltd.
+ * Copyright © 2024 Adrian Larumbe <adrian.larumbe at collabora.com>
+ * Copyright © 2024 Amazon.com, Inc. or its affiliates.
+ */
+
+#ifndef IGT_PROFILING_H
+#define IGT_PROFILING_H
+
+#include <stdbool.h>
+
+struct igt_profiled_device;
+
+void igt_devices_toggle_profiling(struct igt_profiled_device *devices, bool enable);
+
+#endif /* IGT_PROFILING_H */
diff --git a/lib/meson.build b/lib/meson.build
index 6122861d8b7a..0fcc5f1cf5a1 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -36,6 +36,7 @@ lib_sources = [
 	'igt_pipe_crc.c',
 	'igt_power.c',
 	'igt_primes.c',
+        'igt_profiling.c',
 	'igt_pci.c',
 	'igt_rand.c',
 	'igt_sriov_device.c',
-- 
2.44.0



More information about the igt-dev mailing list