1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
// SPDX-License-Identifier: MIT
/*
* Copyright(c) 2023 Intel Corporation. All rights reserved.
*/
#include <stdint.h>
#include "drmtest.h"
#include "igt_aux.h"
#include "igt_core.h"
#include "igt_gt.h"
#include "intel_chipset.h"
#include "intel_reg.h"
#include "ioctl_wrappers.h"
#include "i915/gem.h"
#include "i915/gem_create.h"
#include "i915/gem_engine_topology.h"
#include "i915/perf.h"
/**
* TEST: gem barrier race
* Description: Exercise engine barriers and their interaction with other subsystems
* Feature: core
* Category: Core
* Mega feature: General Core features
* Sub-category: CMD submission
* Functionality: barrier
* Test category: GEM_Legacy
*
* SUBTEST: remote-request
* Description:
* Race intel_context_prepare_remote_request against
* intel_context_active_acquire/release
*/
IGT_TEST_DESCRIPTION("Exercise engine barriers and their interaction with other subsystems");
static void remote_request_workload(int fd, int *done)
{
/*
* Use DRM_IOCTL_I915_PERF_OPEN / close as
* intel_context_prepare_remote_request() workload
*
* Based on code patterns found in tests/i915/perf.c
*/
struct intel_perf_metric_set *metric_set = NULL, *metric_set_iter;
struct intel_perf *intel_perf = intel_perf_for_fd(fd, 0);
uint64_t properties[] = {
DRM_I915_PERF_PROP_SAMPLE_OA, true,
DRM_I915_PERF_PROP_OA_METRICS_SET, 0,
DRM_I915_PERF_PROP_OA_FORMAT, 0,
DRM_I915_PERF_PROP_OA_EXPONENT, 5,
};
struct drm_i915_perf_open_param param = {
.flags = I915_PERF_FLAG_FD_CLOEXEC | I915_PERF_FLAG_DISABLED,
.num_properties = sizeof(properties) / 16,
.properties_ptr = to_user_pointer(properties),
};
uint32_t devid = intel_get_drm_devid(fd);
igt_require(intel_perf);
intel_perf_load_perf_configs(intel_perf, fd);
igt_require(devid);
igt_list_for_each_entry(metric_set_iter, &intel_perf->metric_sets, link) {
if (!strcmp(metric_set_iter->symbol_name,
IS_HASWELL(devid) ? "RenderBasic" : "TestOa")) {
metric_set = metric_set_iter;
break;
}
}
igt_require(metric_set);
igt_require(metric_set->perf_oa_metrics_set);
properties[3] = metric_set->perf_oa_metrics_set;
properties[5] = metric_set->perf_oa_format;
intel_perf_free(intel_perf);
igt_fork(child, 1) {
do {
int stream = igt_ioctl(fd, DRM_IOCTL_I915_PERF_OPEN, ¶m);
igt_assert_fd(stream);
close(stream);
} while (!READ_ONCE(*done));
}
}
/* Copied from tests/i915/gem_ctx_exec.c */
static int exec(int fd, uint32_t handle, int ring, int ctx_id)
{
struct drm_i915_gem_exec_object2 obj = { .handle = handle };
struct drm_i915_gem_execbuffer2 execbuf = {
.buffers_ptr = to_user_pointer(&obj),
.buffer_count = 1,
.flags = ring,
};
i915_execbuffer2_set_context_id(execbuf, ctx_id);
return __gem_execbuf(fd, &execbuf);
}
static void intel_context_first_pin_last_unpin_loop(int fd, uint64_t engine, int *done)
{
/*
* Use gem_create -> gem_write -> gem_execbuf -> gem_sync -> gem_close
* as intel context first pin / last unpin intensive workload
*/
const uint32_t batch[2] = { 0, MI_BATCH_BUFFER_END };
fd = drm_reopen_driver(fd);
do {
uint32_t handle = gem_create(fd, 4096);
gem_write(fd, handle, 0, batch, sizeof(batch));
igt_assert_eq(exec(fd, handle, engine, 0), 0);
gem_sync(fd, handle);
gem_close(fd, handle);
} while (!READ_ONCE(*done));
drm_close_driver(fd);
}
static void test_remote_request(int fd, uint64_t engine, unsigned int timeout)
{
int *done = mmap(0, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
igt_assert(done != MAP_FAILED);
remote_request_workload(fd, done);
igt_fork(child, sysconf(_SC_NPROCESSORS_ONLN))
intel_context_first_pin_last_unpin_loop(fd, engine, done);
sleep(timeout);
*done = 1;
igt_waitchildren();
munmap(done, 4096);
}
igt_main
{
int fd;
igt_fixture {
fd = drm_open_driver_render(DRIVER_INTEL);
igt_require_gem(fd);
}
igt_describe("Race intel_context_prepare_remote_request against intel_context_active_acquire/release");
igt_subtest_with_dynamic("remote-request") {
struct intel_execution_engine2 *e;
for_each_physical_engine(fd, e) {
if (e->class != I915_ENGINE_CLASS_RENDER &&
e->class != I915_ENGINE_CLASS_COMPUTE)
continue;
igt_dynamic(e->name)
test_remote_request(fd, e->flags, 5);
/* We assume no need for all physical engines to be tested */
break;
}
}
igt_fixture
drm_close_driver(fd);
}
|