@@ -44,6 +44,11 @@
<xi:include href="xml/intel_io.xml"/>
<xi:include href="xml/ioctl_wrappers.xml"/>
<xi:include href="xml/sw_sync.xml"/>
+
+ </chapter>
+ <chapter>
+ <title>igt/i915 API Reference</title>
+ <xi:include href="xml/gem_scheduler.xml"/>
</chapter>
<xi:include href="xml/igt_test_programs.xml"/>
@@ -3,6 +3,8 @@ lib_source_list = \
drmtest.c \
drmtest.h \
i830_reg.h \
+ i915/gem_scheduler.c \
+ i915/gem_scheduler.h \
i915_3d.h \
i915_reg.h \
i915_pciids.h \
new file mode 100644
@@ -0,0 +1,125 @@
+/*
+ * Copyright © 2017 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 <errno.h>
+#include <string.h>
+#include <sys/ioctl.h>
+
+#include "igt_core.h"
+#include "ioctl_wrappers.h"
+
+#include "i915/gem_scheduler.h"
+
+#define LOCAL_I915_PARAM_HAS_SCHEDULER 41
+
+/**
+ * SECTION:gem_scheduler
+ * @short_description: Helpers for querying scheduler capabilities
+ * @title: GEM Scheduler
+ *
+ * This helper library contains functions used for getting information on
+ * currently used scheduling model.
+ */
+
+/**
+ * gem_scheduler_capability:
+ * @fd: open i915 drm file descriptor
+ *
+ * Returns: Scheduler capability bitmap.
+ */
+unsigned gem_scheduler_capability(int fd)
+{
+ static int caps = -1;
+
+ if (caps < 0) {
+ struct drm_i915_getparam gp;
+
+ memset(&gp, 0, sizeof(gp));
+ gp.param = LOCAL_I915_PARAM_HAS_SCHEDULER;
+ gp.value = ∩︀
+
+ caps = 0;
+ ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp, sizeof(gp));
+ errno = 0;
+ }
+
+ return caps;
+}
+
+/**
+ * gem_has_scheduler:
+ * @fd: open i915 drm file descriptor
+ *
+ * Feature test macro to query whether the driver has scheduling capability.
+ */
+bool gem_scheduler_enabled(int fd)
+{
+ return gem_scheduler_capability(fd) &
+ LOCAL_I915_SCHEDULER_CAP_ENABLED;
+}
+
+/**
+ * gem_has_ctx_priority:
+ * @fd: open i915 drm file descriptor
+ *
+ * Feature test macro to query whether the driver supports assigning custom
+ * priorities to contexts from userspace.
+ */
+bool gem_scheduler_has_ctx_priority(int fd)
+{
+ return gem_scheduler_capability(fd) &
+ LOCAL_I915_SCHEDULER_CAP_PRIORITY;
+}
+
+/**
+ * gem_has_preemption:
+ * @fd: open i915 drm file descriptor
+ *
+ * Feature test macro to query whether the driver supports preempting active
+ * (currently executing on HW) workloads.
+ */
+bool gem_scheduler_has_preemption(int fd)
+{
+ return gem_scheduler_capability(fd) &
+ LOCAL_I915_SCHEDULER_CAP_PREEMPTION;
+}
+
+/**
+ * gem_scheduler_print_capability:
+ * @fd: open i915 drm file descriptor
+ *
+ * Helper for pretty-printing scheduler capability.
+ */
+void gem_scheduler_print_capability(int fd)
+{
+ unsigned caps = gem_scheduler_capability(fd);
+
+ if (!caps)
+ return;
+
+ igt_info("Has kernel scheduler\n");
+ if (caps & LOCAL_I915_SCHEDULER_CAP_PRIORITY)
+ igt_info(" - With priority sorting\n");
+ if (caps & LOCAL_I915_SCHEDULER_CAP_PREEMPTION)
+ igt_info(" - With preemption enabled\n");
+}
new file mode 100644
@@ -0,0 +1,37 @@
+/*
+ * Copyright © 2017 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.
+ */
+
+#ifndef GEM_SCHEDULER_H
+#define GEM_SCHEDULER_H
+
+#define LOCAL_I915_SCHEDULER_CAP_ENABLED (1 << 0)
+#define LOCAL_I915_SCHEDULER_CAP_PRIORITY (1 << 1)
+#define LOCAL_I915_SCHEDULER_CAP_PREEMPTION (1 << 2)
+
+unsigned gem_scheduler_capability(int fd);
+bool gem_scheduler_enabled(int fd);
+bool gem_scheduler_has_ctx_priority(int fd);
+bool gem_scheduler_has_preemption(int fd);
+void gem_scheduler_print_capability(int fd);
+
+#endif /* GEM_SCHEDULER_H */
@@ -36,6 +36,8 @@
#include <intel_bufmgr.h>
#include <i915_drm.h>
+#include "i915/gem_scheduler.h"
+
/**
* igt_ioctl:
* @fd: file descriptor
@@ -2,6 +2,7 @@ lib_headers = [
'debug.h',
'drmtest.h',
'i830_reg.h',
+ 'i915/gem_scheduler.h',
'i915_3d.h',
'i915_reg.h',
'i915_pciids.h',
@@ -48,6 +49,7 @@ lib_headers = [
lib_sources = [
'drmtest.c',
+ 'i915/gem_scheduler.c',
'igt_debugfs.c',
'igt_aux.c',
'igt_gt.c',
@@ -152,13 +154,7 @@ lib_version = vcs_tag(input : 'version.h.in', output : 'version.h',
lib_intermediates = []
foreach f: lib_sources
- # No / in the target name
- if f.contains('uwildmat')
- name = 'uwildmat'
- else
- name = f
- endif
-
+ name = f.underscorify(f)
lib = static_library('igt-' + name,
[ f, lib_version ],
include_directories: inc,
@@ -44,8 +44,6 @@
#include <time.h>
#include "drm.h"
-#define BIT(x) (1ul << (x))
-
#define LOCAL_I915_EXEC_NO_RELOC (1<<11)
#define LOCAL_I915_EXEC_HANDLE_LUT (1<<12)
@@ -54,10 +52,6 @@
#define ENGINE_FLAGS (I915_EXEC_RING_MASK | LOCAL_I915_EXEC_BSD_MASK)
-#define LOCAL_PARAM_HAS_SCHEDULER 41
-#define HAS_SCHEDULER BIT(0)
-#define HAS_PRIORITY BIT(1)
-#define HAS_PREEMPTION BIT(2)
#define LOCAL_CONTEXT_PARAM_PRIORITY 6
#define MAX_PRIO 1023
#define MIN_PRIO -1023
@@ -665,31 +659,9 @@ static void preempt(int fd, uint32_t handle,
ring_name, count, elapsed(&start, &now)*1e6 / count);
}
-static unsigned int has_scheduler(int fd)
-{
- drm_i915_getparam_t gp;
- unsigned int caps = 0;
-
- gp.param = LOCAL_PARAM_HAS_SCHEDULER;
- gp.value = (int *)∩︀
- drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
-
- if (!caps)
- return 0;
-
- igt_info("Has kernel scheduler\n");
- if (caps & HAS_PRIORITY)
- igt_info(" - With priority sorting\n");
- if (caps & HAS_PREEMPTION)
- igt_info(" - With preemption enabled\n");
-
- return caps;
-}
-
igt_main
{
const struct intel_execution_engine *e;
- unsigned int sched_caps = 0;
uint32_t handle = 0;
int device = -1;
@@ -699,7 +671,7 @@ igt_main
device = drm_open_driver(DRIVER_INTEL);
igt_require_gem(device);
igt_show_submission_method(device);
- sched_caps = has_scheduler(device);
+ gem_scheduler_print_capability(device);
handle = gem_create(device, 4096);
gem_write(device, handle, 0, &bbe, sizeof(bbe));
@@ -746,8 +718,8 @@ igt_main
igt_subtest_group {
igt_fixture {
- igt_require(sched_caps & HAS_PRIORITY);
- igt_require(sched_caps & HAS_PREEMPTION);
+ igt_require(gem_scheduler_has_ctx_priority(device));
+ igt_require(gem_scheduler_has_preemption(device));
}
for (e = intel_execution_engines; e->name; e++) {
@@ -33,12 +33,6 @@
#include "igt_rand.h"
#include "igt_sysfs.h"
-#define BIT(x) (1ul << (x))
-
-#define LOCAL_PARAM_HAS_SCHEDULER 41
-#define HAS_SCHEDULER BIT(0)
-#define HAS_PRIORITY BIT(1)
-#define HAS_PREEMPTION BIT(2)
#define LOCAL_CONTEXT_PARAM_PRIORITY 6
#define LO 0
@@ -70,11 +64,6 @@ static void ctx_set_priority(int fd, uint32_t ctx, int prio)
igt_assert_eq(__ctx_set_priority(fd, ctx, prio), 0);
}
-static void ctx_has_priority(int fd)
-{
- igt_require(__ctx_set_priority(fd, 0, MAX_PRIO) == 0);
-}
-
static void store_dword(int fd, uint32_t ctx, unsigned ring,
uint32_t target, uint32_t offset, uint32_t value,
uint32_t cork, unsigned write_domain)
@@ -979,31 +968,9 @@ static void test_pi_ringfull(int fd, unsigned int engine)
munmap(result, 4096);
}
-static unsigned int has_scheduler(int fd)
-{
- drm_i915_getparam_t gp;
- unsigned int caps = 0;
-
- gp.param = LOCAL_PARAM_HAS_SCHEDULER;
- gp.value = (int *)∩︀
- drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
-
- if (!caps)
- return 0;
-
- igt_info("Has kernel scheduler\n");
- if (caps & HAS_PRIORITY)
- igt_info(" - With priority sorting\n");
- if (caps & HAS_PREEMPTION)
- igt_info(" - With preemption enabled\n");
-
- return caps;
-}
-
igt_main
{
const struct intel_execution_engine *e;
- unsigned int sched_caps = 0;
int fd = -1;
igt_skip_on_simulation();
@@ -1011,7 +978,7 @@ igt_main
igt_fixture {
fd = drm_open_driver_master(DRIVER_INTEL);
igt_show_submission_method(fd);
- sched_caps = has_scheduler(fd);
+ gem_scheduler_print_capability(fd);
igt_require_gem(fd);
gem_require_mmap_wc(fd);
igt_fork_hang_detector(fd);
@@ -1033,8 +1000,8 @@ igt_main
igt_subtest_group {
igt_fixture {
- igt_require(sched_caps & HAS_SCHEDULER);
- ctx_has_priority(fd);
+ igt_require(gem_scheduler_enabled(fd));
+ igt_require(gem_scheduler_has_ctx_priority(fd));
}
igt_subtest("smoketest-all")
@@ -1062,7 +1029,7 @@ igt_main
igt_subtest_group {
igt_fixture {
- igt_require(sched_caps & HAS_PREEMPTION);
+ igt_require(gem_scheduler_has_preemption(fd));
}
igt_subtest_f("preempt-%s", e->name)
@@ -1095,8 +1062,8 @@ igt_main
igt_subtest_group {
igt_fixture {
- igt_require(sched_caps & HAS_SCHEDULER);
- ctx_has_priority(fd);
+ igt_require(gem_scheduler_enabled(fd));
+ igt_require(gem_scheduler_has_ctx_priority(fd));
/* need separate rings */
igt_require(gem_has_execlists(fd));
@@ -1106,7 +1073,7 @@ igt_main
igt_subtest_group {
igt_fixture {
gem_require_ring(fd, e->exec_id | e->flags);
- igt_require(sched_caps & HAS_PREEMPTION);
+ igt_require(gem_scheduler_has_preemption(fd));
}
igt_subtest_f("pi-ringfull-%s", e->name)
@@ -191,21 +191,8 @@ static void fini_hang(struct hang *h)
close(h->fd);
}
-#define LOCAL_PARAM_HAS_SCHEDULER 41
#define LOCAL_CONTEXT_PARAM_PRIORITY 6
-static bool __has_scheduler(int fd)
-{
- drm_i915_getparam_t gp;
- int has = -1;
-
- gp.param = LOCAL_PARAM_HAS_SCHEDULER;
- gp.value = &has;
- drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
-
- return has > 0;
-}
-
static int __ctx_set_priority(int fd, uint32_t ctx, int prio)
{
struct local_i915_gem_context_param param;
@@ -250,13 +237,8 @@ static void whisper(int fd, unsigned engine, unsigned flags)
int debugfs;
if (flags & PRIORITY) {
- int __fd = drm_open_driver(DRIVER_INTEL);
- bool has_scheduler = __has_scheduler(__fd);
- bool ctx_has_priority =
- __ctx_set_priority(__fd, 0, 1) == 0;
- close(__fd);
-
- igt_require(has_scheduler && ctx_has_priority);
+ igt_require(gem_scheduler_enabled(fd));
+ igt_require(gem_scheduler_has_ctx_priority(fd));
}
debugfs = igt_debugfs_dir(fd);
@@ -27,18 +27,12 @@
#include "igt.h"
#include "igt_sysfs.h"
-#define BIT(x) (1ul << (x))
-
#define LOCAL_I915_EXEC_NO_RELOC (1<<11)
#define LOCAL_I915_EXEC_HANDLE_LUT (1<<12)
#define LOCAL_I915_EXEC_BSD_SHIFT (13)
#define LOCAL_I915_EXEC_BSD_MASK (3 << LOCAL_I915_EXEC_BSD_SHIFT)
-#define LOCAL_PARAM_HAS_SCHEDULER 41
-#define HAS_SCHEDULER BIT(0)
-#define HAS_PRIORITY BIT(1)
-#define HAS_PREEMPTION BIT(2)
#define LOCAL_CONTEXT_PARAM_PRIORITY 6
#define MAX_PRIO 1023
#define MIN_PRIO -1023
@@ -807,32 +801,10 @@ preempt(int fd, unsigned ring, int num_children, int timeout)
gem_context_destroy(fd, ctx[0]);
}
-static unsigned int has_scheduler(int fd)
-{
- drm_i915_getparam_t gp;
- unsigned int caps = 0;
-
- gp.param = LOCAL_PARAM_HAS_SCHEDULER;
- gp.value = (int *)∩︀
- drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
-
- if (!caps)
- return 0;
-
- igt_info("Has kernel scheduler\n");
- if (caps & HAS_PRIORITY)
- igt_info(" - With priority sorting\n");
- if (caps & HAS_PREEMPTION)
- igt_info(" - With preemption enabled\n");
-
- return caps;
-}
-
igt_main
{
const struct intel_execution_engine *e;
const int ncpus = sysconf(_SC_NPROCESSORS_ONLN);
- unsigned int sched_caps = 0;
int fd = -1;
igt_skip_on_simulation();
@@ -841,7 +813,7 @@ igt_main
fd = drm_open_driver(DRIVER_INTEL);
igt_require_gem(fd);
igt_show_submission_method(fd);
- sched_caps = has_scheduler(fd);
+ gem_scheduler_print_capability(fd);
igt_fork_hang_detector(fd);
}
@@ -886,8 +858,8 @@ igt_main
igt_subtest_group {
igt_fixture {
- igt_require(sched_caps & HAS_PRIORITY);
- igt_require(sched_caps & HAS_PREEMPTION);
+ igt_require(gem_scheduler_has_ctx_priority(fd));
+ igt_require(gem_scheduler_has_preemption(fd));
}
igt_subtest("preempt-all")
Couple of tests are using either determining scheduler capabilities or pretty printing. Let's move those to helpers in lib. We can also keep the value obtained from getparam static. v2: Break the trend of expanding ioctl_wrappers Signed-off-by: Michał Winiarski <michal.winiarski@intel.com> Cc: Arkadiusz Hiler <arkadiusz.hiler@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Cc: Katarzyna Dec <katarzyna.dec@intel.com> Cc: Petri Latvala <petri.latvala@intel.com> --- .../intel-gpu-tools/intel-gpu-tools-docs.xml | 5 + lib/Makefile.sources | 2 + lib/i915/gem_scheduler.c | 125 +++++++++++++++++++++ lib/i915/gem_scheduler.h | 37 ++++++ lib/ioctl_wrappers.h | 2 + lib/meson.build | 10 +- tests/gem_exec_nop.c | 34 +----- tests/gem_exec_schedule.c | 47 ++------ tests/gem_exec_whisper.c | 22 +--- tests/gem_sync.c | 34 +----- 10 files changed, 189 insertions(+), 129 deletions(-) create mode 100644 lib/i915/gem_scheduler.c create mode 100644 lib/i915/gem_scheduler.h