* [Intel-gfx] [PATCH] drm/i915/selftests: Measure dispatch latency
@ 2020-05-15 15:10 Chris Wilson
2020-05-15 17:32 ` Chris Wilson
` (5 more replies)
0 siblings, 6 replies; 7+ messages in thread
From: Chris Wilson @ 2020-05-15 15:10 UTC (permalink / raw)
To: intel-gfx; +Cc: Chris Wilson
A useful metric of the system's health is how fast we can tell the GPU
to do various actions, so measure our latency.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
drivers/gpu/drm/i915/selftests/i915_request.c | 505 ++++++++++++++++++
1 file changed, 505 insertions(+)
diff --git a/drivers/gpu/drm/i915/selftests/i915_request.c b/drivers/gpu/drm/i915/selftests/i915_request.c
index 6014e8dfcbb1..94c79066f82a 100644
--- a/drivers/gpu/drm/i915/selftests/i915_request.c
+++ b/drivers/gpu/drm/i915/selftests/i915_request.c
@@ -24,13 +24,16 @@
#include <linux/prime_numbers.h>
#include <linux/pm_qos.h>
+#include <linux/sort.h>
#include "gem/i915_gem_pm.h"
#include "gem/selftests/mock_context.h"
+#include "gt/intel_engine_heartbeat.h"
#include "gt/intel_engine_pm.h"
#include "gt/intel_engine_user.h"
#include "gt/intel_gt.h"
+#include "gt/intel_gt_requests.h"
#include "i915_random.h"
#include "i915_selftest.h"
@@ -1524,6 +1527,507 @@ struct perf_series {
struct intel_context *ce[];
};
+#define COUNT 5
+
+static int cmp_u32(const void *A, const void *B)
+{
+ const u32 *a = A, *b = B;
+
+ return *a - *b;
+}
+
+static u32 trifilter(u32 *a)
+{
+ u64 sum;
+
+ sort(a, COUNT, sizeof(*a), cmp_u32, NULL);
+
+ sum = mul_u32_u32(a[2], 2);
+ sum += a[1];
+ sum += a[3];
+
+ return sum >> 2;
+}
+
+static int measure_semaphore_response(struct intel_context *ce)
+{
+ u32 *sema = memset32(ce->engine->status_page.addr + 1000, 0, 21);
+ const u32 offset =
+ i915_ggtt_offset(ce->engine->status_page.vma) +
+ offset_in_page(sema);
+ u32 elapsed[COUNT], cycles;
+ struct i915_request *rq;
+ u32 *cs;
+ int i;
+
+ rq = i915_request_create(ce);
+ if (IS_ERR(rq))
+ return PTR_ERR(rq);
+
+ cs = intel_ring_begin(rq, 4 + 8 * ARRAY_SIZE(elapsed));
+ if (IS_ERR(cs)) {
+ i915_request_add(rq);
+ return PTR_ERR(cs);
+ }
+
+ *cs++ = MI_STORE_DWORD_IMM_GEN4 | MI_USE_GGTT;
+ *cs++ = offset;
+ *cs++ = 0;
+ *cs++ = 0xffffffff;
+
+ for (i = 1; i <= ARRAY_SIZE(elapsed); i++) {
+ *cs++ = MI_SEMAPHORE_WAIT |
+ MI_SEMAPHORE_GLOBAL_GTT |
+ MI_SEMAPHORE_POLL |
+ MI_SEMAPHORE_SAD_EQ_SDD;
+ *cs++ = i;
+ *cs++ = offset;
+ *cs++ = 0;
+
+ *cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
+ *cs++ = ce->engine->mmio_base + 0x358;
+ *cs++ = offset + sizeof(*sema) * i;
+ *cs++ = 0;
+ }
+
+ intel_ring_advance(rq, cs);
+ i915_request_add(rq);
+
+ if (wait_for(READ_ONCE(*sema) == 0xffffffff, 50)) {
+ intel_gt_set_wedged(ce->engine->gt);
+ return -EIO;
+ }
+
+ for (i = 1; i <= ARRAY_SIZE(elapsed); i++) {
+ cycles = ENGINE_READ_FW(ce->engine, RING_TIMESTAMP);
+ WRITE_ONCE(sema[0], i);
+ wmb();
+
+ if (wait_for(READ_ONCE(sema[i]), 50)) {
+ intel_gt_set_wedged(ce->engine->gt);
+ return -EIO;
+ }
+
+ elapsed[i - 1] = (sema[i] - cycles) << COUNT;
+ }
+
+ cycles = trifilter(elapsed);
+ pr_err("%s: semaphore response %d cycles, %lluns\n",
+ ce->engine->name, cycles >> COUNT,
+ i915_cs_timestamp_ticks_to_ns(ce->engine->i915,
+ cycles) >> COUNT);
+
+ return 0;
+}
+
+static int measure_idle_dispatch(struct intel_context *ce)
+{
+ u32 *sema = memset32(ce->engine->status_page.addr + 1000, 0, 21);
+ const u32 offset =
+ i915_ggtt_offset(ce->engine->status_page.vma) +
+ offset_in_page(sema);
+ u32 elapsed[COUNT], cycles;
+ u32 *cs;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(elapsed); i++) {
+ struct i915_request *rq;
+ int err;
+
+ err = intel_gt_wait_for_idle(ce->engine->gt, HZ / 2);
+ if (err)
+ return err;
+
+ rq = i915_request_create(ce);
+ if (IS_ERR(rq))
+ return PTR_ERR(rq);
+
+ cs = intel_ring_begin(rq, 4);
+ if (IS_ERR(cs)) {
+ i915_request_add(rq);
+ return PTR_ERR(cs);
+ }
+
+ *cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
+ *cs++ = ce->engine->mmio_base + 0x358;
+ *cs++ = offset + sizeof(*sema) * i;
+ *cs++ = 0;
+
+ intel_ring_advance(rq, cs);
+
+ elapsed[i] = ENGINE_READ_FW(ce->engine, RING_TIMESTAMP);
+ i915_request_add(rq);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(elapsed); i++) {
+ if (wait_for(READ_ONCE(sema[i]), 50)) {
+ intel_gt_set_wedged(ce->engine->gt);
+ return -EIO;
+ }
+
+ elapsed[i] = (sema[i] - elapsed[i]) << COUNT;
+ }
+
+ cycles = trifilter(elapsed);
+ pr_err("%s: idle dispatch latency %d cycles, %lluns\n",
+ ce->engine->name, cycles >> COUNT,
+ i915_cs_timestamp_ticks_to_ns(ce->engine->i915,
+ cycles) >> COUNT);
+
+ return 0;
+}
+
+static int plug(struct intel_engine_cs *engine, u32 *sema, u32 mode, int value)
+{
+ const u32 offset =
+ i915_ggtt_offset(engine->status_page.vma) +
+ offset_in_page(sema);
+ struct i915_request *rq;
+ u32 *cs;
+
+ rq = i915_request_create(engine->kernel_context);
+ if (IS_ERR(rq))
+ return PTR_ERR(rq);
+
+ cs = intel_ring_begin(rq, 4);
+ if (IS_ERR(cs)) {
+ i915_request_add(rq);
+ return PTR_ERR(cs);
+ }
+
+ *cs++ = MI_SEMAPHORE_WAIT |
+ MI_SEMAPHORE_GLOBAL_GTT |
+ MI_SEMAPHORE_POLL |
+ mode;
+ *cs++ = value;
+ *cs++ = offset;
+ *cs++ = 0;
+
+ intel_ring_advance(rq, cs);
+ i915_request_add(rq);
+
+ return 0;
+}
+
+static int measure_inter_request(struct intel_context *ce)
+{
+ u32 *sema = memset32(ce->engine->status_page.addr + 1000, 0, 21);
+ const u32 offset =
+ i915_ggtt_offset(ce->engine->status_page.vma) +
+ offset_in_page(sema);
+ u32 elapsed[COUNT + 1], cycles;
+ struct i915_sw_fence *submit;
+ int i, err;
+
+ err = plug(ce->engine, sema, MI_SEMAPHORE_SAD_NEQ_SDD, 0);
+ if (err)
+ return err;
+
+ submit = heap_fence_create(GFP_KERNEL);
+ if (!submit) {
+ WRITE_ONCE(sema[0], 1);
+ return -ENOMEM;
+ }
+
+ intel_engine_flush_submission(ce->engine);
+ for (i = 1; i <= ARRAY_SIZE(elapsed); i++) {
+ struct i915_request *rq;
+ u32 *cs;
+
+ rq = i915_request_create(ce);
+ if (IS_ERR(rq)) {
+ WRITE_ONCE(sema[0], 1);
+ return PTR_ERR(rq);
+ }
+
+ err = i915_sw_fence_await_sw_fence_gfp(&rq->submit,
+ submit,
+ GFP_KERNEL);
+ if (err < 0) {
+ i915_sw_fence_commit(submit);
+ heap_fence_put(submit);
+ i915_request_add(rq);
+ WRITE_ONCE(sema[0], 1);
+ return err;
+ }
+
+ cs = intel_ring_begin(rq, 4);
+ if (IS_ERR(cs)) {
+ i915_sw_fence_commit(submit);
+ heap_fence_put(submit);
+ i915_request_add(rq);
+ WRITE_ONCE(sema[0], 1);
+ return PTR_ERR(cs);
+ }
+
+ *cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
+ *cs++ = ce->engine->mmio_base + 0x358;
+ *cs++ = offset + sizeof(*sema) * i;
+ *cs++ = 0;
+
+ intel_ring_advance(rq, cs);
+ i915_request_add(rq);
+ }
+ i915_sw_fence_commit(submit);
+ intel_engine_flush_submission(ce->engine);
+ heap_fence_put(submit);
+
+ WRITE_ONCE(sema[0], 1);
+ if (wait_for(READ_ONCE(sema[COUNT + 1]), 100)) {
+ intel_gt_set_wedged(ce->engine->gt);
+ return -EIO;
+ }
+
+ for (i = 1; i <= COUNT; i++)
+ elapsed[i - 1] = (sema[i + 1] - sema[i]) << COUNT;
+
+ cycles = trifilter(elapsed);
+ pr_err("%s: inter-request latency %d cycles, %lluns\n",
+ ce->engine->name, cycles >> COUNT,
+ i915_cs_timestamp_ticks_to_ns(ce->engine->i915,
+ cycles) >> COUNT);
+
+ return 0;
+}
+
+static int measure_lite_restore(struct intel_context *ce)
+{
+ u32 *sema = memset32(ce->engine->status_page.addr + 1000, 0, 21);
+ const u32 offset =
+ i915_ggtt_offset(ce->engine->status_page.vma) +
+ offset_in_page(sema);
+ u32 elapsed[COUNT + 1], cycles;
+ u32 *cs;
+ int i;
+
+ for (i = 1; i <= ARRAY_SIZE(elapsed); i++) {
+ struct i915_request *rq;
+
+ rq = i915_request_create(ce);
+ if (IS_ERR(rq))
+ return PTR_ERR(rq);
+
+ cs = intel_ring_begin(rq, 12);
+ if (IS_ERR(cs)) {
+ i915_request_add(rq);
+ return PTR_ERR(cs);
+ }
+
+ *cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
+ *cs++ = ce->engine->mmio_base + 0x358;
+ *cs++ = offset + sizeof(*sema) * (2 * i + 0);
+ *cs++ = 0;
+
+ *cs++ = MI_SEMAPHORE_WAIT |
+ MI_SEMAPHORE_GLOBAL_GTT |
+ MI_SEMAPHORE_POLL |
+ MI_SEMAPHORE_SAD_GTE_SDD;
+ *cs++ = i;
+ *cs++ = offset;
+ *cs++ = 0;
+
+ *cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
+ *cs++ = ce->engine->mmio_base + 0x358;
+ *cs++ = offset + sizeof(*sema) * (2 * i + 1);
+ *cs++ = 0;
+
+ intel_ring_advance(rq, cs);
+ i915_request_add(rq);
+ intel_engine_flush_submission(ce->engine);
+
+ WRITE_ONCE(sema[0], i - 1);
+ if (i > 1 && wait_for(READ_ONCE(sema[2 * (i - 1)]), 100)) {
+ intel_gt_set_wedged(ce->engine->gt);
+ return -EIO;
+ }
+ }
+
+ WRITE_ONCE(sema[0], i - 1);
+ if (wait_for(READ_ONCE(sema[2 *i - 1]), 500)) {
+ intel_gt_set_wedged(ce->engine->gt);
+ return -EIO;
+ }
+
+ for (i = 1; i <= COUNT; i++)
+ elapsed[i - 1] = (sema[2 * i + 2] - sema[2 * i + 1]) << COUNT;
+
+ cycles = trifilter(elapsed);
+ pr_err("%s: lite restore latency %d cycles, %lluns\n",
+ ce->engine->name, cycles >> COUNT,
+ i915_cs_timestamp_ticks_to_ns(ce->engine->i915,
+ cycles) >> COUNT);
+
+ return 0;
+}
+
+static int measure_context_switch(struct intel_context *ce)
+{
+ u32 *sema = memset32(ce->engine->status_page.addr + 1000, 0, 21);
+ const u32 offset =
+ i915_ggtt_offset(ce->engine->status_page.vma) +
+ offset_in_page(sema);
+ struct i915_request *fence = NULL;
+ u32 elapsed[COUNT + 1], cycles;
+ int i, j, err;
+ u32 *cs;
+
+ err = plug(ce->engine, sema, MI_SEMAPHORE_SAD_NEQ_SDD, 0);
+ if (err)
+ return err;
+
+ for (i = 1; i <= ARRAY_SIZE(elapsed); i++) {
+ struct intel_context *arr[] = {
+ ce, ce->engine->kernel_context
+ };
+
+ for (j = 0; j < ARRAY_SIZE(arr); j++) {
+ struct i915_request *rq;
+
+ rq = i915_request_create(arr[j]);
+ if (IS_ERR(rq))
+ return PTR_ERR(rq);
+
+ if (fence) {
+ err = i915_request_await_dma_fence(rq,
+ &fence->fence);
+ if (err) {
+ i915_request_add(rq);
+ return err;
+ }
+ }
+
+ cs = intel_ring_begin(rq, 4);
+ if (IS_ERR(cs)) {
+ i915_request_add(rq);
+ return PTR_ERR(cs);
+ }
+
+ *cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
+ *cs++ = ce->engine->mmio_base + 0x358;
+ *cs++ = offset +
+ sizeof(*sema) * (ARRAY_SIZE(arr) * i + j);
+ *cs++ = 0;
+
+ intel_ring_advance(rq, cs);
+
+ i915_request_put(fence);
+ fence = i915_request_get(rq);
+
+ i915_request_add(rq);
+ }
+ }
+ i915_request_put(fence);
+ intel_engine_flush_submission(ce->engine);
+
+ WRITE_ONCE(sema[0], 1);
+ if (wait_for(READ_ONCE(sema[2 *i - 1]), 500)) {
+ intel_gt_set_wedged(ce->engine->gt);
+ return -EIO;
+ }
+
+ for (i = 1; i <= COUNT; i++)
+ elapsed[i - 1] = (sema[2 * i + 2] - sema[2 * i + 1]) << COUNT;
+
+ cycles = trifilter(elapsed);
+ pr_err("%s: context switch latency %d cycles, %lluns\n",
+ ce->engine->name, cycles >> COUNT,
+ i915_cs_timestamp_ticks_to_ns(ce->engine->i915,
+ cycles) >> COUNT);
+
+ return 0;
+}
+
+static void rps_pin(struct intel_gt *gt)
+{
+ /* Pin the frequency to max */
+ atomic_inc(>->rps.num_waiters);
+
+ mutex_lock(>->rps.lock);
+ intel_rps_set(>->rps, gt->rps.max_freq);
+ mutex_unlock(>->rps.lock);
+}
+
+static void rps_unpin(struct intel_gt *gt)
+{
+ atomic_dec(>->rps.num_waiters);
+}
+
+static unsigned long engine_heartbeat_disable(struct intel_engine_cs *engine)
+{
+ unsigned long old;
+
+ old = fetch_and_zero(&engine->props.heartbeat_interval_ms);
+
+ intel_engine_pm_get(engine);
+ intel_engine_park_heartbeat(engine);
+
+ return old;
+}
+
+static void engine_heartbeat_enable(struct intel_engine_cs *engine,
+ unsigned long saved)
+{
+ intel_engine_pm_put(engine);
+
+ engine->props.heartbeat_interval_ms = saved;
+}
+
+static int perf_request_latency(void *arg)
+{
+ struct drm_i915_private *i915 = arg;
+ struct intel_engine_cs *engine;
+ struct pm_qos_request qos;
+ int err = 0;
+
+ if (INTEL_GEN(i915) < 8) /* per-engine CS timestamp, semaphores */
+ return 0;
+
+ cpu_latency_qos_add_request(&qos, 0); /* disable cstates */
+
+ for_each_uabi_engine(engine, i915) {
+ unsigned long saved_heartbeat;
+ struct intel_context *ce;
+
+ ce = intel_context_create(engine);
+ if (IS_ERR(ce))
+ goto out;
+
+ err = intel_context_pin(ce);
+ if (err) {
+ intel_context_put(ce);
+ goto out;
+ }
+
+ saved_heartbeat = engine_heartbeat_disable(engine);
+ intel_uncore_forcewake_get(engine->uncore, FORCEWAKE_ALL);
+ rps_pin(engine->gt);
+
+ if (err == 0)
+ err = measure_semaphore_response(ce);
+ if (err == 0)
+ err = measure_idle_dispatch(ce);
+ if (err == 0)
+ err = measure_inter_request(ce);
+ if (err == 0)
+ err = measure_lite_restore(ce);
+ if (err == 0)
+ err = measure_context_switch(ce);
+
+ rps_unpin(engine->gt);
+ intel_uncore_forcewake_put(engine->uncore, FORCEWAKE_ALL);
+ engine_heartbeat_enable(engine, saved_heartbeat);
+
+ intel_context_unpin(ce);
+ intel_context_put(ce);
+ if (err)
+ goto out;
+ }
+
+out:
+ cpu_latency_qos_remove_request(&qos);
+ return err;
+}
+
static int s_sync0(void *arg)
{
struct perf_series *ps = arg;
@@ -2042,6 +2546,7 @@ static int perf_parallel_engines(void *arg)
int i915_request_perf_selftests(struct drm_i915_private *i915)
{
static const struct i915_subtest tests[] = {
+ SUBTEST(perf_request_latency),
SUBTEST(perf_series_engines),
SUBTEST(perf_parallel_engines),
};
--
2.20.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Intel-gfx] [PATCH] drm/i915/selftests: Measure dispatch latency
2020-05-15 15:10 [Intel-gfx] [PATCH] drm/i915/selftests: Measure dispatch latency Chris Wilson
@ 2020-05-15 17:32 ` Chris Wilson
2020-05-15 17:58 ` Chris Wilson
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Chris Wilson @ 2020-05-15 17:32 UTC (permalink / raw)
To: intel-gfx; +Cc: Chris Wilson
A useful metric of the system's health is how fast we can tell the GPU
to do various actions, so measure our latency.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
drivers/gpu/drm/i915/selftests/i915_request.c | 521 ++++++++++++++++++
1 file changed, 521 insertions(+)
diff --git a/drivers/gpu/drm/i915/selftests/i915_request.c b/drivers/gpu/drm/i915/selftests/i915_request.c
index 6014e8dfcbb1..a47ac68955ec 100644
--- a/drivers/gpu/drm/i915/selftests/i915_request.c
+++ b/drivers/gpu/drm/i915/selftests/i915_request.c
@@ -24,16 +24,20 @@
#include <linux/prime_numbers.h>
#include <linux/pm_qos.h>
+#include <linux/sort.h>
#include "gem/i915_gem_pm.h"
#include "gem/selftests/mock_context.h"
+#include "gt/intel_engine_heartbeat.h"
#include "gt/intel_engine_pm.h"
#include "gt/intel_engine_user.h"
#include "gt/intel_gt.h"
+#include "gt/intel_gt_requests.h"
#include "i915_random.h"
#include "i915_selftest.h"
+#include "igt_flush_test.h"
#include "igt_live_test.h"
#include "igt_spinner.h"
#include "lib_sw_fence.h"
@@ -1524,6 +1528,522 @@ struct perf_series {
struct intel_context *ce[];
};
+#define COUNT 5
+
+static int cmp_u32(const void *A, const void *B)
+{
+ const u32 *a = A, *b = B;
+
+ return *a - *b;
+}
+
+static u32 trifilter(u32 *a)
+{
+ u64 sum;
+
+ sort(a, COUNT, sizeof(*a), cmp_u32, NULL);
+
+ sum = mul_u32_u32(a[2], 2);
+ sum += a[1];
+ sum += a[3];
+
+ return (sum + 2) >> 2;
+}
+
+static u64 cycles_to_ns(struct intel_engine_cs *engine, u32 cycles)
+{
+ u64 ns = i915_cs_timestamp_ticks_to_ns(engine->i915, cycles);
+
+ return DIV_ROUND_CLOSEST(ns, 1 << COUNT);
+}
+
+static int measure_semaphore_response(struct intel_context *ce)
+{
+ u32 *sema = memset32(ce->engine->status_page.addr + 1000, 0, 21);
+ const u32 offset =
+ i915_ggtt_offset(ce->engine->status_page.vma) +
+ offset_in_page(sema);
+ u32 elapsed[COUNT], cycles;
+ struct i915_request *rq;
+ u32 *cs;
+ int i;
+
+ rq = i915_request_create(ce);
+ if (IS_ERR(rq))
+ return PTR_ERR(rq);
+
+ cs = intel_ring_begin(rq, 4 + 8 * ARRAY_SIZE(elapsed));
+ if (IS_ERR(cs)) {
+ i915_request_add(rq);
+ return PTR_ERR(cs);
+ }
+
+ *cs++ = MI_STORE_DWORD_IMM_GEN4 | MI_USE_GGTT;
+ *cs++ = offset;
+ *cs++ = 0;
+ *cs++ = 0xffffffff;
+
+ for (i = 1; i <= ARRAY_SIZE(elapsed); i++) {
+ *cs++ = MI_SEMAPHORE_WAIT |
+ MI_SEMAPHORE_GLOBAL_GTT |
+ MI_SEMAPHORE_POLL |
+ MI_SEMAPHORE_SAD_EQ_SDD;
+ *cs++ = i;
+ *cs++ = offset;
+ *cs++ = 0;
+
+ *cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
+ *cs++ = ce->engine->mmio_base + 0x358;
+ *cs++ = offset + sizeof(*sema) * i;
+ *cs++ = 0;
+ }
+
+ intel_ring_advance(rq, cs);
+ i915_request_add(rq);
+
+ if (wait_for(READ_ONCE(*sema) == 0xffffffff, 50)) {
+ intel_gt_set_wedged(ce->engine->gt);
+ return -EIO;
+ }
+
+ for (i = 1; i <= ARRAY_SIZE(elapsed); i++) {
+ cycles = ENGINE_READ_FW(ce->engine, RING_TIMESTAMP);
+ WRITE_ONCE(sema[0], i);
+ wmb(); /* flush the update to the cache, and beyond */
+
+ if (wait_for(READ_ONCE(sema[i]), 50)) {
+ intel_gt_set_wedged(ce->engine->gt);
+ return -EIO;
+ }
+
+ elapsed[i - 1] = (sema[i] - cycles) << COUNT;
+ }
+
+ cycles = trifilter(elapsed);
+ pr_err("%s: semaphore response %d cycles, %lluns\n",
+ ce->engine->name, cycles >> COUNT,
+ cycles_to_ns(ce->engine, cycles));
+
+ return intel_gt_wait_for_idle(ce->engine->gt, HZ);
+}
+
+static int measure_idle_dispatch(struct intel_context *ce)
+{
+ u32 *sema = memset32(ce->engine->status_page.addr + 1000, 0, 21);
+ const u32 offset =
+ i915_ggtt_offset(ce->engine->status_page.vma) +
+ offset_in_page(sema);
+ u32 elapsed[COUNT], cycles;
+ u32 *cs;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(elapsed); i++) {
+ struct i915_request *rq;
+ int err;
+
+ err = intel_gt_wait_for_idle(ce->engine->gt, HZ / 2);
+ if (err)
+ return err;
+
+ rq = i915_request_create(ce);
+ if (IS_ERR(rq))
+ return PTR_ERR(rq);
+
+ cs = intel_ring_begin(rq, 4);
+ if (IS_ERR(cs)) {
+ i915_request_add(rq);
+ return PTR_ERR(cs);
+ }
+
+ *cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
+ *cs++ = ce->engine->mmio_base + 0x358;
+ *cs++ = offset + sizeof(*sema) * i;
+ *cs++ = 0;
+
+ intel_ring_advance(rq, cs);
+
+ elapsed[i] = ENGINE_READ_FW(ce->engine, RING_TIMESTAMP);
+
+ local_bh_disable();
+ i915_request_add(rq);
+ local_bh_enable();
+ }
+
+ for (i = 0; i < ARRAY_SIZE(elapsed); i++) {
+ if (wait_for(READ_ONCE(sema[i]), 50)) {
+ intel_gt_set_wedged(ce->engine->gt);
+ return -EIO;
+ }
+
+ elapsed[i] = (sema[i] - elapsed[i]) << COUNT;
+ }
+
+ cycles = trifilter(elapsed);
+ pr_err("%s: idle dispatch latency %d cycles, %lluns\n",
+ ce->engine->name, cycles >> COUNT,
+ cycles_to_ns(ce->engine, cycles));
+
+ return intel_gt_wait_for_idle(ce->engine->gt, HZ);
+}
+
+static int measure_busy_dispatch(struct intel_context *ce)
+{
+ u32 *sema = memset32(ce->engine->status_page.addr + 1000, 0, 21);
+ const u32 offset =
+ i915_ggtt_offset(ce->engine->status_page.vma) +
+ offset_in_page(sema);
+ u32 elapsed[COUNT + 1], cycles;
+ u32 *cs;
+ int i;
+
+ for (i = 1; i <= ARRAY_SIZE(elapsed); i++) {
+ struct i915_request *rq;
+
+ rq = i915_request_create(ce);
+ if (IS_ERR(rq))
+ return PTR_ERR(rq);
+
+ cs = intel_ring_begin(rq, 12);
+ if (IS_ERR(cs)) {
+ i915_request_add(rq);
+ return PTR_ERR(cs);
+ }
+
+ *cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
+ *cs++ = ce->engine->mmio_base + 0x358;
+ *cs++ = offset + sizeof(*sema) * i;
+ *cs++ = 0;
+
+ *cs++ = MI_SEMAPHORE_WAIT |
+ MI_SEMAPHORE_GLOBAL_GTT |
+ MI_SEMAPHORE_POLL |
+ MI_SEMAPHORE_SAD_GTE_SDD;
+ *cs++ = i;
+ *cs++ = offset;
+ *cs++ = 0;
+
+ *cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
+ *cs++ = ce->engine->mmio_base + 0x358;
+ *cs++ = offset + sizeof(*sema) * i;
+ *cs++ = 0;
+
+ intel_ring_advance(rq, cs);
+
+ if (i > 1 && wait_for(READ_ONCE(sema[i - 1]), 500)) {
+ intel_gt_set_wedged(ce->engine->gt);
+ return -EIO;
+ }
+
+ elapsed[i - 1] = ENGINE_READ_FW(ce->engine, RING_TIMESTAMP);
+
+ local_bh_disable();
+ i915_request_add(rq);
+ local_bh_enable();
+
+ WRITE_ONCE(sema[0], i - 1);
+ wmb(); /* flush the update to the cache, and beyond */
+ }
+ WRITE_ONCE(sema[0], i - 1);
+
+ for (i = 1; i <= COUNT; i++)
+ elapsed[i - 1] = (sema[i] - elapsed[i]) << COUNT;
+
+ cycles = trifilter(elapsed);
+ pr_err("%s: busy dispatch latency %d cycles, %lluns\n",
+ ce->engine->name, cycles >> COUNT,
+ cycles_to_ns(ce->engine, cycles));
+
+ return intel_gt_wait_for_idle(ce->engine->gt, HZ);
+}
+
+static int plug(struct intel_engine_cs *engine, u32 *sema, u32 mode, int value)
+{
+ const u32 offset =
+ i915_ggtt_offset(engine->status_page.vma) +
+ offset_in_page(sema);
+ struct i915_request *rq;
+ u32 *cs;
+
+ rq = i915_request_create(engine->kernel_context);
+ if (IS_ERR(rq))
+ return PTR_ERR(rq);
+
+ cs = intel_ring_begin(rq, 4);
+ if (IS_ERR(cs)) {
+ i915_request_add(rq);
+ return PTR_ERR(cs);
+ }
+
+ *cs++ = MI_SEMAPHORE_WAIT |
+ MI_SEMAPHORE_GLOBAL_GTT |
+ MI_SEMAPHORE_POLL |
+ mode;
+ *cs++ = value;
+ *cs++ = offset;
+ *cs++ = 0;
+
+ intel_ring_advance(rq, cs);
+ i915_request_add(rq);
+
+ return 0;
+}
+
+static int measure_inter_request(struct intel_context *ce)
+{
+ u32 *sema = memset32(ce->engine->status_page.addr + 1000, 0, 21);
+ const u32 offset =
+ i915_ggtt_offset(ce->engine->status_page.vma) +
+ offset_in_page(sema);
+ u32 elapsed[COUNT + 1], cycles;
+ struct i915_sw_fence *submit;
+ int i, err;
+
+ err = plug(ce->engine, sema, MI_SEMAPHORE_SAD_NEQ_SDD, 0);
+ if (err)
+ return err;
+
+ submit = heap_fence_create(GFP_KERNEL);
+ if (!submit) {
+ WRITE_ONCE(sema[0], 1);
+ return -ENOMEM;
+ }
+
+ intel_engine_flush_submission(ce->engine);
+ for (i = 1; i <= ARRAY_SIZE(elapsed); i++) {
+ struct i915_request *rq;
+ u32 *cs;
+
+ rq = i915_request_create(ce);
+ if (IS_ERR(rq)) {
+ WRITE_ONCE(sema[0], 1);
+ return PTR_ERR(rq);
+ }
+
+ err = i915_sw_fence_await_sw_fence_gfp(&rq->submit,
+ submit,
+ GFP_KERNEL);
+ if (err < 0) {
+ i915_sw_fence_commit(submit);
+ heap_fence_put(submit);
+ i915_request_add(rq);
+ WRITE_ONCE(sema[0], 1);
+ return err;
+ }
+
+ cs = intel_ring_begin(rq, 4);
+ if (IS_ERR(cs)) {
+ i915_sw_fence_commit(submit);
+ heap_fence_put(submit);
+ i915_request_add(rq);
+ WRITE_ONCE(sema[0], 1);
+ return PTR_ERR(cs);
+ }
+
+ *cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
+ *cs++ = ce->engine->mmio_base + 0x358;
+ *cs++ = offset + sizeof(*sema) * i;
+ *cs++ = 0;
+
+ intel_ring_advance(rq, cs);
+ i915_request_add(rq);
+ }
+ local_bh_disable();
+ i915_sw_fence_commit(submit);
+ local_bh_enable();
+ intel_engine_flush_submission(ce->engine);
+ heap_fence_put(submit);
+
+ WRITE_ONCE(sema[0], 1);
+ wmb(); /* flush the update to the cache, and beyond */
+
+ if (wait_for(READ_ONCE(sema[COUNT + 1]), 100)) {
+ intel_gt_set_wedged(ce->engine->gt);
+ return -EIO;
+ }
+
+ for (i = 1; i <= COUNT; i++)
+ elapsed[i - 1] = (sema[i + 1] - sema[i]) << COUNT;
+
+ cycles = trifilter(elapsed);
+ pr_err("%s: inter-request latency %d cycles, %lluns\n",
+ ce->engine->name, cycles >> COUNT,
+ cycles_to_ns(ce->engine, cycles));
+
+ return intel_gt_wait_for_idle(ce->engine->gt, HZ);
+}
+
+static int measure_context_switch(struct intel_context *ce)
+{
+ u32 *sema = memset32(ce->engine->status_page.addr + 1000, 0, 21);
+ const u32 offset =
+ i915_ggtt_offset(ce->engine->status_page.vma) +
+ offset_in_page(sema);
+ struct i915_request *fence = NULL;
+ u32 elapsed[COUNT + 1], cycles;
+ int i, j, err;
+ u32 *cs;
+
+ err = plug(ce->engine, sema, MI_SEMAPHORE_SAD_NEQ_SDD, 0);
+ if (err)
+ return err;
+
+ for (i = 1; i <= ARRAY_SIZE(elapsed); i++) {
+ struct intel_context *arr[] = {
+ ce, ce->engine->kernel_context
+ };
+
+ for (j = 0; j < ARRAY_SIZE(arr); j++) {
+ struct i915_request *rq;
+
+ rq = i915_request_create(arr[j]);
+ if (IS_ERR(rq))
+ return PTR_ERR(rq);
+
+ if (fence) {
+ err = i915_request_await_dma_fence(rq,
+ &fence->fence);
+ if (err) {
+ i915_request_add(rq);
+ return err;
+ }
+ }
+
+ cs = intel_ring_begin(rq, 4);
+ if (IS_ERR(cs)) {
+ i915_request_add(rq);
+ return PTR_ERR(cs);
+ }
+
+ *cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
+ *cs++ = ce->engine->mmio_base + 0x358;
+ *cs++ = offset +
+ sizeof(*sema) * (ARRAY_SIZE(arr) * i + j);
+ *cs++ = 0;
+
+ intel_ring_advance(rq, cs);
+
+ i915_request_put(fence);
+ fence = i915_request_get(rq);
+
+ i915_request_add(rq);
+ }
+ }
+ i915_request_put(fence);
+ intel_engine_flush_submission(ce->engine);
+
+ WRITE_ONCE(sema[0], 1);
+ wmb(); /* flush the update to the cache, and beyond */
+
+ if (wait_for(READ_ONCE(sema[2 *i - 1]), 500)) {
+ intel_gt_set_wedged(ce->engine->gt);
+ return -EIO;
+ }
+
+ for (i = 1; i <= COUNT; i++)
+ elapsed[i - 1] = (sema[2 * i + 2] - sema[2 * i + 1]) << COUNT;
+
+ cycles = trifilter(elapsed);
+ pr_err("%s: context switch latency %d cycles, %lluns\n",
+ ce->engine->name, cycles >> COUNT,
+ cycles_to_ns(ce->engine, cycles));
+
+ return intel_gt_wait_for_idle(ce->engine->gt, HZ);
+}
+
+static void rps_pin(struct intel_gt *gt)
+{
+ /* Pin the frequency to max */
+ atomic_inc(>->rps.num_waiters);
+ intel_uncore_forcewake_get(gt->uncore, FORCEWAKE_ALL);
+
+ mutex_lock(>->rps.lock);
+ intel_rps_set(>->rps, gt->rps.max_freq);
+ mutex_unlock(>->rps.lock);
+}
+
+static void rps_unpin(struct intel_gt *gt)
+{
+ intel_uncore_forcewake_put(gt->uncore, FORCEWAKE_ALL);
+ atomic_dec(>->rps.num_waiters);
+}
+
+static unsigned long engine_heartbeat_disable(struct intel_engine_cs *engine)
+{
+ unsigned long old;
+
+ old = fetch_and_zero(&engine->props.heartbeat_interval_ms);
+
+ intel_engine_pm_get(engine);
+ intel_engine_park_heartbeat(engine);
+
+ return old;
+}
+
+static void engine_heartbeat_enable(struct intel_engine_cs *engine,
+ unsigned long saved)
+{
+ intel_engine_pm_put(engine);
+
+ engine->props.heartbeat_interval_ms = saved;
+}
+
+static int perf_request_latency(void *arg)
+{
+ struct drm_i915_private *i915 = arg;
+ struct intel_engine_cs *engine;
+ struct pm_qos_request qos;
+ int err = 0;
+
+ if (INTEL_GEN(i915) < 8) /* per-engine CS timestamp, semaphores */
+ return 0;
+
+ cpu_latency_qos_add_request(&qos, 0); /* disable cstates */
+
+ for_each_uabi_engine(engine, i915) {
+ unsigned long saved_heartbeat;
+ struct intel_context *ce;
+
+ ce = intel_context_create(engine);
+ if (IS_ERR(ce))
+ goto out;
+
+ err = intel_context_pin(ce);
+ if (err) {
+ intel_context_put(ce);
+ goto out;
+ }
+
+ saved_heartbeat = engine_heartbeat_disable(engine);
+ rps_pin(engine->gt);
+
+ if (err == 0)
+ err = measure_semaphore_response(ce);
+ if (err == 0)
+ err = measure_idle_dispatch(ce);
+ if (err == 0)
+ err = measure_busy_dispatch(ce);
+ if (err == 0)
+ err = measure_inter_request(ce);
+ if (err == 0)
+ err = measure_context_switch(ce);
+
+ rps_unpin(engine->gt);
+ engine_heartbeat_enable(engine, saved_heartbeat);
+
+ intel_context_unpin(ce);
+ intel_context_put(ce);
+ if (err)
+ goto out;
+ }
+
+out:
+ if (igt_flush_test(i915))
+ err = -EIO;
+
+ cpu_latency_qos_remove_request(&qos);
+ return err;
+}
+
static int s_sync0(void *arg)
{
struct perf_series *ps = arg;
@@ -2042,6 +2562,7 @@ static int perf_parallel_engines(void *arg)
int i915_request_perf_selftests(struct drm_i915_private *i915)
{
static const struct i915_subtest tests[] = {
+ SUBTEST(perf_request_latency),
SUBTEST(perf_series_engines),
SUBTEST(perf_parallel_engines),
};
--
2.20.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Intel-gfx] [PATCH] drm/i915/selftests: Measure dispatch latency
2020-05-15 15:10 [Intel-gfx] [PATCH] drm/i915/selftests: Measure dispatch latency Chris Wilson
2020-05-15 17:32 ` Chris Wilson
@ 2020-05-15 17:58 ` Chris Wilson
2020-05-15 18:02 ` Chris Wilson
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Chris Wilson @ 2020-05-15 17:58 UTC (permalink / raw)
To: intel-gfx; +Cc: Chris Wilson
A useful metric of the system's health is how fast we can tell the GPU
to do various actions, so measure our latency.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
drivers/gpu/drm/i915/selftests/i915_request.c | 612 ++++++++++++++++++
1 file changed, 612 insertions(+)
diff --git a/drivers/gpu/drm/i915/selftests/i915_request.c b/drivers/gpu/drm/i915/selftests/i915_request.c
index 6014e8dfcbb1..c265501c26a8 100644
--- a/drivers/gpu/drm/i915/selftests/i915_request.c
+++ b/drivers/gpu/drm/i915/selftests/i915_request.c
@@ -24,16 +24,20 @@
#include <linux/prime_numbers.h>
#include <linux/pm_qos.h>
+#include <linux/sort.h>
#include "gem/i915_gem_pm.h"
#include "gem/selftests/mock_context.h"
+#include "gt/intel_engine_heartbeat.h"
#include "gt/intel_engine_pm.h"
#include "gt/intel_engine_user.h"
#include "gt/intel_gt.h"
+#include "gt/intel_gt_requests.h"
#include "i915_random.h"
#include "i915_selftest.h"
+#include "igt_flush_test.h"
#include "igt_live_test.h"
#include "igt_spinner.h"
#include "lib_sw_fence.h"
@@ -1524,6 +1528,613 @@ struct perf_series {
struct intel_context *ce[];
};
+#define COUNT 5
+
+static int cmp_u32(const void *A, const void *B)
+{
+ const u32 *a = A, *b = B;
+
+ return *a - *b;
+}
+
+static u32 trifilter(u32 *a)
+{
+ u64 sum;
+
+ sort(a, COUNT, sizeof(*a), cmp_u32, NULL);
+
+ sum = mul_u32_u32(a[2], 2);
+ sum += a[1];
+ sum += a[3];
+
+ return (sum + 2) >> 2;
+}
+
+static u64 cycles_to_ns(struct intel_engine_cs *engine, u32 cycles)
+{
+ u64 ns = i915_cs_timestamp_ticks_to_ns(engine->i915, cycles);
+
+ return DIV_ROUND_CLOSEST(ns, 1 << COUNT);
+}
+
+static int measure_semaphore_response(struct intel_context *ce)
+{
+ u32 *sema = memset32(ce->engine->status_page.addr + 1000, 0, 21);
+ const u32 offset =
+ i915_ggtt_offset(ce->engine->status_page.vma) +
+ offset_in_page(sema);
+ u32 elapsed[COUNT], cycles;
+ struct i915_request *rq;
+ u32 *cs;
+ int i;
+
+ rq = i915_request_create(ce);
+ if (IS_ERR(rq))
+ return PTR_ERR(rq);
+
+ cs = intel_ring_begin(rq, 4 + 8 * ARRAY_SIZE(elapsed));
+ if (IS_ERR(cs)) {
+ i915_request_add(rq);
+ return PTR_ERR(cs);
+ }
+
+ *cs++ = MI_STORE_DWORD_IMM_GEN4 | MI_USE_GGTT;
+ *cs++ = offset;
+ *cs++ = 0;
+ *cs++ = 0xffffffff;
+
+ for (i = 1; i <= ARRAY_SIZE(elapsed); i++) {
+ *cs++ = MI_SEMAPHORE_WAIT |
+ MI_SEMAPHORE_GLOBAL_GTT |
+ MI_SEMAPHORE_POLL |
+ MI_SEMAPHORE_SAD_EQ_SDD;
+ *cs++ = i;
+ *cs++ = offset;
+ *cs++ = 0;
+
+ *cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
+ *cs++ = ce->engine->mmio_base + 0x358;
+ *cs++ = offset + sizeof(*sema) * i;
+ *cs++ = 0;
+ }
+
+ intel_ring_advance(rq, cs);
+ i915_request_add(rq);
+
+ if (wait_for(READ_ONCE(*sema) == 0xffffffff, 50)) {
+ intel_gt_set_wedged(ce->engine->gt);
+ return -EIO;
+ }
+
+ for (i = 1; i <= ARRAY_SIZE(elapsed); i++) {
+ cycles = ENGINE_READ_FW(ce->engine, RING_TIMESTAMP);
+ WRITE_ONCE(sema[0], i);
+ wmb(); /* flush the update to the cache, and beyond */
+
+ if (wait_for(READ_ONCE(sema[i]), 50)) {
+ intel_gt_set_wedged(ce->engine->gt);
+ return -EIO;
+ }
+
+ elapsed[i - 1] = (sema[i] - cycles) << COUNT;
+ }
+
+ cycles = trifilter(elapsed);
+ pr_info("%s: semaphore response %d cycles, %lluns\n",
+ ce->engine->name, cycles >> COUNT,
+ cycles_to_ns(ce->engine, cycles));
+
+ return intel_gt_wait_for_idle(ce->engine->gt, HZ);
+}
+
+static int measure_idle_dispatch(struct intel_context *ce)
+{
+ u32 *sema = memset32(ce->engine->status_page.addr + 1000, 0, 21);
+ const u32 offset =
+ i915_ggtt_offset(ce->engine->status_page.vma) +
+ offset_in_page(sema);
+ u32 elapsed[COUNT], cycles;
+ u32 *cs;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(elapsed); i++) {
+ struct i915_request *rq;
+ int err;
+
+ err = intel_gt_wait_for_idle(ce->engine->gt, HZ / 2);
+ if (err)
+ return err;
+
+ rq = i915_request_create(ce);
+ if (IS_ERR(rq))
+ return PTR_ERR(rq);
+
+ cs = intel_ring_begin(rq, 4);
+ if (IS_ERR(cs)) {
+ i915_request_add(rq);
+ return PTR_ERR(cs);
+ }
+
+ *cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
+ *cs++ = ce->engine->mmio_base + 0x358;
+ *cs++ = offset + sizeof(*sema) * i;
+ *cs++ = 0;
+
+ intel_ring_advance(rq, cs);
+
+ preempt_disable();
+ local_bh_disable();
+ elapsed[i] = ENGINE_READ_FW(ce->engine, RING_TIMESTAMP);
+ i915_request_add(rq);
+ local_bh_enable();
+ preempt_enable();
+ }
+
+ for (i = 0; i < ARRAY_SIZE(elapsed); i++) {
+ if (wait_for(READ_ONCE(sema[i]), 50)) {
+ intel_gt_set_wedged(ce->engine->gt);
+ return -EIO;
+ }
+
+ elapsed[i] = (sema[i] - elapsed[i]) << COUNT;
+ }
+
+ cycles = trifilter(elapsed);
+ pr_info("%s: idle dispatch latency %d cycles, %lluns\n",
+ ce->engine->name, cycles >> COUNT,
+ cycles_to_ns(ce->engine, cycles));
+
+ return intel_gt_wait_for_idle(ce->engine->gt, HZ);
+}
+
+static int measure_busy_dispatch(struct intel_context *ce)
+{
+ u32 *sema = memset32(ce->engine->status_page.addr + 1000, 0, 21);
+ const u32 offset =
+ i915_ggtt_offset(ce->engine->status_page.vma) +
+ offset_in_page(sema);
+ u32 elapsed[COUNT + 1], cycles;
+ u32 *cs;
+ int i;
+
+ for (i = 1; i <= ARRAY_SIZE(elapsed); i++) {
+ struct i915_request *rq;
+
+ rq = i915_request_create(ce);
+ if (IS_ERR(rq))
+ return PTR_ERR(rq);
+
+ cs = intel_ring_begin(rq, 12);
+ if (IS_ERR(cs)) {
+ i915_request_add(rq);
+ return PTR_ERR(cs);
+ }
+
+ *cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
+ *cs++ = ce->engine->mmio_base + 0x358;
+ *cs++ = offset + sizeof(*sema) * i;
+ *cs++ = 0;
+
+ *cs++ = MI_SEMAPHORE_WAIT |
+ MI_SEMAPHORE_GLOBAL_GTT |
+ MI_SEMAPHORE_POLL |
+ MI_SEMAPHORE_SAD_GTE_SDD;
+ *cs++ = i;
+ *cs++ = offset;
+ *cs++ = 0;
+
+ *cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
+ *cs++ = ce->engine->mmio_base + 0x358;
+ *cs++ = offset + sizeof(*sema) * i;
+ *cs++ = 0;
+
+ intel_ring_advance(rq, cs);
+
+ if (i > 1 && wait_for(READ_ONCE(sema[i - 1]), 500)) {
+ intel_gt_set_wedged(ce->engine->gt);
+ return -EIO;
+ }
+
+ preempt_disable();
+ local_bh_disable();
+ elapsed[i - 1] = ENGINE_READ_FW(ce->engine, RING_TIMESTAMP);
+ i915_request_add(rq);
+ local_bh_enable();
+ WRITE_ONCE(sema[0], i - 1);
+ wmb(); /* flush the update to the cache, and beyond */
+ preempt_enable();
+ }
+ WRITE_ONCE(sema[0], i - 1);
+
+ for (i = 1; i <= COUNT; i++)
+ elapsed[i - 1] = (sema[i] - elapsed[i]) << COUNT;
+
+ cycles = trifilter(elapsed);
+ pr_info("%s: busy dispatch latency %d cycles, %lluns\n",
+ ce->engine->name, cycles >> COUNT,
+ cycles_to_ns(ce->engine, cycles));
+
+ return intel_gt_wait_for_idle(ce->engine->gt, HZ);
+}
+
+static int plug(struct intel_engine_cs *engine, u32 *sema, u32 mode, int value)
+{
+ const u32 offset =
+ i915_ggtt_offset(engine->status_page.vma) +
+ offset_in_page(sema);
+ struct i915_request *rq;
+ u32 *cs;
+
+ rq = i915_request_create(engine->kernel_context);
+ if (IS_ERR(rq))
+ return PTR_ERR(rq);
+
+ cs = intel_ring_begin(rq, 4);
+ if (IS_ERR(cs)) {
+ i915_request_add(rq);
+ return PTR_ERR(cs);
+ }
+
+ *cs++ = MI_SEMAPHORE_WAIT |
+ MI_SEMAPHORE_GLOBAL_GTT |
+ MI_SEMAPHORE_POLL |
+ mode;
+ *cs++ = value;
+ *cs++ = offset;
+ *cs++ = 0;
+
+ intel_ring_advance(rq, cs);
+ i915_request_add(rq);
+
+ return 0;
+}
+
+static int measure_inter_request(struct intel_context *ce)
+{
+ u32 *sema = memset32(ce->engine->status_page.addr + 1000, 0, 21);
+ const u32 offset =
+ i915_ggtt_offset(ce->engine->status_page.vma) +
+ offset_in_page(sema);
+ u32 elapsed[COUNT + 1], cycles;
+ struct i915_sw_fence *submit;
+ int i, err;
+
+ err = plug(ce->engine, sema, MI_SEMAPHORE_SAD_NEQ_SDD, 0);
+ if (err)
+ return err;
+
+ submit = heap_fence_create(GFP_KERNEL);
+ if (!submit) {
+ WRITE_ONCE(sema[0], 1);
+ return -ENOMEM;
+ }
+
+ intel_engine_flush_submission(ce->engine);
+ for (i = 1; i <= ARRAY_SIZE(elapsed); i++) {
+ struct i915_request *rq;
+ u32 *cs;
+
+ rq = i915_request_create(ce);
+ if (IS_ERR(rq)) {
+ WRITE_ONCE(sema[0], 1);
+ return PTR_ERR(rq);
+ }
+
+ err = i915_sw_fence_await_sw_fence_gfp(&rq->submit,
+ submit,
+ GFP_KERNEL);
+ if (err < 0) {
+ i915_sw_fence_commit(submit);
+ heap_fence_put(submit);
+ i915_request_add(rq);
+ WRITE_ONCE(sema[0], 1);
+ return err;
+ }
+
+ cs = intel_ring_begin(rq, 4);
+ if (IS_ERR(cs)) {
+ i915_sw_fence_commit(submit);
+ heap_fence_put(submit);
+ i915_request_add(rq);
+ WRITE_ONCE(sema[0], 1);
+ return PTR_ERR(cs);
+ }
+
+ *cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
+ *cs++ = ce->engine->mmio_base + 0x358;
+ *cs++ = offset + sizeof(*sema) * i;
+ *cs++ = 0;
+
+ intel_ring_advance(rq, cs);
+ i915_request_add(rq);
+ }
+ local_bh_disable();
+ i915_sw_fence_commit(submit);
+ local_bh_enable();
+ intel_engine_flush_submission(ce->engine);
+ heap_fence_put(submit);
+
+ WRITE_ONCE(sema[0], 1);
+ wmb(); /* flush the update to the cache, and beyond */
+
+ if (wait_for(READ_ONCE(sema[COUNT + 1]), 100)) {
+ intel_gt_set_wedged(ce->engine->gt);
+ return -EIO;
+ }
+
+ for (i = 1; i <= COUNT; i++)
+ elapsed[i - 1] = (sema[i + 1] - sema[i]) << COUNT;
+
+ cycles = trifilter(elapsed);
+ pr_info("%s: inter-request latency %d cycles, %lluns\n",
+ ce->engine->name, cycles >> COUNT,
+ cycles_to_ns(ce->engine, cycles));
+
+ return intel_gt_wait_for_idle(ce->engine->gt, HZ);
+}
+
+static int measure_context_switch(struct intel_context *ce)
+{
+ u32 *sema = memset32(ce->engine->status_page.addr + 1000, 0, 21);
+ const u32 offset =
+ i915_ggtt_offset(ce->engine->status_page.vma) +
+ offset_in_page(sema);
+ struct i915_request *fence = NULL;
+ u32 elapsed[COUNT + 1], cycles;
+ int i, j, err;
+ u32 *cs;
+
+ err = plug(ce->engine, sema, MI_SEMAPHORE_SAD_NEQ_SDD, 0);
+ if (err)
+ return err;
+
+ for (i = 1; i <= ARRAY_SIZE(elapsed); i++) {
+ struct intel_context *arr[] = {
+ ce, ce->engine->kernel_context
+ };
+
+ for (j = 0; j < ARRAY_SIZE(arr); j++) {
+ struct i915_request *rq;
+
+ rq = i915_request_create(arr[j]);
+ if (IS_ERR(rq))
+ return PTR_ERR(rq);
+
+ if (fence) {
+ err = i915_request_await_dma_fence(rq,
+ &fence->fence);
+ if (err) {
+ i915_request_add(rq);
+ return err;
+ }
+ }
+
+ cs = intel_ring_begin(rq, 4);
+ if (IS_ERR(cs)) {
+ i915_request_add(rq);
+ return PTR_ERR(cs);
+ }
+
+ *cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
+ *cs++ = ce->engine->mmio_base + 0x358;
+ *cs++ = offset +
+ sizeof(*sema) * (ARRAY_SIZE(arr) * i + j);
+ *cs++ = 0;
+
+ intel_ring_advance(rq, cs);
+
+ i915_request_put(fence);
+ fence = i915_request_get(rq);
+
+ i915_request_add(rq);
+ }
+ }
+ i915_request_put(fence);
+ intel_engine_flush_submission(ce->engine);
+
+ WRITE_ONCE(sema[0], 1);
+ wmb(); /* flush the update to the cache, and beyond */
+
+ if (wait_for(READ_ONCE(sema[2 *i - 1]), 500)) {
+ intel_gt_set_wedged(ce->engine->gt);
+ return -EIO;
+ }
+
+ for (i = 1; i <= COUNT; i++)
+ elapsed[i - 1] = (sema[2 * i + 2] - sema[2 * i + 1]) << COUNT;
+
+ cycles = trifilter(elapsed);
+ pr_info("%s: context switch latency %d cycles, %lluns\n",
+ ce->engine->name, cycles >> COUNT,
+ cycles_to_ns(ce->engine, cycles));
+
+ return intel_gt_wait_for_idle(ce->engine->gt, HZ);
+}
+
+struct signal_cb {
+ struct dma_fence_cb base;
+ bool seen;
+};
+
+static void signal_cb(struct dma_fence *fence, struct dma_fence_cb *cb)
+{
+ struct signal_cb *s = container_of(cb, typeof(*s), base);
+
+ smp_store_mb(s->seen, true); /* be safe, be strong */
+}
+
+static int measure_completion(struct intel_context *ce)
+{
+ u32 *sema = memset32(ce->engine->status_page.addr + 1000, 0, 21);
+ const u32 offset =
+ i915_ggtt_offset(ce->engine->status_page.vma) +
+ offset_in_page(sema);
+ u32 elapsed[COUNT], cycles;
+ u32 *cs;
+ int i;
+
+ for (i = 1; i <= ARRAY_SIZE(elapsed); i++) {
+ struct signal_cb cb = { .seen = false };
+ struct i915_request *rq;
+
+ rq = i915_request_create(ce);
+ if (IS_ERR(rq))
+ return PTR_ERR(rq);
+
+ cs = intel_ring_begin(rq, 12);
+ if (IS_ERR(cs)) {
+ i915_request_add(rq);
+ return PTR_ERR(cs);
+ }
+
+ *cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
+ *cs++ = ce->engine->mmio_base + 0x358;
+ *cs++ = offset + sizeof(*sema) * i;
+ *cs++ = 0;
+
+ *cs++ = MI_SEMAPHORE_WAIT |
+ MI_SEMAPHORE_GLOBAL_GTT |
+ MI_SEMAPHORE_POLL |
+ MI_SEMAPHORE_SAD_EQ_SDD;
+ *cs++ = i;
+ *cs++ = offset;
+ *cs++ = 0;
+
+ *cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
+ *cs++ = ce->engine->mmio_base + 0x358;
+ *cs++ = offset + sizeof(*sema) * i;
+ *cs++ = 0;
+
+ intel_ring_advance(rq, cs);
+
+ dma_fence_add_callback(&rq->fence, &cb.base, signal_cb);
+
+ local_bh_disable();
+ i915_request_add(rq);
+ local_bh_enable();
+
+ if (wait_for(READ_ONCE(sema[i]), 50)) {
+ intel_gt_set_wedged(ce->engine->gt);
+ return -EIO;
+ }
+
+ preempt_disable();
+ WRITE_ONCE(sema[0], i);
+ wmb();
+ while (!READ_ONCE(cb.seen))
+ cpu_relax();
+
+ elapsed[i - 1] = ENGINE_READ_FW(ce->engine, RING_TIMESTAMP);
+ preempt_enable();
+ }
+
+ for (i = 0; i < ARRAY_SIZE(elapsed); i++)
+ elapsed[i] = (sema[i + 1] - elapsed[i]) << COUNT;
+
+ cycles = trifilter(elapsed);
+ pr_info("%s: completion latency %d cycles, %lluns\n",
+ ce->engine->name, cycles >> COUNT,
+ cycles_to_ns(ce->engine, cycles));
+
+ return intel_gt_wait_for_idle(ce->engine->gt, HZ);
+}
+
+static void rps_pin(struct intel_gt *gt)
+{
+ /* Pin the frequency to max */
+ atomic_inc(>->rps.num_waiters);
+ intel_uncore_forcewake_get(gt->uncore, FORCEWAKE_ALL);
+
+ mutex_lock(>->rps.lock);
+ intel_rps_set(>->rps, gt->rps.max_freq);
+ mutex_unlock(>->rps.lock);
+}
+
+static void rps_unpin(struct intel_gt *gt)
+{
+ intel_uncore_forcewake_put(gt->uncore, FORCEWAKE_ALL);
+ atomic_dec(>->rps.num_waiters);
+}
+
+static unsigned long engine_heartbeat_disable(struct intel_engine_cs *engine)
+{
+ unsigned long old;
+
+ old = fetch_and_zero(&engine->props.heartbeat_interval_ms);
+
+ intel_engine_pm_get(engine);
+ intel_engine_park_heartbeat(engine);
+
+ return old;
+}
+
+static void engine_heartbeat_enable(struct intel_engine_cs *engine,
+ unsigned long saved)
+{
+ intel_engine_pm_put(engine);
+
+ engine->props.heartbeat_interval_ms = saved;
+}
+
+static int perf_request_latency(void *arg)
+{
+ struct drm_i915_private *i915 = arg;
+ struct intel_engine_cs *engine;
+ struct pm_qos_request qos;
+ int err = 0;
+
+ if (INTEL_GEN(i915) < 8) /* per-engine CS timestamp, semaphores */
+ return 0;
+
+ cpu_latency_qos_add_request(&qos, 0); /* disable cstates */
+
+ for_each_uabi_engine(engine, i915) {
+ unsigned long saved_heartbeat;
+ struct intel_context *ce;
+
+ ce = intel_context_create(engine);
+ if (IS_ERR(ce))
+ goto out;
+
+ err = intel_context_pin(ce);
+ if (err) {
+ intel_context_put(ce);
+ goto out;
+ }
+
+ saved_heartbeat = engine_heartbeat_disable(engine);
+ rps_pin(engine->gt);
+
+ if (err == 0)
+ err = measure_semaphore_response(ce);
+ if (err == 0)
+ err = measure_idle_dispatch(ce);
+ if (err == 0)
+ err = measure_busy_dispatch(ce);
+ if (err == 0)
+ err = measure_inter_request(ce);
+ if (err == 0)
+ err = measure_context_switch(ce);
+ if (err == 0)
+ err = measure_completion(ce);
+
+ rps_unpin(engine->gt);
+ engine_heartbeat_enable(engine, saved_heartbeat);
+
+ intel_context_unpin(ce);
+ intel_context_put(ce);
+ if (err)
+ goto out;
+ }
+
+out:
+ if (igt_flush_test(i915))
+ err = -EIO;
+
+ cpu_latency_qos_remove_request(&qos);
+ return err;
+}
+
static int s_sync0(void *arg)
{
struct perf_series *ps = arg;
@@ -2042,6 +2653,7 @@ static int perf_parallel_engines(void *arg)
int i915_request_perf_selftests(struct drm_i915_private *i915)
{
static const struct i915_subtest tests[] = {
+ SUBTEST(perf_request_latency),
SUBTEST(perf_series_engines),
SUBTEST(perf_parallel_engines),
};
--
2.20.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Intel-gfx] [PATCH] drm/i915/selftests: Measure dispatch latency
2020-05-15 15:10 [Intel-gfx] [PATCH] drm/i915/selftests: Measure dispatch latency Chris Wilson
2020-05-15 17:32 ` Chris Wilson
2020-05-15 17:58 ` Chris Wilson
@ 2020-05-15 18:02 ` Chris Wilson
2020-05-15 20:00 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915/selftests: Measure dispatch latency (rev4) Patchwork
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Chris Wilson @ 2020-05-15 18:02 UTC (permalink / raw)
To: intel-gfx; +Cc: Chris Wilson
A useful metric of the system's health is how fast we can tell the GPU
to do various actions, so measure our latency.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
drivers/gpu/drm/i915/selftests/i915_request.c | 612 ++++++++++++++++++
1 file changed, 612 insertions(+)
diff --git a/drivers/gpu/drm/i915/selftests/i915_request.c b/drivers/gpu/drm/i915/selftests/i915_request.c
index 6014e8dfcbb1..bfb601214c4a 100644
--- a/drivers/gpu/drm/i915/selftests/i915_request.c
+++ b/drivers/gpu/drm/i915/selftests/i915_request.c
@@ -24,16 +24,20 @@
#include <linux/prime_numbers.h>
#include <linux/pm_qos.h>
+#include <linux/sort.h>
#include "gem/i915_gem_pm.h"
#include "gem/selftests/mock_context.h"
+#include "gt/intel_engine_heartbeat.h"
#include "gt/intel_engine_pm.h"
#include "gt/intel_engine_user.h"
#include "gt/intel_gt.h"
+#include "gt/intel_gt_requests.h"
#include "i915_random.h"
#include "i915_selftest.h"
+#include "igt_flush_test.h"
#include "igt_live_test.h"
#include "igt_spinner.h"
#include "lib_sw_fence.h"
@@ -1524,6 +1528,613 @@ struct perf_series {
struct intel_context *ce[];
};
+#define COUNT 5
+
+static int cmp_u32(const void *A, const void *B)
+{
+ const u32 *a = A, *b = B;
+
+ return *a - *b;
+}
+
+static u32 trifilter(u32 *a)
+{
+ u64 sum;
+
+ sort(a, COUNT, sizeof(*a), cmp_u32, NULL);
+
+ sum = mul_u32_u32(a[2], 2);
+ sum += a[1];
+ sum += a[3];
+
+ return (sum + 2) >> 2;
+}
+
+static u64 cycles_to_ns(struct intel_engine_cs *engine, u32 cycles)
+{
+ u64 ns = i915_cs_timestamp_ticks_to_ns(engine->i915, cycles);
+
+ return DIV_ROUND_CLOSEST(ns, 1 << COUNT);
+}
+
+static int measure_semaphore_response(struct intel_context *ce)
+{
+ u32 *sema = memset32(ce->engine->status_page.addr + 1000, 0, 21);
+ const u32 offset =
+ i915_ggtt_offset(ce->engine->status_page.vma) +
+ offset_in_page(sema);
+ u32 elapsed[COUNT], cycles;
+ struct i915_request *rq;
+ u32 *cs;
+ int i;
+
+ rq = i915_request_create(ce);
+ if (IS_ERR(rq))
+ return PTR_ERR(rq);
+
+ cs = intel_ring_begin(rq, 4 + 8 * ARRAY_SIZE(elapsed));
+ if (IS_ERR(cs)) {
+ i915_request_add(rq);
+ return PTR_ERR(cs);
+ }
+
+ *cs++ = MI_STORE_DWORD_IMM_GEN4 | MI_USE_GGTT;
+ *cs++ = offset;
+ *cs++ = 0;
+ *cs++ = 0xffffffff;
+
+ for (i = 1; i <= ARRAY_SIZE(elapsed); i++) {
+ *cs++ = MI_SEMAPHORE_WAIT |
+ MI_SEMAPHORE_GLOBAL_GTT |
+ MI_SEMAPHORE_POLL |
+ MI_SEMAPHORE_SAD_EQ_SDD;
+ *cs++ = i;
+ *cs++ = offset;
+ *cs++ = 0;
+
+ *cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
+ *cs++ = ce->engine->mmio_base + 0x358;
+ *cs++ = offset + sizeof(*sema) * i;
+ *cs++ = 0;
+ }
+
+ intel_ring_advance(rq, cs);
+ i915_request_add(rq);
+
+ if (wait_for(READ_ONCE(*sema) == 0xffffffff, 50)) {
+ intel_gt_set_wedged(ce->engine->gt);
+ return -EIO;
+ }
+
+ for (i = 1; i <= ARRAY_SIZE(elapsed); i++) {
+ cycles = ENGINE_READ_FW(ce->engine, RING_TIMESTAMP);
+ WRITE_ONCE(sema[0], i);
+ wmb(); /* flush the update to the cache, and beyond */
+
+ if (wait_for(READ_ONCE(sema[i]), 50)) {
+ intel_gt_set_wedged(ce->engine->gt);
+ return -EIO;
+ }
+
+ elapsed[i - 1] = (sema[i] - cycles) << COUNT;
+ }
+
+ cycles = trifilter(elapsed);
+ pr_info("%s: semaphore response %d cycles, %lluns\n",
+ ce->engine->name, cycles >> COUNT,
+ cycles_to_ns(ce->engine, cycles));
+
+ return intel_gt_wait_for_idle(ce->engine->gt, HZ);
+}
+
+static int measure_idle_dispatch(struct intel_context *ce)
+{
+ u32 *sema = memset32(ce->engine->status_page.addr + 1000, 0, 21);
+ const u32 offset =
+ i915_ggtt_offset(ce->engine->status_page.vma) +
+ offset_in_page(sema);
+ u32 elapsed[COUNT], cycles;
+ u32 *cs;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(elapsed); i++) {
+ struct i915_request *rq;
+ int err;
+
+ err = intel_gt_wait_for_idle(ce->engine->gt, HZ / 2);
+ if (err)
+ return err;
+
+ rq = i915_request_create(ce);
+ if (IS_ERR(rq))
+ return PTR_ERR(rq);
+
+ cs = intel_ring_begin(rq, 4);
+ if (IS_ERR(cs)) {
+ i915_request_add(rq);
+ return PTR_ERR(cs);
+ }
+
+ *cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
+ *cs++ = ce->engine->mmio_base + 0x358;
+ *cs++ = offset + sizeof(*sema) * i;
+ *cs++ = 0;
+
+ intel_ring_advance(rq, cs);
+
+ preempt_disable();
+ local_bh_disable();
+ elapsed[i] = ENGINE_READ_FW(ce->engine, RING_TIMESTAMP);
+ i915_request_add(rq);
+ local_bh_enable();
+ preempt_enable();
+ }
+
+ for (i = 0; i < ARRAY_SIZE(elapsed); i++) {
+ if (wait_for(READ_ONCE(sema[i]), 50)) {
+ intel_gt_set_wedged(ce->engine->gt);
+ return -EIO;
+ }
+
+ elapsed[i] = (sema[i] - elapsed[i]) << COUNT;
+ }
+
+ cycles = trifilter(elapsed);
+ pr_info("%s: idle dispatch latency %d cycles, %lluns\n",
+ ce->engine->name, cycles >> COUNT,
+ cycles_to_ns(ce->engine, cycles));
+
+ return intel_gt_wait_for_idle(ce->engine->gt, HZ);
+}
+
+static int measure_busy_dispatch(struct intel_context *ce)
+{
+ u32 *sema = memset32(ce->engine->status_page.addr + 1000, 0, 21);
+ const u32 offset =
+ i915_ggtt_offset(ce->engine->status_page.vma) +
+ offset_in_page(sema);
+ u32 elapsed[COUNT + 1], cycles;
+ u32 *cs;
+ int i;
+
+ for (i = 1; i <= ARRAY_SIZE(elapsed); i++) {
+ struct i915_request *rq;
+
+ rq = i915_request_create(ce);
+ if (IS_ERR(rq))
+ return PTR_ERR(rq);
+
+ cs = intel_ring_begin(rq, 12);
+ if (IS_ERR(cs)) {
+ i915_request_add(rq);
+ return PTR_ERR(cs);
+ }
+
+ *cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
+ *cs++ = ce->engine->mmio_base + 0x358;
+ *cs++ = offset + sizeof(*sema) * i;
+ *cs++ = 0;
+
+ *cs++ = MI_SEMAPHORE_WAIT |
+ MI_SEMAPHORE_GLOBAL_GTT |
+ MI_SEMAPHORE_POLL |
+ MI_SEMAPHORE_SAD_GTE_SDD;
+ *cs++ = i;
+ *cs++ = offset;
+ *cs++ = 0;
+
+ *cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
+ *cs++ = ce->engine->mmio_base + 0x358;
+ *cs++ = offset + sizeof(*sema) * i;
+ *cs++ = 0;
+
+ intel_ring_advance(rq, cs);
+
+ if (i > 1 && wait_for(READ_ONCE(sema[i - 1]), 500)) {
+ intel_gt_set_wedged(ce->engine->gt);
+ return -EIO;
+ }
+
+ preempt_disable();
+ local_bh_disable();
+ elapsed[i - 1] = ENGINE_READ_FW(ce->engine, RING_TIMESTAMP);
+ i915_request_add(rq);
+ local_bh_enable();
+ WRITE_ONCE(sema[0], i - 1);
+ wmb(); /* flush the update to the cache, and beyond */
+ preempt_enable();
+ }
+ WRITE_ONCE(sema[0], i - 1);
+
+ for (i = 1; i <= COUNT; i++)
+ elapsed[i - 1] = (sema[i] - elapsed[i]) << COUNT;
+
+ cycles = trifilter(elapsed);
+ pr_info("%s: busy dispatch latency %d cycles, %lluns\n",
+ ce->engine->name, cycles >> COUNT,
+ cycles_to_ns(ce->engine, cycles));
+
+ return intel_gt_wait_for_idle(ce->engine->gt, HZ);
+}
+
+static int plug(struct intel_engine_cs *engine, u32 *sema, u32 mode, int value)
+{
+ const u32 offset =
+ i915_ggtt_offset(engine->status_page.vma) +
+ offset_in_page(sema);
+ struct i915_request *rq;
+ u32 *cs;
+
+ rq = i915_request_create(engine->kernel_context);
+ if (IS_ERR(rq))
+ return PTR_ERR(rq);
+
+ cs = intel_ring_begin(rq, 4);
+ if (IS_ERR(cs)) {
+ i915_request_add(rq);
+ return PTR_ERR(cs);
+ }
+
+ *cs++ = MI_SEMAPHORE_WAIT |
+ MI_SEMAPHORE_GLOBAL_GTT |
+ MI_SEMAPHORE_POLL |
+ mode;
+ *cs++ = value;
+ *cs++ = offset;
+ *cs++ = 0;
+
+ intel_ring_advance(rq, cs);
+ i915_request_add(rq);
+
+ return 0;
+}
+
+static int measure_inter_request(struct intel_context *ce)
+{
+ u32 *sema = memset32(ce->engine->status_page.addr + 1000, 0, 21);
+ const u32 offset =
+ i915_ggtt_offset(ce->engine->status_page.vma) +
+ offset_in_page(sema);
+ u32 elapsed[COUNT + 1], cycles;
+ struct i915_sw_fence *submit;
+ int i, err;
+
+ err = plug(ce->engine, sema, MI_SEMAPHORE_SAD_NEQ_SDD, 0);
+ if (err)
+ return err;
+
+ submit = heap_fence_create(GFP_KERNEL);
+ if (!submit) {
+ WRITE_ONCE(sema[0], 1);
+ return -ENOMEM;
+ }
+
+ intel_engine_flush_submission(ce->engine);
+ for (i = 1; i <= ARRAY_SIZE(elapsed); i++) {
+ struct i915_request *rq;
+ u32 *cs;
+
+ rq = i915_request_create(ce);
+ if (IS_ERR(rq)) {
+ WRITE_ONCE(sema[0], 1);
+ return PTR_ERR(rq);
+ }
+
+ err = i915_sw_fence_await_sw_fence_gfp(&rq->submit,
+ submit,
+ GFP_KERNEL);
+ if (err < 0) {
+ i915_sw_fence_commit(submit);
+ heap_fence_put(submit);
+ i915_request_add(rq);
+ WRITE_ONCE(sema[0], 1);
+ return err;
+ }
+
+ cs = intel_ring_begin(rq, 4);
+ if (IS_ERR(cs)) {
+ i915_sw_fence_commit(submit);
+ heap_fence_put(submit);
+ i915_request_add(rq);
+ WRITE_ONCE(sema[0], 1);
+ return PTR_ERR(cs);
+ }
+
+ *cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
+ *cs++ = ce->engine->mmio_base + 0x358;
+ *cs++ = offset + sizeof(*sema) * i;
+ *cs++ = 0;
+
+ intel_ring_advance(rq, cs);
+ i915_request_add(rq);
+ }
+ local_bh_disable();
+ i915_sw_fence_commit(submit);
+ local_bh_enable();
+ intel_engine_flush_submission(ce->engine);
+ heap_fence_put(submit);
+
+ WRITE_ONCE(sema[0], 1);
+ wmb(); /* flush the update to the cache, and beyond */
+
+ if (wait_for(READ_ONCE(sema[COUNT + 1]), 100)) {
+ intel_gt_set_wedged(ce->engine->gt);
+ return -EIO;
+ }
+
+ for (i = 1; i <= COUNT; i++)
+ elapsed[i - 1] = (sema[i + 1] - sema[i]) << COUNT;
+
+ cycles = trifilter(elapsed);
+ pr_info("%s: inter-request latency %d cycles, %lluns\n",
+ ce->engine->name, cycles >> COUNT,
+ cycles_to_ns(ce->engine, cycles));
+
+ return intel_gt_wait_for_idle(ce->engine->gt, HZ);
+}
+
+static int measure_context_switch(struct intel_context *ce)
+{
+ u32 *sema = memset32(ce->engine->status_page.addr + 1000, 0, 21);
+ const u32 offset =
+ i915_ggtt_offset(ce->engine->status_page.vma) +
+ offset_in_page(sema);
+ struct i915_request *fence = NULL;
+ u32 elapsed[COUNT + 1], cycles;
+ int i, j, err;
+ u32 *cs;
+
+ err = plug(ce->engine, sema, MI_SEMAPHORE_SAD_NEQ_SDD, 0);
+ if (err)
+ return err;
+
+ for (i = 1; i <= ARRAY_SIZE(elapsed); i++) {
+ struct intel_context *arr[] = {
+ ce, ce->engine->kernel_context
+ };
+
+ for (j = 0; j < ARRAY_SIZE(arr); j++) {
+ struct i915_request *rq;
+
+ rq = i915_request_create(arr[j]);
+ if (IS_ERR(rq))
+ return PTR_ERR(rq);
+
+ if (fence) {
+ err = i915_request_await_dma_fence(rq,
+ &fence->fence);
+ if (err) {
+ i915_request_add(rq);
+ return err;
+ }
+ }
+
+ cs = intel_ring_begin(rq, 4);
+ if (IS_ERR(cs)) {
+ i915_request_add(rq);
+ return PTR_ERR(cs);
+ }
+
+ *cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
+ *cs++ = ce->engine->mmio_base + 0x358;
+ *cs++ = offset +
+ sizeof(*sema) * (ARRAY_SIZE(arr) * i + j);
+ *cs++ = 0;
+
+ intel_ring_advance(rq, cs);
+
+ i915_request_put(fence);
+ fence = i915_request_get(rq);
+
+ i915_request_add(rq);
+ }
+ }
+ i915_request_put(fence);
+ intel_engine_flush_submission(ce->engine);
+
+ WRITE_ONCE(sema[0], 1);
+ wmb(); /* flush the update to the cache, and beyond */
+
+ if (wait_for(READ_ONCE(sema[2 *i - 1]), 500)) {
+ intel_gt_set_wedged(ce->engine->gt);
+ return -EIO;
+ }
+
+ for (i = 1; i <= COUNT; i++)
+ elapsed[i - 1] = (sema[2 * i + 2] - sema[2 * i + 1]) << COUNT;
+
+ cycles = trifilter(elapsed);
+ pr_info("%s: context switch latency %d cycles, %lluns\n",
+ ce->engine->name, cycles >> COUNT,
+ cycles_to_ns(ce->engine, cycles));
+
+ return intel_gt_wait_for_idle(ce->engine->gt, HZ);
+}
+
+struct signal_cb {
+ struct dma_fence_cb base;
+ bool seen;
+};
+
+static void signal_cb(struct dma_fence *fence, struct dma_fence_cb *cb)
+{
+ struct signal_cb *s = container_of(cb, typeof(*s), base);
+
+ smp_store_mb(s->seen, true); /* be safe, be strong */
+}
+
+static int measure_completion(struct intel_context *ce)
+{
+ u32 *sema = memset32(ce->engine->status_page.addr + 1000, 0, 21);
+ const u32 offset =
+ i915_ggtt_offset(ce->engine->status_page.vma) +
+ offset_in_page(sema);
+ u32 elapsed[COUNT], cycles;
+ u32 *cs;
+ int i;
+
+ for (i = 1; i <= ARRAY_SIZE(elapsed); i++) {
+ struct signal_cb cb = { .seen = false };
+ struct i915_request *rq;
+
+ rq = i915_request_create(ce);
+ if (IS_ERR(rq))
+ return PTR_ERR(rq);
+
+ cs = intel_ring_begin(rq, 12);
+ if (IS_ERR(cs)) {
+ i915_request_add(rq);
+ return PTR_ERR(cs);
+ }
+
+ *cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
+ *cs++ = ce->engine->mmio_base + 0x358;
+ *cs++ = offset + sizeof(*sema) * i;
+ *cs++ = 0;
+
+ *cs++ = MI_SEMAPHORE_WAIT |
+ MI_SEMAPHORE_GLOBAL_GTT |
+ MI_SEMAPHORE_POLL |
+ MI_SEMAPHORE_SAD_EQ_SDD;
+ *cs++ = i;
+ *cs++ = offset;
+ *cs++ = 0;
+
+ *cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
+ *cs++ = ce->engine->mmio_base + 0x358;
+ *cs++ = offset + sizeof(*sema) * i;
+ *cs++ = 0;
+
+ intel_ring_advance(rq, cs);
+
+ dma_fence_add_callback(&rq->fence, &cb.base, signal_cb);
+
+ local_bh_disable();
+ i915_request_add(rq);
+ local_bh_enable();
+
+ if (wait_for(READ_ONCE(sema[i]), 50)) {
+ intel_gt_set_wedged(ce->engine->gt);
+ return -EIO;
+ }
+
+ preempt_disable();
+ WRITE_ONCE(sema[0], i);
+ wmb();
+ while (!READ_ONCE(cb.seen))
+ cpu_relax();
+
+ elapsed[i - 1] = ENGINE_READ_FW(ce->engine, RING_TIMESTAMP);
+ preempt_enable();
+ }
+
+ for (i = 0; i < ARRAY_SIZE(elapsed); i++)
+ elapsed[i] = (elapsed[i] - sema[i + 1]) << COUNT;
+
+ cycles = trifilter(elapsed);
+ pr_info("%s: completion latency %d cycles, %lluns\n",
+ ce->engine->name, cycles >> COUNT,
+ cycles_to_ns(ce->engine, cycles));
+
+ return intel_gt_wait_for_idle(ce->engine->gt, HZ);
+}
+
+static void rps_pin(struct intel_gt *gt)
+{
+ /* Pin the frequency to max */
+ atomic_inc(>->rps.num_waiters);
+ intel_uncore_forcewake_get(gt->uncore, FORCEWAKE_ALL);
+
+ mutex_lock(>->rps.lock);
+ intel_rps_set(>->rps, gt->rps.max_freq);
+ mutex_unlock(>->rps.lock);
+}
+
+static void rps_unpin(struct intel_gt *gt)
+{
+ intel_uncore_forcewake_put(gt->uncore, FORCEWAKE_ALL);
+ atomic_dec(>->rps.num_waiters);
+}
+
+static unsigned long engine_heartbeat_disable(struct intel_engine_cs *engine)
+{
+ unsigned long old;
+
+ old = fetch_and_zero(&engine->props.heartbeat_interval_ms);
+
+ intel_engine_pm_get(engine);
+ intel_engine_park_heartbeat(engine);
+
+ return old;
+}
+
+static void engine_heartbeat_enable(struct intel_engine_cs *engine,
+ unsigned long saved)
+{
+ intel_engine_pm_put(engine);
+
+ engine->props.heartbeat_interval_ms = saved;
+}
+
+static int perf_request_latency(void *arg)
+{
+ struct drm_i915_private *i915 = arg;
+ struct intel_engine_cs *engine;
+ struct pm_qos_request qos;
+ int err = 0;
+
+ if (INTEL_GEN(i915) < 8) /* per-engine CS timestamp, semaphores */
+ return 0;
+
+ cpu_latency_qos_add_request(&qos, 0); /* disable cstates */
+
+ for_each_uabi_engine(engine, i915) {
+ unsigned long saved_heartbeat;
+ struct intel_context *ce;
+
+ ce = intel_context_create(engine);
+ if (IS_ERR(ce))
+ goto out;
+
+ err = intel_context_pin(ce);
+ if (err) {
+ intel_context_put(ce);
+ goto out;
+ }
+
+ saved_heartbeat = engine_heartbeat_disable(engine);
+ rps_pin(engine->gt);
+
+ if (err == 0)
+ err = measure_semaphore_response(ce);
+ if (err == 0)
+ err = measure_idle_dispatch(ce);
+ if (err == 0)
+ err = measure_busy_dispatch(ce);
+ if (err == 0)
+ err = measure_inter_request(ce);
+ if (err == 0)
+ err = measure_context_switch(ce);
+ if (err == 0)
+ err = measure_completion(ce);
+
+ rps_unpin(engine->gt);
+ engine_heartbeat_enable(engine, saved_heartbeat);
+
+ intel_context_unpin(ce);
+ intel_context_put(ce);
+ if (err)
+ goto out;
+ }
+
+out:
+ if (igt_flush_test(i915))
+ err = -EIO;
+
+ cpu_latency_qos_remove_request(&qos);
+ return err;
+}
+
static int s_sync0(void *arg)
{
struct perf_series *ps = arg;
@@ -2042,6 +2653,7 @@ static int perf_parallel_engines(void *arg)
int i915_request_perf_selftests(struct drm_i915_private *i915)
{
static const struct i915_subtest tests[] = {
+ SUBTEST(perf_request_latency),
SUBTEST(perf_series_engines),
SUBTEST(perf_parallel_engines),
};
--
2.20.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915/selftests: Measure dispatch latency (rev4)
2020-05-15 15:10 [Intel-gfx] [PATCH] drm/i915/selftests: Measure dispatch latency Chris Wilson
` (2 preceding siblings ...)
2020-05-15 18:02 ` Chris Wilson
@ 2020-05-15 20:00 ` Patchwork
2020-05-15 20:27 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2020-05-16 1:29 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork
5 siblings, 0 replies; 7+ messages in thread
From: Patchwork @ 2020-05-15 20:00 UTC (permalink / raw)
To: Chris Wilson; +Cc: intel-gfx
== Series Details ==
Series: drm/i915/selftests: Measure dispatch latency (rev4)
URL : https://patchwork.freedesktop.org/series/77308/
State : warning
== Summary ==
$ dim checkpatch origin/drm-tip
8323202f9b72 drm/i915/selftests: Measure dispatch latency
-:448: CHECK:SPACING: spaces preferred around that '*' (ctx:WxV)
#448: FILE: drivers/gpu/drm/i915/selftests/i915_request.c:1938:
+ if (wait_for(READ_ONCE(sema[2 *i - 1]), 500)) {
^
-:533: WARNING:MEMORY_BARRIER: memory barrier without comment
#533: FILE: drivers/gpu/drm/i915/selftests/i915_request.c:2023:
+ wmb();
total: 0 errors, 1 warnings, 1 checks, 640 lines checked
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 7+ messages in thread
* [Intel-gfx] ✓ Fi.CI.BAT: success for drm/i915/selftests: Measure dispatch latency (rev4)
2020-05-15 15:10 [Intel-gfx] [PATCH] drm/i915/selftests: Measure dispatch latency Chris Wilson
` (3 preceding siblings ...)
2020-05-15 20:00 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915/selftests: Measure dispatch latency (rev4) Patchwork
@ 2020-05-15 20:27 ` Patchwork
2020-05-16 1:29 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork
5 siblings, 0 replies; 7+ messages in thread
From: Patchwork @ 2020-05-15 20:27 UTC (permalink / raw)
To: Chris Wilson; +Cc: intel-gfx
== Series Details ==
Series: drm/i915/selftests: Measure dispatch latency (rev4)
URL : https://patchwork.freedesktop.org/series/77308/
State : success
== Summary ==
CI Bug Log - changes from CI_DRM_8489 -> Patchwork_17674
====================================================
Summary
-------
**SUCCESS**
No regressions found.
External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/index.html
Known issues
------------
Here are the changes found in Patchwork_17674 that come from known issues:
### IGT changes ###
#### Issues hit ####
* igt@i915_selftest@live@execlists:
- fi-cml-u2: [PASS][1] -> [INCOMPLETE][2] ([i915#656])
[1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/fi-cml-u2/igt@i915_selftest@live@execlists.html
[2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/fi-cml-u2/igt@i915_selftest@live@execlists.html
#### Possible fixes ####
* igt@i915_selftest@live@execlists:
- fi-skl-lmem: [INCOMPLETE][3] ([i915#656]) -> [PASS][4]
[3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/fi-skl-lmem/igt@i915_selftest@live@execlists.html
[4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/fi-skl-lmem/igt@i915_selftest@live@execlists.html
#### Warnings ####
* igt@i915_pm_rpm@module-reload:
- fi-kbl-x1275: [FAIL][5] ([i915#62]) -> [FAIL][6] ([i915#62] / [i915#95])
[5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/fi-kbl-x1275/igt@i915_pm_rpm@module-reload.html
[6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/fi-kbl-x1275/igt@i915_pm_rpm@module-reload.html
[i915#62]: https://gitlab.freedesktop.org/drm/intel/issues/62
[i915#656]: https://gitlab.freedesktop.org/drm/intel/issues/656
[i915#95]: https://gitlab.freedesktop.org/drm/intel/issues/95
Participating hosts (52 -> 45)
------------------------------
Missing (7): fi-ilk-m540 fi-hsw-4200u fi-byt-squawks fi-bsw-cyan fi-ctg-p8600 fi-byt-clapper fi-bdw-samus
Build changes
-------------
* Linux: CI_DRM_8489 -> Patchwork_17674
CI-20190529: 20190529
CI_DRM_8489: 4a38678eb36587a5fdcccbf0e9e888bf30e8bb3e @ git://anongit.freedesktop.org/gfx-ci/linux
IGT_5655: 2cc4c1edc3065590f9917930b6d049a90c4a38fd @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
Patchwork_17674: 8323202f9b72548e2e5ad19c4519dd8f16bbd7ae @ git://anongit.freedesktop.org/gfx-ci/linux
== Linux commits ==
8323202f9b72 drm/i915/selftests: Measure dispatch latency
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/index.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 7+ messages in thread
* [Intel-gfx] ✓ Fi.CI.IGT: success for drm/i915/selftests: Measure dispatch latency (rev4)
2020-05-15 15:10 [Intel-gfx] [PATCH] drm/i915/selftests: Measure dispatch latency Chris Wilson
` (4 preceding siblings ...)
2020-05-15 20:27 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
@ 2020-05-16 1:29 ` Patchwork
5 siblings, 0 replies; 7+ messages in thread
From: Patchwork @ 2020-05-16 1:29 UTC (permalink / raw)
To: Chris Wilson; +Cc: intel-gfx
== Series Details ==
Series: drm/i915/selftests: Measure dispatch latency (rev4)
URL : https://patchwork.freedesktop.org/series/77308/
State : success
== Summary ==
CI Bug Log - changes from CI_DRM_8489_full -> Patchwork_17674_full
====================================================
Summary
-------
**SUCCESS**
No regressions found.
Known issues
------------
Here are the changes found in Patchwork_17674_full that come from known issues:
### IGT changes ###
#### Issues hit ####
* igt@gem_exec_suspend@basic-s3:
- shard-kbl: [PASS][1] -> [DMESG-WARN][2] ([i915#180])
[1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/shard-kbl3/igt@gem_exec_suspend@basic-s3.html
[2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/shard-kbl6/igt@gem_exec_suspend@basic-s3.html
* igt@kms_cursor_crc@pipe-c-cursor-64x21-random:
- shard-skl: [PASS][3] -> [FAIL][4] ([i915#54])
[3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/shard-skl4/igt@kms_cursor_crc@pipe-c-cursor-64x21-random.html
[4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/shard-skl10/igt@kms_cursor_crc@pipe-c-cursor-64x21-random.html
* igt@kms_cursor_edge_walk@pipe-a-64x64-left-edge:
- shard-apl: [PASS][5] -> [FAIL][6] ([i915#70] / [i915#95])
[5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/shard-apl3/igt@kms_cursor_edge_walk@pipe-a-64x64-left-edge.html
[6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/shard-apl2/igt@kms_cursor_edge_walk@pipe-a-64x64-left-edge.html
* igt@kms_cursor_legacy@all-pipes-torture-bo:
- shard-tglb: [PASS][7] -> [DMESG-WARN][8] ([i915#128])
[7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/shard-tglb1/igt@kms_cursor_legacy@all-pipes-torture-bo.html
[8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/shard-tglb1/igt@kms_cursor_legacy@all-pipes-torture-bo.html
* igt@kms_pipe_crc_basic@nonblocking-crc-pipe-c-frame-sequence:
- shard-skl: [PASS][9] -> [FAIL][10] ([i915#53]) +1 similar issue
[9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/shard-skl6/igt@kms_pipe_crc_basic@nonblocking-crc-pipe-c-frame-sequence.html
[10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/shard-skl6/igt@kms_pipe_crc_basic@nonblocking-crc-pipe-c-frame-sequence.html
* igt@kms_plane@plane-panning-bottom-right-suspend-pipe-b-planes:
- shard-apl: [PASS][11] -> [DMESG-WARN][12] ([i915#180]) +1 similar issue
[11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/shard-apl7/igt@kms_plane@plane-panning-bottom-right-suspend-pipe-b-planes.html
[12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/shard-apl6/igt@kms_plane@plane-panning-bottom-right-suspend-pipe-b-planes.html
* igt@kms_plane_alpha_blend@pipe-c-constant-alpha-min:
- shard-skl: [PASS][13] -> [FAIL][14] ([fdo#108145] / [i915#265])
[13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/shard-skl6/igt@kms_plane_alpha_blend@pipe-c-constant-alpha-min.html
[14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/shard-skl6/igt@kms_plane_alpha_blend@pipe-c-constant-alpha-min.html
* igt@kms_plane_lowres@pipe-a-tiling-x:
- shard-glk: [PASS][15] -> [FAIL][16] ([i915#899])
[15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/shard-glk8/igt@kms_plane_lowres@pipe-a-tiling-x.html
[16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/shard-glk8/igt@kms_plane_lowres@pipe-a-tiling-x.html
* igt@kms_plane_multiple@atomic-pipe-a-tiling-y:
- shard-apl: [PASS][17] -> [FAIL][18] ([i915#1779] / [i915#95])
[17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/shard-apl1/igt@kms_plane_multiple@atomic-pipe-a-tiling-y.html
[18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/shard-apl8/igt@kms_plane_multiple@atomic-pipe-a-tiling-y.html
* igt@kms_psr@psr2_primary_mmap_cpu:
- shard-iclb: [PASS][19] -> [SKIP][20] ([fdo#109441]) +3 similar issues
[19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/shard-iclb2/igt@kms_psr@psr2_primary_mmap_cpu.html
[20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/shard-iclb5/igt@kms_psr@psr2_primary_mmap_cpu.html
#### Possible fixes ####
* igt@kms_color@pipe-a-ctm-green-to-red:
- shard-skl: [FAIL][21] ([i915#129]) -> [PASS][22]
[21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/shard-skl6/igt@kms_color@pipe-a-ctm-green-to-red.html
[22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/shard-skl6/igt@kms_color@pipe-a-ctm-green-to-red.html
* igt@kms_cursor_crc@pipe-b-cursor-64x64-random:
- shard-snb: [SKIP][23] ([fdo#109271]) -> [PASS][24] +1 similar issue
[23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/shard-snb1/igt@kms_cursor_crc@pipe-b-cursor-64x64-random.html
[24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/shard-snb2/igt@kms_cursor_crc@pipe-b-cursor-64x64-random.html
* igt@kms_cursor_legacy@all-pipes-torture-bo:
- shard-snb: [DMESG-WARN][25] ([i915#128]) -> [PASS][26]
[25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/shard-snb5/igt@kms_cursor_legacy@all-pipes-torture-bo.html
[26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/shard-snb2/igt@kms_cursor_legacy@all-pipes-torture-bo.html
* {igt@kms_flip@2x-flip-vs-expired-vblank-interruptible@ac-hdmi-a1-hdmi-a2}:
- shard-glk: [FAIL][27] ([i915#79]) -> [PASS][28]
[27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/shard-glk2/igt@kms_flip@2x-flip-vs-expired-vblank-interruptible@ac-hdmi-a1-hdmi-a2.html
[28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/shard-glk2/igt@kms_flip@2x-flip-vs-expired-vblank-interruptible@ac-hdmi-a1-hdmi-a2.html
* {igt@kms_flip@flip-vs-suspend-interruptible@a-dp1}:
- shard-kbl: [DMESG-WARN][29] ([i915#180]) -> [PASS][30] +8 similar issues
[29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/shard-kbl2/igt@kms_flip@flip-vs-suspend-interruptible@a-dp1.html
[30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/shard-kbl1/igt@kms_flip@flip-vs-suspend-interruptible@a-dp1.html
* {igt@kms_flip@flip-vs-suspend@c-dp1}:
- shard-apl: [DMESG-WARN][31] ([i915#180]) -> [PASS][32]
[31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/shard-apl1/igt@kms_flip@flip-vs-suspend@c-dp1.html
[32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/shard-apl3/igt@kms_flip@flip-vs-suspend@c-dp1.html
* {igt@kms_flip@plain-flip-fb-recreate-interruptible@b-edp1}:
- shard-skl: [FAIL][33] ([i915#1883]) -> [PASS][34]
[33]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/shard-skl1/igt@kms_flip@plain-flip-fb-recreate-interruptible@b-edp1.html
[34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/shard-skl1/igt@kms_flip@plain-flip-fb-recreate-interruptible@b-edp1.html
* igt@kms_hdr@bpc-switch-dpms:
- shard-skl: [FAIL][35] ([i915#1188]) -> [PASS][36]
[35]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/shard-skl7/igt@kms_hdr@bpc-switch-dpms.html
[36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/shard-skl4/igt@kms_hdr@bpc-switch-dpms.html
* igt@kms_plane@plane-panning-bottom-right-suspend-pipe-a-planes:
- shard-skl: [INCOMPLETE][37] ([i915#648] / [i915#69]) -> [PASS][38]
[37]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/shard-skl10/igt@kms_plane@plane-panning-bottom-right-suspend-pipe-a-planes.html
[38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/shard-skl9/igt@kms_plane@plane-panning-bottom-right-suspend-pipe-a-planes.html
* igt@kms_plane@plane-panning-bottom-right-suspend-pipe-c-planes:
- shard-skl: [INCOMPLETE][39] ([i915#69]) -> [PASS][40]
[39]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/shard-skl3/igt@kms_plane@plane-panning-bottom-right-suspend-pipe-c-planes.html
[40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/shard-skl7/igt@kms_plane@plane-panning-bottom-right-suspend-pipe-c-planes.html
* igt@kms_plane_alpha_blend@pipe-c-coverage-7efc:
- shard-skl: [FAIL][41] ([fdo#108145] / [i915#265]) -> [PASS][42]
[41]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/shard-skl9/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html
[42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/shard-skl3/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html
* igt@kms_psr2_su@frontbuffer:
- shard-iclb: [SKIP][43] ([fdo#109642] / [fdo#111068]) -> [PASS][44]
[43]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/shard-iclb8/igt@kms_psr2_su@frontbuffer.html
[44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/shard-iclb2/igt@kms_psr2_su@frontbuffer.html
* igt@kms_psr@psr2_sprite_blt:
- shard-iclb: [SKIP][45] ([fdo#109441]) -> [PASS][46] +1 similar issue
[45]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/shard-iclb5/igt@kms_psr@psr2_sprite_blt.html
[46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/shard-iclb2/igt@kms_psr@psr2_sprite_blt.html
* igt@kms_setmode@basic:
- shard-kbl: [FAIL][47] ([i915#31]) -> [PASS][48]
[47]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/shard-kbl3/igt@kms_setmode@basic.html
[48]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/shard-kbl2/igt@kms_setmode@basic.html
* {igt@perf@blocking-parameterized}:
- shard-iclb: [FAIL][49] ([i915#1542]) -> [PASS][50]
[49]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/shard-iclb1/igt@perf@blocking-parameterized.html
[50]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/shard-iclb5/igt@perf@blocking-parameterized.html
#### Warnings ####
* igt@i915_pm_dc@dc3co-vpb-simulation:
- shard-iclb: [SKIP][51] ([i915#658]) -> [SKIP][52] ([i915#588])
[51]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/shard-iclb5/igt@i915_pm_dc@dc3co-vpb-simulation.html
[52]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/shard-iclb2/igt@i915_pm_dc@dc3co-vpb-simulation.html
* igt@i915_pm_dc@dc6-dpms:
- shard-tglb: [FAIL][53] ([i915#454]) -> [SKIP][54] ([i915#468])
[53]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/shard-tglb8/igt@i915_pm_dc@dc6-dpms.html
[54]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/shard-tglb2/igt@i915_pm_dc@dc6-dpms.html
* igt@i915_pm_dc@dc6-psr:
- shard-tglb: [SKIP][55] ([i915#468]) -> [FAIL][56] ([i915#454])
[55]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/shard-tglb2/igt@i915_pm_dc@dc6-psr.html
[56]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/shard-tglb3/igt@i915_pm_dc@dc6-psr.html
* igt@kms_content_protection@atomic-dpms:
- shard-apl: [TIMEOUT][57] ([i915#1319]) -> [FAIL][58] ([fdo#110321] / [fdo#110336])
[57]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/shard-apl8/igt@kms_content_protection@atomic-dpms.html
[58]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/shard-apl8/igt@kms_content_protection@atomic-dpms.html
* igt@kms_content_protection@lic:
- shard-apl: [FAIL][59] ([fdo#110321]) -> [TIMEOUT][60] ([i915#1319])
[59]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8489/shard-apl1/igt@kms_content_protection@lic.html
[60]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/shard-apl4/igt@kms_content_protection@lic.html
{name}: This element is suppressed. This means it is ignored when computing
the status of the difference (SUCCESS, WARNING, or FAILURE).
[fdo#108145]: https://bugs.freedesktop.org/show_bug.cgi?id=108145
[fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
[fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
[fdo#109642]: https://bugs.freedesktop.org/show_bug.cgi?id=109642
[fdo#110321]: https://bugs.freedesktop.org/show_bug.cgi?id=110321
[fdo#110336]: https://bugs.freedesktop.org/show_bug.cgi?id=110336
[fdo#111068]: https://bugs.freedesktop.org/show_bug.cgi?id=111068
[i915#1188]: https://gitlab.freedesktop.org/drm/intel/issues/1188
[i915#128]: https://gitlab.freedesktop.org/drm/intel/issues/128
[i915#129]: https://gitlab.freedesktop.org/drm/intel/issues/129
[i915#1319]: https://gitlab.freedesktop.org/drm/intel/issues/1319
[i915#1542]: https://gitlab.freedesktop.org/drm/intel/issues/1542
[i915#1779]: https://gitlab.freedesktop.org/drm/intel/issues/1779
[i915#180]: https://gitlab.freedesktop.org/drm/intel/issues/180
[i915#1883]: https://gitlab.freedesktop.org/drm/intel/issues/1883
[i915#265]: https://gitlab.freedesktop.org/drm/intel/issues/265
[i915#31]: https://gitlab.freedesktop.org/drm/intel/issues/31
[i915#454]: https://gitlab.freedesktop.org/drm/intel/issues/454
[i915#468]: https://gitlab.freedesktop.org/drm/intel/issues/468
[i915#53]: https://gitlab.freedesktop.org/drm/intel/issues/53
[i915#54]: https://gitlab.freedesktop.org/drm/intel/issues/54
[i915#588]: https://gitlab.freedesktop.org/drm/intel/issues/588
[i915#648]: https://gitlab.freedesktop.org/drm/intel/issues/648
[i915#658]: https://gitlab.freedesktop.org/drm/intel/issues/658
[i915#69]: https://gitlab.freedesktop.org/drm/intel/issues/69
[i915#70]: https://gitlab.freedesktop.org/drm/intel/issues/70
[i915#79]: https://gitlab.freedesktop.org/drm/intel/issues/79
[i915#899]: https://gitlab.freedesktop.org/drm/intel/issues/899
[i915#95]: https://gitlab.freedesktop.org/drm/intel/issues/95
Participating hosts (11 -> 11)
------------------------------
No changes in participating hosts
Build changes
-------------
* Linux: CI_DRM_8489 -> Patchwork_17674
CI-20190529: 20190529
CI_DRM_8489: 4a38678eb36587a5fdcccbf0e9e888bf30e8bb3e @ git://anongit.freedesktop.org/gfx-ci/linux
IGT_5655: 2cc4c1edc3065590f9917930b6d049a90c4a38fd @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
Patchwork_17674: 8323202f9b72548e2e5ad19c4519dd8f16bbd7ae @ git://anongit.freedesktop.org/gfx-ci/linux
piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17674/index.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2020-05-16 1:29 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-15 15:10 [Intel-gfx] [PATCH] drm/i915/selftests: Measure dispatch latency Chris Wilson
2020-05-15 17:32 ` Chris Wilson
2020-05-15 17:58 ` Chris Wilson
2020-05-15 18:02 ` Chris Wilson
2020-05-15 20:00 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915/selftests: Measure dispatch latency (rev4) Patchwork
2020-05-15 20:27 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2020-05-16 1:29 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).