diff options
author | Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com> | 2023-03-23 15:55:18 -0700 |
---|---|---|
committer | Kamil Konieczny <kamil.konieczny@linux.intel.com> | 2023-03-24 13:31:39 +0100 |
commit | 710004f9647ee411be58582cbec586d36e62a6f9 (patch) | |
tree | 8738084e7e29c4003afcbed5183c148abf89b3b8 | |
parent | c6ed51328b6a0631ef9a01a0fe88436eea784069 (diff) |
i915/perf: Test concurrent access to OA in different groups
With multiple OA buffers, verify that the perf interface allows
concurrent access to the OA buffers in different groups.
v2: (Ashutosh)
- Rename concurrency functions to use group instead of gt
- Fix comment
v3: (CI issues)
- Run group-exclusive-stream tests for >= gen12
- Fix exponent for group-exclusive-stream tests
Signed-off-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
Reviewed-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
-rw-r--r-- | tests/i915/perf.c | 142 |
1 files changed, 138 insertions, 4 deletions
diff --git a/tests/i915/perf.c b/tests/i915/perf.c index 5340eff17..d3f80a19f 100644 --- a/tests/i915/perf.c +++ b/tests/i915/perf.c @@ -2235,6 +2235,7 @@ test_blocking(uint64_t requested_oa_period, int max_iterations = (test_duration_ns / oa_period) + 2; int n_extra_iterations = 0; + int perf_fd; /* It's a bit tricky to put a lower limit here, but we expect a * relatively low latency for seeing reports, while we don't currently @@ -2268,7 +2269,7 @@ test_blocking(uint64_t requested_oa_period, param.num_properties = (idx - props) / 2; param.properties_ptr = to_user_pointer(props); - stream_fd = __perf_open(drm_fd, ¶m, true /* prevent_pm */); + perf_fd = __perf_open(drm_fd, ¶m, true /* prevent_pm */); times(&start_times); @@ -2300,14 +2301,14 @@ test_blocking(uint64_t requested_oa_period, * the error delta. */ start = get_time(); - do_ioctl(stream_fd, I915_PERF_IOCTL_ENABLE, 0); + do_ioctl(perf_fd, I915_PERF_IOCTL_ENABLE, 0); for (/* nop */; ((end = get_time()) - start) < test_duration_ns; /* nop */) { struct drm_i915_perf_record_header *header; bool timer_report_read = false; bool non_timer_report_read = false; int ret; - while ((ret = read(stream_fd, buf, sizeof(buf))) < 0 && + while ((ret = read(perf_fd, buf, sizeof(buf))) < 0 && errno == EINTR) ; @@ -2375,7 +2376,7 @@ test_blocking(uint64_t requested_oa_period, if (!set_kernel_hrtimer) igt_assert(kernel_ns <= (test_duration_ns / 100ull)); - __perf_close(stream_fd); + __perf_close(perf_fd); } static void @@ -5469,6 +5470,14 @@ static void put_engine_groups(struct perf_engine_group *groups, free(groups); } +static struct i915_engine_class_instance * +random_engine(struct perf_engine_group *group) +{ + srandom(time(NULL)); + + return &group->ci[random() % group->num_engines]; +} + static bool has_class_instance(int i915, uint16_t class, uint16_t instance) { int fd; @@ -5491,6 +5500,111 @@ static void set_default_engine(const intel_ctx_t *ctx) default_e2 = *e; } +/* + * Test if OA buffer streams can be independently opened on each group. Once a user + * opens a stream, that group is exclusive to the user, other users get -EBUSY on + * trying to open a stream. + */ +static void +test_group_exclusive_stream(const intel_ctx_t *ctx, bool exponent) +{ + uint64_t properties[] = { + DRM_I915_PERF_PROP_SAMPLE_OA, true, + DRM_I915_PERF_PROP_OA_METRICS_SET, test_set->perf_oa_metrics_set, + DRM_I915_PERF_PROP_OA_FORMAT, test_set->perf_oa_format, + DRM_I915_PERF_PROP_OA_ENGINE_CLASS, 0, + DRM_I915_PERF_PROP_OA_ENGINE_INSTANCE, 0, + DRM_I915_PERF_PROP_OA_EXPONENT, oa_exp_1_millisec, + }; + struct drm_i915_perf_open_param param = { + .flags = I915_PERF_FLAG_FD_CLOEXEC, + /* for gem_context use case, we do no pass exponent */ + .num_properties = exponent ? + ARRAY_SIZE(properties) / 2 : + ARRAY_SIZE(properties) / 2 - 1, + .properties_ptr = to_user_pointer(properties), + }; + uint32_t i, j; + + /* for each group, open one random perf stream with sample OA */ + for (i = 0; i < num_perf_oa_groups; i++) { + struct perf_engine_group *grp = &perf_oa_groups[i]; + struct i915_engine_class_instance *ci = random_engine(grp); + + if (!exponent) { + properties[0] = DRM_I915_PERF_PROP_CTX_HANDLE; + properties[1] = ctx->id; + } + + properties[7] = ci->engine_class; + properties[9] = ci->engine_instance; + grp->perf_fd = igt_ioctl(drm_fd, + DRM_IOCTL_I915_PERF_OPEN, + ¶m); + igt_assert(grp->perf_fd >= 0); + igt_debug("opened OA buffer with c:i %d:%d\n", + ci->engine_class, ci->engine_instance); + } + + /* for each group make sure no other streams can be opened */ + for (i = 0; i < num_perf_oa_groups; i++) { + struct perf_engine_group *grp = &perf_oa_groups[i]; + int err; + + for (j = 0; j < grp->num_engines; j++) { + struct i915_engine_class_instance *ci = grp->ci + j; + + /* + * case 1: + * concurrent access to OAG should fail + */ + properties[0] = DRM_I915_PERF_PROP_SAMPLE_OA; + properties[1] = true; + properties[7] = ci->engine_class; + properties[9] = ci->engine_instance; + /* for SAMPLE OA use case, we must pass exponent */ + param.num_properties = ARRAY_SIZE(properties) / 2; + do_ioctl_err(drm_fd, DRM_IOCTL_I915_PERF_OPEN, ¶m, + EBUSY); + igt_debug("try OA buffer with c:i %d:%d\n", + ci->engine_class, ci->engine_instance); + + /* + * case 2: + * concurrent access to non-OAG unit should fail + */ + properties[0] = DRM_I915_PERF_PROP_CTX_HANDLE; + properties[1] = gem_context_create(drm_fd); + /* for gem_context use case, we do no pass exponent */ + param.num_properties = ARRAY_SIZE(properties) / 2 - 1; + errno = 0; + err = igt_ioctl(drm_fd, DRM_IOCTL_I915_PERF_OPEN, ¶m); + igt_assert(err < 0); + igt_assert(errno == EBUSY || errno == ENODEV); + igt_debug("try OA ci unit with c:i %d:%d\n", + ci->engine_class, ci->engine_instance); + gem_context_destroy(drm_fd, properties[1]); + } + + if (grp->perf_fd >= 0) + close(grp->perf_fd); + } +} + +static void +test_group_concurrent_oa_buffer_read(void) +{ + igt_fork(child, num_perf_oa_groups) { + struct intel_execution_engine2 e; + + e.class = perf_oa_groups[child].ci->engine_class; + e.instance = perf_oa_groups[child].ci->engine_instance; + + test_blocking(40 * 1000 * 1000, false, 5 * 1000 * 1000, &e); + } + igt_waitchildren(); +} + igt_main { const intel_ctx_t *ctx; @@ -5716,6 +5830,26 @@ igt_main igt_describe("Verify invalid class instance"); igt_subtest("gen12-invalid-class-instance") test_invalid_class_instance(); + + /* + * OAR and OAG use cases can be separately opened only on gen12 + * and later, so group-exclusive-stream tests require >= 12. + */ + igt_describe("Verify exclusivity of perf streams with sample oa option"); + igt_subtest("gen12-group-exclusive-stream-sample-oa") { + igt_require(intel_gen(devid) >= 12); + test_group_exclusive_stream(ctx, true); + } + + igt_describe("Verify exclusivity of perf streams with ctx handle"); + igt_subtest("gen12-group-exclusive-stream-ctx-handle") { + igt_require(intel_gen(devid) >= 12); + test_group_exclusive_stream(ctx, false); + } + + igt_describe("Verify concurrent reads from OA buffers in different groups"); + igt_subtest("gen12-group-concurrent-oa-buffer-read") + test_group_concurrent_oa_buffer_read(); } igt_subtest("rc6-disable") |