[Intel-gfx] [PATCH i-g-t] tests: Introduce drv_cgroup (v2)
Matt Roper
matthew.d.roper at intel.com
Sat Mar 17 00:16:51 UTC 2018
drv_cgroup exercises both valid and invalid usage of the i915 cgroup
parameter ioctl.
v2:
- Add support for display boost
- Drop cgroup permissions test (the kernel no longer bases access
control on fs permissions)
Signed-off-by: Matt Roper <matthew.d.roper at intel.com>
---
tests/Makefile.sources | 1 +
tests/drv_cgroup.c | 262 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 263 insertions(+)
create mode 100644 tests/drv_cgroup.c
diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index 4e6f5319..ba4b00bb 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -37,6 +37,7 @@ TESTS_progs = \
drm_vma_limiter_cached \
drm_vma_limiter_cpu \
drm_vma_limiter_gtt \
+ drv_cgroup \
drv_getparams_basic \
drv_hangman \
drv_missed_irq \
diff --git a/tests/drv_cgroup.c b/tests/drv_cgroup.c
new file mode 100644
index 00000000..457daf7b
--- /dev/null
+++ b/tests/drv_cgroup.c
@@ -0,0 +1,262 @@
+/*
+ * Copyright © 2018 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+#include "igt.h"
+#include "igt_debugfs.h"
+#include "igt_aux.h"
+#include "igt_kmod.h"
+#include "igt_sysfs.h"
+#include "igt_core.h"
+
+#include <dirent.h>
+#include <fcntl.h>
+#include <libgen.h>
+#include <signal.h>
+#include <stdio.h>
+#include <linux/limits.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/utsname.h>
+
+/* libdrm support is not yet upstream, so duplicate defs here for now */
+
+struct INTERNAL_drm_i915_cgroup_param {
+ __s32 cgroup_fd;
+ __u32 flags;
+ __u64 param;
+#define I915_CGROUP_PARAM_PRIORITY_OFFSET 0x1
+#define I915_CGROUP_PARAM_DISPBOOST_PRIORITY 0x2
+ __s64 value;
+};
+
+#define INTERNAL_IOCTL_I915_CGROUP_SETPARAM \
+ DRM_IOW(DRM_COMMAND_BASE + 0x3a, struct INTERNAL_drm_i915_cgroup_param)
+
+static char tmp[PATH_MAX], *cgrp2dir = NULL;
+static int cgrp2fd = -1;
+static int drm_fd = -1;
+
+/* Figure out where (if) cgroups-v2 is mounted on this machine. */
+static void
+find_cgroup2(void)
+{
+ FILE *f;
+ char *from, *path, *type;
+
+ f = fopen("/proc/mounts", "r");
+ igt_assert(f);
+
+ while (fgets(tmp, sizeof(tmp), f)) {
+ from = strtok(tmp, " ");
+ if (!from) continue;
+
+ path = strtok(NULL, " ");
+ if (!path) continue;
+
+ type = strtok(NULL, " ");
+ if (strcmp(type, "cgroup2") == 0) {
+ cgrp2dir = path;
+ cgrp2fd = open(cgrp2dir, O_DIRECTORY|O_RDONLY);
+ break;
+ }
+ }
+
+ fclose(f);
+
+ igt_skip_on_f(!cgrp2dir, "cgroups-v2 is not mounted\n");
+ igt_skip_on_f(!cgrp2fd, "Insufficient fs permissions on cgroup2 dir\n");
+}
+
+static char tmp_cgroup[PATH_MAX];
+
+static int
+create_tmp_cgroup(void)
+{
+ char *dirname;
+ int fd;
+
+ snprintf(tmp_cgroup, sizeof(tmp_cgroup), "%s/igt_cgroup_XXXXXX",
+ cgrp2dir);
+ dirname = mkdtemp(tmp_cgroup);
+ igt_assert(dirname);
+
+ fd = open(dirname, O_DIRECTORY|O_RDONLY);
+ igt_assert(fd >= 0);
+
+ return fd;
+}
+
+static void
+rm_tmp_cgroup(int fd)
+{
+ close(fd);
+ rmdir(tmp_cgroup);
+}
+
+static int
+set_prio(int fd, int prio)
+{
+ struct INTERNAL_drm_i915_cgroup_param req;
+
+ req.cgroup_fd = fd;
+ req.flags = 0;
+ req.param = I915_CGROUP_PARAM_PRIORITY_OFFSET;
+ req.value = prio;
+
+ return drmIoctl(drm_fd, INTERNAL_IOCTL_I915_CGROUP_SETPARAM, &req);
+}
+
+static int
+set_boost(int fd, int boost)
+{
+ struct INTERNAL_drm_i915_cgroup_param req;
+
+ req.cgroup_fd = fd;
+ req.flags = 0;
+ req.param = I915_CGROUP_PARAM_DISPBOOST_PRIORITY;
+ req.value = boost;
+
+ return drmIoctl(drm_fd, INTERNAL_IOCTL_I915_CGROUP_SETPARAM, &req);
+}
+
+igt_main
+{
+ char other_file[PATH_MAX];
+ int ret, fd;
+
+ igt_fixture {
+ find_cgroup2();
+ drm_fd = drm_open_driver_master(DRIVER_INTEL);
+ }
+
+ /* Standard request to set priority. Should succeed */
+ igt_subtest_f("set-prio") {
+ fd = create_tmp_cgroup();
+ ret = set_prio(fd, 123);
+ igt_fail_on(ret);
+ rm_tmp_cgroup(fd);
+ }
+
+ /* Set priority outside valid range. Should fail */
+ igt_subtest_f("prio-out-of-range") {
+ fd = create_tmp_cgroup();
+ ret = set_prio(fd, 0x800000);
+ igt_assert(ret < 0 && errno == EINVAL);
+ rm_tmp_cgroup(fd);
+ }
+
+ /* Set display boost to valid value. Should succeed */
+ igt_subtest_f("set-dispboost") {
+ fd = create_tmp_cgroup();
+ ret = set_boost(fd, 0x3000);
+ igt_fail_on(ret);
+ rm_tmp_cgroup(fd);
+ }
+
+ /* Set display boost outside valid range. Should fail */
+ igt_subtest_f("dispboost-out-of-range") {
+ fd = create_tmp_cgroup();
+ ret = set_boost(fd, 0x800001);
+ igt_assert(ret < 0 && errno == EINVAL);
+ rm_tmp_cgroup(fd);
+ }
+
+ /* Use an invalid parameter ID. Should fail. */
+ igt_subtest_f("bad-param") {
+ struct INTERNAL_drm_i915_cgroup_param req;
+
+ fd = create_tmp_cgroup();
+ req.cgroup_fd = fd;
+ req.flags = 0;
+ req.param = 0xDEADBEEF;
+ req.value = 123;
+
+ ret = drmIoctl(drm_fd, INTERNAL_IOCTL_I915_CGROUP_SETPARAM, &req);
+ igt_assert(ret < 0 && errno == EINVAL);
+
+ rm_tmp_cgroup(fd);
+ }
+
+ /*
+ * Pass fd for a cgroup control file instead of cgroup directory itself.
+ * Should fail.
+ */
+ igt_subtest_f("control-file-fd") {
+ int fd2;
+
+ fd = create_tmp_cgroup();
+ snprintf(other_file, sizeof(other_file),
+ "%s/cgroup.procs", tmp_cgroup);
+ fd2 = open(other_file, O_RDONLY);
+ igt_assert(fd2 >= 0);
+
+ ret = set_prio(fd2, 123);
+ igt_assert(ret < 0 && errno == EBADF);
+
+ close(fd2);
+ rm_tmp_cgroup(fd);
+ }
+
+ /*
+ * Pass an fd for a non-cgroup directory. Should fail.
+ * Note that we rely on /tmp being available and writable.
+ */
+ igt_subtest_f("non-cgroup-fd") {
+ char *dirname;
+
+ strcpy(other_file, "/tmp/igt_XXXXXX");
+ dirname = mkdtemp(other_file);
+ igt_assert(dirname);
+
+ fd = open(dirname, O_DIRECTORY|O_RDONLY);
+ igt_assert(fd >= 0);
+
+ ret = set_prio(fd, 123);
+ igt_assert(ret < 0 && errno == EBADF);
+
+ close(fd);
+ rmdir(dirname);
+ }
+
+ /*
+ * Reload driver after setting priority. Should pass.
+ *
+ * The priority data will be lost across reload, but the goal is to
+ * make sure we don't panic during driver removal or subsequent
+ * assignment of a new priority to the existing cgroup.
+ */
+ igt_subtest_f("cgroup-reload") {
+ fd = create_tmp_cgroup();
+ ret = set_prio(fd, 123);
+ igt_fail_on(ret);
+
+ ret = igt_i915_driver_unload();
+ igt_fail_on(ret);
+ ret = igt_i915_driver_load(NULL);
+ igt_fail_on(ret);
+
+ ret = set_prio(fd, 456);
+ igt_fail_on(ret);
+
+ rm_tmp_cgroup(fd);
+ }
+}
--
2.14.3
More information about the Intel-gfx
mailing list