From patchwork Wed Nov 13 15:49:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Kuoppala X-Patchwork-Id: 11242151 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EEF251390 for ; Wed, 13 Nov 2019 15:49:29 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D77D822B51 for ; Wed, 13 Nov 2019 15:49:29 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D77D822B51 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8E8E36ED74; Wed, 13 Nov 2019 15:49:28 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by gabe.freedesktop.org (Postfix) with ESMTPS id D9D056ED06; Wed, 13 Nov 2019 15:49:26 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 13 Nov 2019 07:49:26 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.68,300,1569308400"; d="scan'208";a="406004481" Received: from rosetta.fi.intel.com ([10.237.72.194]) by fmsmga006.fm.intel.com with ESMTP; 13 Nov 2019 07:49:25 -0800 Received: by rosetta.fi.intel.com (Postfix, from userid 1000) id 704D28402DF; Wed, 13 Nov 2019 17:49:17 +0200 (EET) From: Mika Kuoppala To: intel-gfx@lists.freedesktop.org Date: Wed, 13 Nov 2019 17:49:07 +0200 Message-Id: <20191113154913.8787-1-mika.kuoppala@linux.intel.com> X-Mailer: git-send-email 2.17.1 Subject: [Intel-gfx] [PATCH i-g-t 1/7] lib/igt_dummyload: Send batch as first X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: igt-dev@lists.freedesktop.org MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" To simplify emitting the recursive batch, make batch always the first object on the execbuf list. v2: set handles early, poll_ptr indecency (Chris) v3: allow dep with poll v4: fix gem_exec_schedule v5: rebase v6: rebase v6: gem_ctx_shared v7: conditional close of poll handle Cc: Chris Wilson Signed-off-by: Mika Kuoppala --- lib/igt_dummyload.c | 111 +++++++++++++++++---------------- lib/igt_dummyload.h | 8 ++- tests/i915/gem_exec_balancer.c | 8 +-- tests/i915/gem_spin_batch.c | 13 ++-- 4 files changed, 73 insertions(+), 67 deletions(-) diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c index b9e239db..c079bd04 100644 --- a/lib/igt_dummyload.c +++ b/lib/igt_dummyload.c @@ -63,6 +63,7 @@ #define MI_ARB_CHK (0x5 << 23) static const int BATCH_SIZE = 4096; +static const int POLL_SIZE = 4096; static const int LOOP_START_OFFSET = 64; static IGT_LIST_HEAD(spin_list); @@ -72,16 +73,23 @@ static int emit_recursive_batch(igt_spin_t *spin, int fd, const struct igt_spin_factory *opts) { -#define SCRATCH 0 + #define BATCH IGT_SPIN_BATCH +#define POLL 1 +#define DEP 2 const int gen = intel_gen(intel_get_drm_devid(fd)); - struct drm_i915_gem_relocation_entry relocs[2], *r; + struct drm_i915_gem_exec_object2 * const batch = + &spin->obj[BATCH]; + struct drm_i915_gem_exec_object2 * const poll = + &spin->obj[POLL]; + struct drm_i915_gem_exec_object2 * const dep = + &spin->obj[DEP]; + struct drm_i915_gem_relocation_entry relocs[4], *r; struct drm_i915_gem_execbuffer2 *execbuf; - struct drm_i915_gem_exec_object2 *obj; unsigned int flags[GEM_MAX_ENGINES]; unsigned int nengine; int fence_fd = -1; - uint32_t *cs, *batch; + uint32_t *cs, *batch_start; int i; nengine = 0; @@ -103,64 +111,48 @@ emit_recursive_batch(igt_spin_t *spin, memset(&spin->execbuf, 0, sizeof(spin->execbuf)); execbuf = &spin->execbuf; memset(spin->obj, 0, sizeof(spin->obj)); - obj = spin->obj; memset(relocs, 0, sizeof(relocs)); - obj[BATCH].handle = gem_create(fd, BATCH_SIZE); - batch = __gem_mmap__wc(fd, obj[BATCH].handle, + batch->handle = gem_create(fd, BATCH_SIZE); + spin->handle = batch->handle; + + batch_start = __gem_mmap__wc(fd, batch->handle, 0, BATCH_SIZE, PROT_WRITE); - if (!batch) - batch = gem_mmap__gtt(fd, obj[BATCH].handle, + if (!batch_start) + batch_start = gem_mmap__gtt(fd, batch->handle, BATCH_SIZE, PROT_WRITE); - - gem_set_domain(fd, obj[BATCH].handle, + gem_set_domain(fd, batch->handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT); execbuf->buffer_count++; - cs = batch; - - if (opts->dependency) { - igt_assert(!(opts->flags & IGT_SPIN_POLL_RUN)); - - r = &relocs[obj[BATCH].relocation_count++]; - - /* dummy write to dependency */ - obj[SCRATCH].handle = opts->dependency; - r->presumed_offset = 0; - r->target_handle = obj[SCRATCH].handle; - r->offset = sizeof(uint32_t) * 1020; - r->delta = 0; - r->read_domains = I915_GEM_DOMAIN_RENDER; - r->write_domain = I915_GEM_DOMAIN_RENDER; + cs = batch_start; + poll->handle = gem_create(fd, POLL_SIZE); + spin->poll_handle = poll->handle; execbuf->buffer_count++; - } else if (opts->flags & IGT_SPIN_POLL_RUN) { - r = &relocs[obj[BATCH].relocation_count++]; - igt_assert(!opts->dependency); + if (opts->flags & IGT_SPIN_POLL_RUN) { + r = &relocs[batch->relocation_count++]; if (gen == 4 || gen == 5) { execbuf->flags |= I915_EXEC_SECURE; igt_require(__igt_device_set_master(fd) == 0); } - spin->poll_handle = gem_create(fd, 4096); - obj[SCRATCH].handle = spin->poll_handle; - - if (__gem_set_caching(fd, spin->poll_handle, + if (__gem_set_caching(fd, poll->handle, I915_CACHING_CACHED) == 0) - spin->poll = gem_mmap__cpu(fd, spin->poll_handle, - 0, 4096, + spin->poll = gem_mmap__cpu(fd, poll->handle, + 0, POLL_SIZE, PROT_READ | PROT_WRITE); else - spin->poll = gem_mmap__wc(fd, spin->poll_handle, - 0, 4096, + spin->poll = gem_mmap__wc(fd, poll->handle, + 0, POLL_SIZE, PROT_READ | PROT_WRITE); igt_assert_eq(spin->poll[SPIN_POLL_START_IDX], 0); /* batch is first */ - r->presumed_offset = 4096; - r->target_handle = obj[SCRATCH].handle; + r->presumed_offset = BATCH_SIZE; + r->target_handle = poll->handle; r->offset = sizeof(uint32_t) * 1; r->delta = sizeof(uint32_t) * SPIN_POLL_START_IDX; @@ -179,14 +171,25 @@ emit_recursive_batch(igt_spin_t *spin, } *cs++ = 1; + } + + if (opts->dependency) { + r = &relocs[batch->relocation_count++]; + + /* dummy write to dependency */ + dep->handle = opts->dependency; + r->presumed_offset = BATCH_SIZE + POLL_SIZE; + r->target_handle = dep->handle; + r->offset = sizeof(uint32_t) * 1020; + r->delta = 0; + r->read_domains = I915_GEM_DOMAIN_RENDER; + r->write_domain = I915_GEM_DOMAIN_RENDER; execbuf->buffer_count++; } - spin->handle = obj[BATCH].handle; - - igt_assert_lt(cs - batch, LOOP_START_OFFSET / sizeof(*cs)); - spin->condition = batch + LOOP_START_OFFSET / sizeof(*cs); + igt_assert_lt(cs - batch_start, LOOP_START_OFFSET / sizeof(*cs)); + spin->condition = batch_start + LOOP_START_OFFSET / sizeof(*cs); cs = spin->condition; /* Allow ourselves to be preempted */ @@ -208,9 +211,9 @@ emit_recursive_batch(igt_spin_t *spin, cs += 1000; /* recurse */ - r = &relocs[obj[BATCH].relocation_count++]; - r->target_handle = obj[BATCH].handle; - r->offset = (cs + 1 - batch) * sizeof(*cs); + r = &relocs[batch->relocation_count++]; + r->target_handle = batch->handle; + r->offset = (cs + 1 - batch_start) * sizeof(*cs); r->read_domains = I915_GEM_DOMAIN_COMMAND; r->delta = LOOP_START_OFFSET; if (gen >= 8) { @@ -227,10 +230,10 @@ emit_recursive_batch(igt_spin_t *spin, *cs = r->delta; cs++; } - obj[BATCH].relocs_ptr = to_user_pointer(relocs); + batch->relocs_ptr = to_user_pointer(relocs); - execbuf->buffers_ptr = to_user_pointer(obj + - (2 - execbuf->buffer_count)); + execbuf->buffers_ptr = to_user_pointer(spin->obj); + execbuf->flags |= I915_EXEC_BATCH_FIRST; execbuf->rsvd1 = opts->ctx; if (opts->flags & IGT_SPIN_FENCE_OUT) @@ -264,10 +267,9 @@ emit_recursive_batch(igt_spin_t *spin, } } - igt_assert_lt(cs - batch, BATCH_SIZE / sizeof(*cs)); + igt_assert_lt(cs - batch_start, BATCH_SIZE / sizeof(*cs)); - /* Make it easier for callers to resubmit. */ - for (i = 0; i < ARRAY_SIZE(spin->obj); i++) { + for (i = 0; i < execbuf->buffer_count; i++) { spin->obj[i].relocation_count = 0; spin->obj[i].relocs_ptr = 0; spin->obj[i].flags = EXEC_OBJECT_PINNED; @@ -445,10 +447,11 @@ void igt_spin_free(int fd, igt_spin_t *spin) gem_munmap((void *)((unsigned long)spin->condition & (~4095UL)), BATCH_SIZE); - if (spin->poll) { + if (spin->poll) gem_munmap(spin->poll, 4096); + + if (spin->poll_handle) gem_close(fd, spin->poll_handle); - } if (spin->handle) gem_close(fd, spin->handle); diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h index 421ca183..de5781d7 100644 --- a/lib/igt_dummyload.h +++ b/lib/igt_dummyload.h @@ -34,6 +34,7 @@ typedef struct igt_spin { unsigned int handle; + timer_t timer; struct igt_list_head link; @@ -41,9 +42,12 @@ typedef struct igt_spin { uint32_t cmd_precondition; int out_fence; - struct drm_i915_gem_exec_object2 obj[2]; -#define IGT_SPIN_BATCH 1 + struct drm_i915_gem_exec_object2 obj[3]; +#define IGT_SPIN_BATCH 0 +#define IGT_SPIN_POLL 1 + struct drm_i915_gem_execbuffer2 execbuf; + uint32_t poll_handle; uint32_t *poll; #define SPIN_POLL_START_IDX 0 diff --git a/tests/i915/gem_exec_balancer.c b/tests/i915/gem_exec_balancer.c index 70c4529b..19df406c 100644 --- a/tests/i915/gem_exec_balancer.c +++ b/tests/i915/gem_exec_balancer.c @@ -718,7 +718,7 @@ static uint32_t create_semaphore_to_spinner(int i915, igt_spin_t *spin) cs = map = gem_mmap__cpu(i915, handle, 0, 4096, PROT_WRITE); /* Wait until the spinner is running */ - addr = spin->obj[0].offset + 4 * SPIN_POLL_START_IDX; + addr = spin->obj[IGT_SPIN_POLL].offset + 4 * SPIN_POLL_START_IDX; *cs++ = MI_SEMAPHORE_WAIT | MI_SEMAPHORE_POLL | MI_SEMAPHORE_SAD_NEQ_SDD | @@ -797,9 +797,9 @@ static void bonded_slice(int i915) igt_spin_reset(spin); /* igt_spin_t poll and batch obj must be laid out as we expect */ - igt_assert_eq(IGT_SPIN_BATCH, 1); - obj[0] = spin->obj[0]; - obj[1] = spin->obj[1]; + igt_assert_eq(IGT_SPIN_BATCH, 0); + obj[0] = spin->obj[IGT_SPIN_POLL]; + obj[1] = spin->obj[IGT_SPIN_BATCH]; obj[2].handle = create_semaphore_to_spinner(i915, spin); eb.buffers_ptr = to_user_pointer(obj); diff --git a/tests/i915/gem_spin_batch.c b/tests/i915/gem_spin_batch.c index c67f015f..04707fdc 100644 --- a/tests/i915/gem_spin_batch.c +++ b/tests/i915/gem_spin_batch.c @@ -78,12 +78,9 @@ static void spin_resubmit(int fd, const struct intel_execution_engine2 *e2, gem_context_create(fd) : ctx0; igt_spin_t *spin = __igt_spin_new(fd, .ctx = ctx0, .engine = e2->flags); const struct intel_execution_engine2 *other; + struct drm_i915_gem_execbuffer2 eb = spin->execbuf; - struct drm_i915_gem_execbuffer2 eb = { - .buffer_count = 1, - .buffers_ptr = to_user_pointer(&spin->obj[IGT_SPIN_BATCH]), - .rsvd1 = ctx1, - }; + eb.rsvd1 = ctx1; igt_assert(gem_context_has_engine_map(fd, 0) || !(flags & RESUBMIT_ALL_ENGINES)); @@ -97,11 +94,13 @@ static void spin_resubmit(int fd, const struct intel_execution_engine2 *e2, if (gem_engine_is_equal(other, e2)) continue; - eb.flags = other->flags; + eb.flags &= ~(I915_EXEC_RING_MASK | I915_EXEC_BSD_MASK); + eb.flags |= other->flags; gem_execbuf(fd, &eb); } } else { - eb.flags = e2->flags; + eb.flags &= ~(I915_EXEC_RING_MASK | I915_EXEC_BSD_MASK); + eb.flags |= e2->flags; gem_execbuf(fd, &eb); } From patchwork Wed Nov 13 15:49:08 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Kuoppala X-Patchwork-Id: 11242159 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8F2591390 for ; Wed, 13 Nov 2019 15:49:37 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7765C22CA0 for ; Wed, 13 Nov 2019 15:49:37 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7765C22CA0 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 12CB56ED7B; Wed, 13 Nov 2019 15:49:37 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTPS id 4976D6ED70; Wed, 13 Nov 2019 15:49:28 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 13 Nov 2019 07:49:27 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.68,300,1569308400"; d="scan'208";a="198479716" Received: from rosetta.fi.intel.com ([10.237.72.194]) by orsmga008.jf.intel.com with ESMTP; 13 Nov 2019 07:49:25 -0800 Received: by rosetta.fi.intel.com (Postfix, from userid 1000) id 7268A8402DE; Wed, 13 Nov 2019 17:49:17 +0200 (EET) From: Mika Kuoppala To: intel-gfx@lists.freedesktop.org Date: Wed, 13 Nov 2019 17:49:08 +0200 Message-Id: <20191113154913.8787-2-mika.kuoppala@linux.intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191113154913.8787-1-mika.kuoppala@linux.intel.com> References: <20191113154913.8787-1-mika.kuoppala@linux.intel.com> Subject: [Intel-gfx] [PATCH i-g-t 2/7] igt: Use COND_BBEND for busy spinning on gen9 X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: igt-dev@lists.freedesktop.org, Joonas Lahtinen MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" From: Jon Bloomfield gen9+ introduces a cmdparser for the BLT engine which copies the incoming BB to a kmd owned buffer for submission (to prevent changes being made after the bb has been safely scanned). This breaks the spin functionality because it relies on changing the submitted spin buffers in order to terminate them. Instead, for gen9+, we change the semantics by introducing a COND_BB_END into the infinite loop, to wait until a memory flag (in anothe bo) is cleared. v2: Correct nop length to avoid overwriting bb_end instr when using a dependency bo (cork) v3: fix conflicts on igt_dummyload (Mika) v4: s/bool running/uint32_t running, fix r->delta (Mika) v5: remove overzealous assert (Mika) v6: rebase on top of lib changes (Mika) v7: rework on top of public igt lib changes (Mika) v8: rebase Signed-off-by: Jon Bloomfield (v2) Cc: Joonas Lahtinen Cc: Rodrigo Vivi Cc: Mika Kuoppala Signed-off-by: Mika Kuoppala --- lib/i830_reg.h | 2 +- lib/igt_dummyload.c | 46 +++++++++++++++++++++++-- lib/igt_dummyload.h | 3 ++ lib/intel_reg.h | 3 ++ tests/i915/gem_double_irq_loop.c | 2 -- tests/i915/gem_write_read_ring_switch.c | 2 +- 6 files changed, 52 insertions(+), 6 deletions(-) diff --git a/lib/i830_reg.h b/lib/i830_reg.h index a57691c7..41020256 100644 --- a/lib/i830_reg.h +++ b/lib/i830_reg.h @@ -43,7 +43,7 @@ /* broadwater flush bits */ #define BRW_MI_GLOBAL_SNAPSHOT_RESET (1 << 3) -#define MI_COND_BATCH_BUFFER_END (0x36<<23 | 1) +#define MI_COND_BATCH_BUFFER_END (0x36 << 23) #define MI_DO_COMPARE (1<<21) #define MI_BATCH_BUFFER_END (0xA << 23) diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c index c079bd04..a88c8582 100644 --- a/lib/igt_dummyload.c +++ b/lib/igt_dummyload.c @@ -130,7 +130,15 @@ emit_recursive_batch(igt_spin_t *spin, spin->poll_handle = poll->handle; execbuf->buffer_count++; - if (opts->flags & IGT_SPIN_POLL_RUN) { + /* + * For gen9+ we use a conditional loop rather than an + * infinite loop, because we are unable to modify the + * BB's once they have been scanned by the cmdparser + * We share the poll buffer for the conditional test + * and is always the first buffer in the batch list + */ + + if (gen >= 9 || (opts->flags & IGT_SPIN_POLL_RUN)) { r = &relocs[batch->relocation_count++]; if (gen == 4 || gen == 5) { @@ -150,6 +158,13 @@ emit_recursive_batch(igt_spin_t *spin, igt_assert_eq(spin->poll[SPIN_POLL_START_IDX], 0); + /* + * 2nd word used to control conditional end, and is cleared + * to terminate batch. Must be >=1 to spin + */ + spin->poll[SPIN_POLL_END_IDX] = 1; + __sync_synchronize(); + /* batch is first */ r->presumed_offset = BATCH_SIZE; r->target_handle = poll->handle; @@ -208,7 +223,26 @@ emit_recursive_batch(igt_spin_t *spin, * trouble. See https://bugs.freedesktop.org/show_bug.cgi?id=102262 */ if (!(opts->flags & IGT_SPIN_FAST)) - cs += 1000; + cs += 960; + + igt_assert_eq(spin->using_cond_end, 0); + if (gen >= 9) { + r = &relocs[batch->relocation_count++]; + + /* batch is first, so poll is second */ + r->presumed_offset = BATCH_SIZE; + r->target_handle = poll->handle; + r->offset = (cs + 2 - batch_start) * sizeof(*cs); + r->read_domains = I915_GEM_DOMAIN_COMMAND; + r->delta = SPIN_POLL_END_IDX * sizeof(*cs); + + *cs++ = MI_COND_BATCH_BUFFER_END | 1 << 21 | 2; + *cs++ = 0; /* Reference value */ + *cs++ = r->presumed_offset + r->delta; + *cs++ = 0; + + spin->using_cond_end = 1; + } /* recurse */ r = &relocs[batch->relocation_count++]; @@ -401,6 +435,9 @@ void igt_spin_set_timeout(igt_spin_t *spin, int64_t ns) */ void igt_spin_reset(igt_spin_t *spin) { + if (spin->using_cond_end) + spin->poll[SPIN_POLL_END_IDX] = 1; + if (igt_spin_has_poll(spin)) spin->poll[SPIN_POLL_START_IDX] = 0; @@ -419,7 +456,12 @@ void igt_spin_end(igt_spin_t *spin) if (!spin) return; + if (spin->using_cond_end) { + spin->poll[SPIN_POLL_END_IDX] = 0; + } else { *spin->condition = MI_BATCH_BUFFER_END; + } + __sync_synchronize(); } diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h index de5781d7..e9310b4e 100644 --- a/lib/igt_dummyload.h +++ b/lib/igt_dummyload.h @@ -51,6 +51,9 @@ typedef struct igt_spin { uint32_t poll_handle; uint32_t *poll; #define SPIN_POLL_START_IDX 0 +#define SPIN_POLL_END_IDX 1 + + bool using_cond_end; } igt_spin_t; struct igt_spin_factory { diff --git a/lib/intel_reg.h b/lib/intel_reg.h index 069440cb..10ca760a 100644 --- a/lib/intel_reg.h +++ b/lib/intel_reg.h @@ -2593,6 +2593,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define MI_BATCH_BUFFER ((0x30 << 23) | 1) #define MI_BATCH_BUFFER_START (0x31 << 23) #define MI_BATCH_BUFFER_END (0xA << 23) +#define MI_COND_BATCH_BUFFER_END (0x36 << 23) +#define MI_DO_COMPARE (1<<21) + #define MI_BATCH_NON_SECURE (1) #define MI_BATCH_NON_SECURE_I965 (1 << 8) #define MI_BATCH_NON_SECURE_HSW (1<<13) /* Additional bit for RCS */ diff --git a/tests/i915/gem_double_irq_loop.c b/tests/i915/gem_double_irq_loop.c index b326fc58..f17f61c1 100644 --- a/tests/i915/gem_double_irq_loop.c +++ b/tests/i915/gem_double_irq_loop.c @@ -52,8 +52,6 @@ static drm_intel_bo *target_buffer, *blt_bo; IGT_TEST_DESCRIPTION("Basic check for missed IRQs on blt ring."); -#define MI_COND_BATCH_BUFFER_END (0x36<<23 | 1) -#define MI_DO_COMPARE (1<<21) static void dummy_reloc_loop(void) { diff --git a/tests/i915/gem_write_read_ring_switch.c b/tests/i915/gem_write_read_ring_switch.c index ef229cc5..095c13c3 100644 --- a/tests/i915/gem_write_read_ring_switch.c +++ b/tests/i915/gem_write_read_ring_switch.c @@ -115,7 +115,7 @@ static void run_test(int ring) * otherwise the obj->last_write_seqno will be updated. */ if (ring == I915_EXEC_RENDER) { BEGIN_BATCH(4, 1); - OUT_BATCH(MI_COND_BATCH_BUFFER_END | MI_DO_COMPARE); + OUT_BATCH(MI_COND_BATCH_BUFFER_END | MI_DO_COMPARE | 1); OUT_BATCH(0xffffffff); /* compare dword */ OUT_RELOC(target_bo, I915_GEM_DOMAIN_RENDER, 0, 0); OUT_BATCH(MI_NOOP); From patchwork Wed Nov 13 15:49:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Kuoppala X-Patchwork-Id: 11242149 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 98CE81709 for ; Wed, 13 Nov 2019 15:49:29 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8130622B51 for ; Wed, 13 Nov 2019 15:49:29 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8130622B51 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8499C6ED72; Wed, 13 Nov 2019 15:49:28 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTPS id 41BE16ED06; Wed, 13 Nov 2019 15:49:27 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 13 Nov 2019 07:49:26 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.68,300,1569308400"; d="scan'208";a="355505565" Received: from rosetta.fi.intel.com ([10.237.72.194]) by orsmga004.jf.intel.com with ESMTP; 13 Nov 2019 07:49:25 -0800 Received: by rosetta.fi.intel.com (Postfix, from userid 1000) id 747CA8402E2; Wed, 13 Nov 2019 17:49:17 +0200 (EET) From: Mika Kuoppala To: intel-gfx@lists.freedesktop.org Date: Wed, 13 Nov 2019 17:49:09 +0200 Message-Id: <20191113154913.8787-3-mika.kuoppala@linux.intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191113154913.8787-1-mika.kuoppala@linux.intel.com> References: <20191113154913.8787-1-mika.kuoppala@linux.intel.com> Subject: [Intel-gfx] [PATCH i-g-t 3/7] lib/i915: Add query to detect if engine accepts only ro batches X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: igt-dev@lists.freedesktop.org, Kuoppala@rosetta.fi.intel.com MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" From: "Kuoppala, Mika" If cmd parser is mandatory, batch can't be modified post execbuf. Some tests rely on modifying batch post execbuf. Give those tests a method to query if those modifications ever reach the actual engine command stream. v2: pull in the test changes, doh v3: class based query v4: rebase Signed-off-by: Kuoppala, Mika --- lib/i915/gem_submission.c | 62 ++++++++++++++++++++++++++++++++++ lib/i915/gem_submission.h | 2 ++ tests/i915/gem_busy.c | 7 +++- tests/i915/gem_exec_async.c | 3 ++ tests/i915/gem_exec_await.c | 7 +++- tests/i915/gem_exec_fence.c | 8 +++++ tests/i915/gem_exec_latency.c | 7 ++++ tests/i915/gem_exec_nop.c | 4 ++- tests/i915/gem_exec_schedule.c | 6 +++- tests/i915/gem_exec_whisper.c | 4 ++- tests/prime_busy.c | 3 ++ tests/prime_vgem.c | 6 ++++ 12 files changed, 114 insertions(+), 5 deletions(-) diff --git a/lib/i915/gem_submission.c b/lib/i915/gem_submission.c index 4f946493..9bdf28bc 100644 --- a/lib/i915/gem_submission.c +++ b/lib/i915/gem_submission.c @@ -64,6 +64,22 @@ static bool has_semaphores(int fd, int dir) return val; } +static int cmd_parser_version(int fd) +{ + int val = 0; + struct drm_i915_getparam gp = { + gp.param = I915_PARAM_CMD_PARSER_VERSION, + gp.value = &val, + }; + + if (ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp) < 0) { + val = -errno; + igt_assert(val < 0); + } + + return val; +} + /** * gem_submission_method: * @fd: open i915 drm file descriptor @@ -253,3 +269,49 @@ void gem_require_blitter(int i915) { igt_require(gem_has_blitter(i915)); } + +static bool gem_engine_has_immutable_submission(int i915, int class) +{ + const int gen = intel_gen(intel_get_drm_devid(i915)); + int parser_version; + + parser_version = cmd_parser_version(i915); + + if (parser_version < 0) + return false; + + if (gen == 9 && class == I915_ENGINE_CLASS_COPY && parser_version > 9) + return true; + + return false; +} + + +/** + * gem_class_has_mutable_submission: + * @i915: open i915 drm file descriptor + * @class: engine class + * + * Returns boolean value if the engine class allows batch modifications + * post execbuf. + */ + +bool +gem_class_has_mutable_submission(int fd, int class) +{ + return !gem_engine_has_immutable_submission(fd, class); +} + +/** + * gem_engine_has_mutable_submission: + * @i915: open i915 drm file descriptor + * @engine: the engine (I915_EXEC_RING id) of target + * + * Returns boolean value if the engine allows batch modifications + * post execbuf. + */ +bool gem_engine_has_mutable_submission(int i915, unsigned int engine) +{ + return gem_class_has_mutable_submission(i915, + gem_execbuf_flags_to_engine_class(engine)); +} diff --git a/lib/i915/gem_submission.h b/lib/i915/gem_submission.h index 6deb7e2d..acd24bcb 100644 --- a/lib/i915/gem_submission.h +++ b/lib/i915/gem_submission.h @@ -34,6 +34,8 @@ void gem_submission_print_method(int fd); bool gem_has_semaphores(int fd); bool gem_has_execlists(int fd); bool gem_has_guc_submission(int fd); +bool gem_engine_has_mutable_submission(int fd, unsigned int engine); +bool gem_class_has_mutable_submission(int fd, int class); int gem_cmdparser_version(int i915, uint32_t engine); static inline bool gem_has_cmdparser(int i915, uint32_t engine) diff --git a/tests/i915/gem_busy.c b/tests/i915/gem_busy.c index a8388149..b84e2bd1 100644 --- a/tests/i915/gem_busy.c +++ b/tests/i915/gem_busy.c @@ -243,6 +243,10 @@ static void one(int fd, const struct intel_execution_engine2 *e, unsigned test_f i++; igt_assert(i < size/sizeof(*batch)); + + if ((test_flags & HANG) == 0) + igt_require(gem_class_has_mutable_submission(fd, e->class)); + igt_require(__gem_execbuf(fd, &execbuf) == 0); __gem_busy(fd, obj[SCRATCH].handle, &read[SCRATCH], &write[SCRATCH]); @@ -256,7 +260,8 @@ static void one(int fd, const struct intel_execution_engine2 *e, unsigned test_f e2->instance == e->instance) continue; - if (!gem_class_can_store_dword(fd, e2->class)) + if (!gem_class_can_store_dword(fd, e2->class) || + !gem_class_has_mutable_submission(fd, e2->class)) continue; igt_debug("Testing %s in parallel\n", e2->name); diff --git a/tests/i915/gem_exec_async.c b/tests/i915/gem_exec_async.c index d83e9f6d..b9859ffa 100644 --- a/tests/i915/gem_exec_async.c +++ b/tests/i915/gem_exec_async.c @@ -138,6 +138,9 @@ static void one(int fd, unsigned ring, uint32_t flags) execbuf.buffers_ptr = to_user_pointer(obj); execbuf.buffer_count = 2; execbuf.flags = ring | flags; + + igt_require(gem_engine_has_mutable_submission(fd, ring)); + igt_require(__gem_execbuf(fd, &execbuf) == 0); gem_close(fd, obj[BATCH].handle); diff --git a/tests/i915/gem_exec_await.c b/tests/i915/gem_exec_await.c index 33e2ee45..7817b483 100644 --- a/tests/i915/gem_exec_await.c +++ b/tests/i915/gem_exec_await.c @@ -78,8 +78,13 @@ static void wide(int fd, int ring_size, int timeout, unsigned int flags) double time; nengine = 0; - for_each_physical_engine(e, fd) + for_each_physical_engine(e, fd) { + if (!gem_engine_has_mutable_submission(fd, eb_ring(e))) + continue; + engines[nengine++] = eb_ring(e); + } + igt_require(nengine); exec = calloc(nengine, sizeof(*exec)); diff --git a/tests/i915/gem_exec_fence.c b/tests/i915/gem_exec_fence.c index 002120bf..fbb11ab2 100644 --- a/tests/i915/gem_exec_fence.c +++ b/tests/i915/gem_exec_fence.c @@ -129,6 +129,9 @@ static void test_fence_busy(int fd, unsigned ring, unsigned flags) uint32_t *batch; int fence, i, timeout; + if ((flags & HANG) == 0) + igt_require(gem_engine_has_mutable_submission(fd, ring)); + gem_quiescent_gpu(fd); memset(&execbuf, 0, sizeof(execbuf)); @@ -265,6 +268,8 @@ static void test_fence_busy_all(int fd, unsigned flags) for_each_engine(e, fd) { int fence, new; + if ((flags & HANG) == 0) + igt_require(gem_engine_has_mutable_submission(fd, eb_ring(e))); execbuf.flags = eb_ring(e) | LOCAL_EXEC_FENCE_OUT; execbuf.rsvd2 = -1; gem_execbuf_wr(fd, &execbuf); @@ -321,6 +326,9 @@ static void test_fence_await(int fd, unsigned ring, unsigned flags) uint32_t *out; int i; + if ((flags & HANG) == 0) + igt_require(gem_engine_has_mutable_submission(fd, ring)); + igt_require(gem_can_store_dword(fd, 0)); out = gem_mmap__wc(fd, scratch, 0, 4096, PROT_WRITE); diff --git a/tests/i915/gem_exec_latency.c b/tests/i915/gem_exec_latency.c index 3d99182a..e4c0c862 100644 --- a/tests/i915/gem_exec_latency.c +++ b/tests/i915/gem_exec_latency.c @@ -128,6 +128,8 @@ static void latency_on_ring(int fd, double gpu_latency; int i, j; + igt_require(gem_engine_has_mutable_submission(fd, ring)); + reg = (volatile uint32_t *)((volatile char *)igt_global_mmio + RCS_TIMESTAMP); memset(&execbuf, 0, sizeof(execbuf)); @@ -271,6 +273,8 @@ static void latency_from_ring(int fd, uint32_t ctx[2] = {}; int i, j; + igt_require(gem_engine_has_mutable_submission(fd, ring)); + if (flags & PREEMPT) { ctx[0] = gem_context_create(fd); gem_context_set_priority(fd, ctx[0], -1023); @@ -316,6 +320,9 @@ static void latency_from_ring(int fd, igt_spin_t *spin = NULL; IGT_CORK_HANDLE(c); + if (!gem_engine_has_mutable_submission(fd, eb_ring(e))) + continue; + gem_set_domain(fd, obj[2].handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT); diff --git a/tests/i915/gem_exec_nop.c b/tests/i915/gem_exec_nop.c index 2ad8aeea..dbedb356 100644 --- a/tests/i915/gem_exec_nop.c +++ b/tests/i915/gem_exec_nop.c @@ -123,6 +123,7 @@ static void poll_ring(int fd, unsigned engine, const char *name, int timeout) gem_require_ring(fd, engine); igt_require(gem_can_store_dword(fd, engine)); + igt_require(gem_engine_has_mutable_submission(fd, engine)); memset(&obj, 0, sizeof(obj)); obj.handle = gem_create(fd, 4096); @@ -234,7 +235,8 @@ static void poll_sequential(int fd, const char *name, int timeout) nengine = 0; for_each_physical_engine(e, fd) { - if (!gem_can_store_dword(fd, eb_ring(e))) + if (!gem_can_store_dword(fd, eb_ring(e)) || + !gem_engine_has_mutable_submission(fd, eb_ring(e))) continue; engines[nengine++] = eb_ring(e); diff --git a/tests/i915/gem_exec_schedule.c b/tests/i915/gem_exec_schedule.c index 5c15f177..ca6bef6a 100644 --- a/tests/i915/gem_exec_schedule.c +++ b/tests/i915/gem_exec_schedule.c @@ -652,7 +652,8 @@ static void semaphore_noskip(int i915) igt_spin_t *chain, *spin; if (eb_ring(inner) == eb_ring(outer) || - !gem_can_store_dword(i915, eb_ring(inner))) + !gem_can_store_dword(i915, eb_ring(inner)) || + !gem_engine_has_mutable_submission(i915, eb_ring(inner))) continue; chain = __igt_spin_new(i915, .engine = eb_ring(outer)); @@ -1157,6 +1158,9 @@ static void deep(int fd, unsigned ring) int dep_nreq; int n; + igt_require(gem_can_store_dword(fd, ring)); + igt_require(gem_engine_has_mutable_submission(fd, ring)); + ctx = malloc(sizeof(*ctx) * MAX_CONTEXTS); for (n = 0; n < MAX_CONTEXTS; n++) { ctx[n] = gem_context_create(fd); diff --git a/tests/i915/gem_exec_whisper.c b/tests/i915/gem_exec_whisper.c index a3384760..45cc1437 100644 --- a/tests/i915/gem_exec_whisper.c +++ b/tests/i915/gem_exec_whisper.c @@ -204,13 +204,15 @@ static void whisper(int fd, unsigned engine, unsigned flags) nengine = 0; if (engine == ALL_ENGINES) { for_each_physical_engine(e, fd) { - if (gem_can_store_dword(fd, eb_ring(e))) + if (gem_can_store_dword(fd, eb_ring(e)) && + gem_engine_has_mutable_submission(fd, eb_ring(e))) engines[nengine++] = eb_ring(e); } } else { igt_assert(!(flags & ALL)); igt_require(gem_has_ring(fd, engine)); igt_require(gem_can_store_dword(fd, engine)); + igt_require(gem_engine_has_mutable_submission(fd, engine)); engines[nengine++] = engine; } igt_require(nengine); diff --git a/tests/prime_busy.c b/tests/prime_busy.c index 8ee23bb3..bb29216e 100644 --- a/tests/prime_busy.c +++ b/tests/prime_busy.c @@ -53,6 +53,9 @@ static void busy(int fd, unsigned ring, unsigned flags) uint32_t *batch, *bbe; int i, count, timeout; + if ((flags & HANG) == 0) + igt_require(gem_engine_has_mutable_submission(fd, ring)); + gem_quiescent_gpu(fd); memset(&execbuf, 0, sizeof(execbuf)); diff --git a/tests/prime_vgem.c b/tests/prime_vgem.c index 2b21ff41..04cc913d 100644 --- a/tests/prime_vgem.c +++ b/tests/prime_vgem.c @@ -342,6 +342,8 @@ static void work(int i915, int dmabuf, unsigned ring, uint32_t flags) uint32_t *batch, *bbe; int i, count; + igt_require(gem_engine_has_mutable_submission(i915, ring)); + memset(&execbuf, 0, sizeof(execbuf)); execbuf.buffers_ptr = (uintptr_t)obj; execbuf.buffer_count = 2; @@ -850,6 +852,7 @@ igt_main e->name) { gem_require_ring(i915, eb_ring(e)); igt_require(gem_can_store_dword(i915, eb_ring(e))); + igt_require(gem_engine_has_mutable_submission(i915, eb_ring(e))); gem_quiescent_gpu(i915); test_sync(i915, vgem, e->exec_id, e->flags); @@ -862,6 +865,7 @@ igt_main e->name) { gem_require_ring(i915, eb_ring(e)); igt_require(gem_can_store_dword(i915, eb_ring(e))); + igt_require(gem_engine_has_mutable_submission(i915, eb_ring(e))); gem_quiescent_gpu(i915); test_busy(i915, vgem, e->exec_id, e->flags); @@ -874,6 +878,7 @@ igt_main e->name) { gem_require_ring(i915, eb_ring(e)); igt_require(gem_can_store_dword(i915, eb_ring(e))); + igt_require(gem_engine_has_mutable_submission(i915, eb_ring(e))); gem_quiescent_gpu(i915); test_wait(i915, vgem, e->exec_id, e->flags); @@ -897,6 +902,7 @@ igt_main e->name) { gem_require_ring(i915, eb_ring(e)); igt_require(gem_can_store_dword(i915, eb_ring(e))); + igt_require(gem_engine_has_mutable_submission(i915, eb_ring(e))); gem_quiescent_gpu(i915); test_fence_wait(i915, vgem, e->exec_id, e->flags); From patchwork Wed Nov 13 15:49:10 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Kuoppala X-Patchwork-Id: 11242157 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DA2FC1390 for ; Wed, 13 Nov 2019 15:49:34 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C1D5F22C9F for ; Wed, 13 Nov 2019 15:49:34 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C1D5F22C9F Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 9290B6ED77; Wed, 13 Nov 2019 15:49:32 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by gabe.freedesktop.org (Postfix) with ESMTPS id 045886ED6B; Wed, 13 Nov 2019 15:49:26 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 13 Nov 2019 07:49:26 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.68,300,1569308400"; d="scan'208";a="207489128" Received: from rosetta.fi.intel.com ([10.237.72.194]) by orsmga003.jf.intel.com with ESMTP; 13 Nov 2019 07:49:25 -0800 Received: by rosetta.fi.intel.com (Postfix, from userid 1000) id 76B7E8402E3; Wed, 13 Nov 2019 17:49:17 +0200 (EET) From: Mika Kuoppala To: intel-gfx@lists.freedesktop.org Date: Wed, 13 Nov 2019 17:49:10 +0200 Message-Id: <20191113154913.8787-4-mika.kuoppala@linux.intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191113154913.8787-1-mika.kuoppala@linux.intel.com> References: <20191113154913.8787-1-mika.kuoppala@linux.intel.com> Subject: [Intel-gfx] [PATCH i-g-t 4/7] tests/i915: Skip if secure batches is not available X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: igt-dev@lists.freedesktop.org, Kuoppala@rosetta.fi.intel.com MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" From: "Kuoppala, Mika" If we can't do secure execbuf, there is no point in trying. Signed-off-by: Kuoppala, Mika --- tests/i915/gem_exec_params.c | 16 ++++++++++++++++ tests/i915/gem_mocs_settings.c | 14 ++++++++++++++ tests/perf_pmu.c | 11 +++++++++++ 3 files changed, 41 insertions(+) diff --git a/tests/i915/gem_exec_params.c b/tests/i915/gem_exec_params.c index 8f15e645..c5517b07 100644 --- a/tests/i915/gem_exec_params.c +++ b/tests/i915/gem_exec_params.c @@ -193,6 +193,19 @@ static void test_batch_first(int fd) gem_close(fd, obj[0].handle); } +static int has_secure_batches(const int fd) +{ + int v = -1; + drm_i915_getparam_t gp; + + gp.param = I915_PARAM_HAS_SECURE_BATCHES; + gp.value = &v; + + igt_assert_eq(drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp), 0); + + return v; +} + struct drm_i915_gem_execbuffer2 execbuf; struct drm_i915_gem_exec_object2 gem_exec[1]; uint32_t batch[2] = {MI_BATCH_BUFFER_END}; @@ -340,6 +353,8 @@ igt_main } igt_subtest("secure-non-root") { + igt_require(has_secure_batches(fd)); + igt_fork(child, 1) { igt_drop_root(); @@ -352,6 +367,7 @@ igt_main igt_subtest("secure-non-master") { igt_require(__igt_device_set_master(fd) == 0); /* Requires root privilege */ + igt_require(has_secure_batches(fd)); igt_device_drop_master(fd); execbuf.flags = I915_EXEC_RENDER | I915_EXEC_SECURE; diff --git a/tests/i915/gem_mocs_settings.c b/tests/i915/gem_mocs_settings.c index fc2ccb21..82eb8a3f 100644 --- a/tests/i915/gem_mocs_settings.c +++ b/tests/i915/gem_mocs_settings.c @@ -225,6 +225,19 @@ static uint32_t get_engine_base(int fd, uint32_t engine) } } +static int has_secure_batches(const int fd) +{ + int v = -1; + drm_i915_getparam_t gp; + + gp.param = I915_PARAM_HAS_SECURE_BATCHES; + gp.value = &v; + + igt_assert_eq(drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp), 0); + + return v; +} + #define MI_STORE_REGISTER_MEM_64_BIT_ADDR ((0x24 << 23) | 2) static int create_read_batch(struct drm_i915_gem_relocation_entry *reloc, @@ -566,6 +579,7 @@ igt_main igt_require_gem(fd); gem_require_mocs_registers(fd); igt_require(get_mocs_settings(fd, &table, false)); + igt_require(has_secure_batches(fd)); } for (e = intel_execution_engines; e->name; e++) { diff --git a/tests/perf_pmu.c b/tests/perf_pmu.c index e2bd2cc5..296d04c6 100644 --- a/tests/perf_pmu.c +++ b/tests/perf_pmu.c @@ -893,6 +893,16 @@ static int wait_vblank(int fd, union drm_wait_vblank *vbl) return err; } +static int has_secure_batches(const int fd) +{ + int v = -1; + drm_i915_getparam_t gp; + gp.param = I915_PARAM_HAS_SECURE_BATCHES; + gp.value = &v; + igt_assert_eq(drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp), 0); + return v; +} + static void event_wait(int gem_fd, const struct intel_execution_engine2 *e) { @@ -910,6 +920,7 @@ event_wait(int gem_fd, const struct intel_execution_engine2 *e) devid = intel_get_drm_devid(gem_fd); igt_require(intel_gen(devid) >= 7); + igt_require(has_secure_batches(fd)); igt_skip_on(IS_VALLEYVIEW(devid) || IS_CHERRYVIEW(devid)); kmstest_set_vt_graphics_mode(); From patchwork Wed Nov 13 15:49:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Mika Kuoppala X-Patchwork-Id: 11242153 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 53ACD1709 for ; Wed, 13 Nov 2019 15:49:32 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3B42E22BEF for ; Wed, 13 Nov 2019 15:49:32 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3B42E22BEF Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5F1A56ED71; Wed, 13 Nov 2019 15:49:31 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by gabe.freedesktop.org (Postfix) with ESMTPS id 389346ED06; Wed, 13 Nov 2019 15:49:28 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 13 Nov 2019 07:49:27 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.68,300,1569308400"; d="scan'208";a="216426548" Received: from rosetta.fi.intel.com ([10.237.72.194]) by orsmga002.jf.intel.com with ESMTP; 13 Nov 2019 07:49:25 -0800 Received: by rosetta.fi.intel.com (Postfix, from userid 1000) id 78F648402E6; Wed, 13 Nov 2019 17:49:17 +0200 (EET) From: Mika Kuoppala To: intel-gfx@lists.freedesktop.org Date: Wed, 13 Nov 2019 17:49:11 +0200 Message-Id: <20191113154913.8787-5-mika.kuoppala@linux.intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191113154913.8787-1-mika.kuoppala@linux.intel.com> References: <20191113154913.8787-1-mika.kuoppala@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t 5/7] Add tests/gem_blt_parse X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: igt-dev@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" From: Mika Kuoppala For testing blitter engine command parser on gen9. v2: bad jump offset v3: rebase v4: improve bb start and subcase it v5: fix presumed offsets (Jon) Signed-off-by: Mika Kuoppala --- tests/Makefile.sources | 3 + tests/i915/gem_blt_parse.c | 997 ++++++++++++++++++++++++++ tests/intel-ci/fast-feedback.testlist | 1 + tests/meson.build | 1 + 4 files changed, 1002 insertions(+) create mode 100644 tests/i915/gem_blt_parse.c diff --git a/tests/Makefile.sources b/tests/Makefile.sources index abf1e2fc..75c79edb 100644 --- a/tests/Makefile.sources +++ b/tests/Makefile.sources @@ -244,6 +244,9 @@ gem_exec_params_SOURCES = i915/gem_exec_params.c TESTS_progs += gem_exec_parse gem_exec_parse_SOURCES = i915/gem_exec_parse.c +TESTS_progs += gem_blt_parse +gem_blt_parse_SOURCES = i915/gem_blt_parse.c + TESTS_progs += gem_exec_reloc gem_exec_reloc_SOURCES = i915/gem_exec_reloc.c diff --git a/tests/i915/gem_blt_parse.c b/tests/i915/gem_blt_parse.c new file mode 100644 index 00000000..607afba9 --- /dev/null +++ b/tests/i915/gem_blt_parse.c @@ -0,0 +1,997 @@ +/* + * Copyright © 2018 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + */ + +#include "igt.h" +#include +#include +#include +#include + +#include + +#ifndef I915_PARAM_CMD_PARSER_VERSION +#define I915_PARAM_CMD_PARSER_VERSION 28 +#endif + +#ifndef I915_PARAM_HAS_SECURE_BATCHES +#define I915_PARAM_HAS_SECURE_BATCHES 23 +#endif + +/* To help craft commands known to be invalid across all engines */ +#define INSTR_CLIENT_SHIFT 29 +#define INSTR_INVALID_CLIENT 0x7 + +#define MI_LOAD_REGISTER_REG (0x2a << 23) +#define MI_STORE_REGISTER_MEM (0x24 << 23) +#define MI_ARB_ON_OFF (0x8 << 23) +#define MI_USER_INTERRUPT (0x02 << 23) +#define MI_FLUSH_DW (0x26 << 23) +#define MI_ARB_CHECK (0x05 << 23) +#define MI_REPORT_HEAD (0x07 << 23) +#define MI_SUSPEND_FLUSH (0x0b << 23) +#define MI_LOAD_SCAN_LINES_EXCL (0x13 << 23) +#define MI_UPDATE_GTT (0x23 << 23) + +#define BCS_SWCTRL 0x22200 +#define BCS_GPR_BASE 0x22600 +#define BCS_GPR(n) (0x22600 + (n) * 8) +#define BCS_GPR_UDW(n) (0x22600 + (n) * 8 + 4) + +#define HANDLE_SIZE 4096 + +static int parser_version; + +static int command_parser_version(int fd) +{ + int version = -1; + drm_i915_getparam_t gp; + + gp.param = I915_PARAM_CMD_PARSER_VERSION; + gp.value = &version; + + if (drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp) == 0) + return version; + + return -1; +} + +static int __exec_batch_patched(int fd, int engine, + uint32_t cmd_bo, const uint32_t *cmds, int size, + uint32_t target_bo, uint64_t target_offset, uint64_t target_delta) +{ + struct drm_i915_gem_execbuffer2 execbuf; + struct drm_i915_gem_exec_object2 obj[2]; + struct drm_i915_gem_relocation_entry reloc[1]; + + gem_write(fd, cmd_bo, 0, cmds, size); + + memset(obj, 0, sizeof(obj)); + obj[0].handle = target_bo; + obj[1].handle = cmd_bo; + + memset(reloc, 0, sizeof(reloc)); + reloc[0].offset = target_offset; + reloc[0].target_handle = target_bo; + reloc[0].delta = target_delta; + reloc[0].read_domains = I915_GEM_DOMAIN_COMMAND; + reloc[0].write_domain = I915_GEM_DOMAIN_COMMAND; + reloc[0].presumed_offset = -1; + + obj[1].relocs_ptr = to_user_pointer(reloc); + obj[1].relocation_count = 1; + + memset(&execbuf, 0, sizeof(execbuf)); + execbuf.buffers_ptr = to_user_pointer(obj); + execbuf.buffer_count = 2; + execbuf.batch_len = size; + execbuf.flags = engine; + + return __gem_execbuf(fd, &execbuf); +} + +static void exec_batch_patched(int fd, int engine, + uint32_t cmd_bo, const uint32_t *cmds, + int size, int patch_offset, + long int expected_value) +{ + const uint32_t target_bo = gem_create(fd, HANDLE_SIZE); + uint64_t actual_value = 0; + long int ret; + + ret = __exec_batch_patched(fd, engine, cmd_bo, cmds, size, target_bo, patch_offset, 0); + if (ret) { + igt_assert_lt(ret, 0); + gem_close(fd, target_bo); + igt_assert_eq(ret, expected_value); + return; + } + + gem_sync(fd, cmd_bo); + + gem_read(fd, target_bo, 0, &actual_value, sizeof(actual_value)); + + gem_close(fd, target_bo); + + igt_assert_eq(actual_value, expected_value); +} + +static int __exec_batch(int fd, int engine, uint32_t cmd_bo, + const uint32_t *cmds, int size) +{ + struct drm_i915_gem_execbuffer2 execbuf; + struct drm_i915_gem_exec_object2 obj[1]; + int ret; + + gem_write(fd, cmd_bo, 0, cmds, size); + + memset(obj, 0, sizeof(obj)); + obj[0].handle = cmd_bo; + + memset(&execbuf, 0, sizeof(execbuf)); + execbuf.buffers_ptr = to_user_pointer(obj); + execbuf.buffer_count = 1; + execbuf.batch_len = size; + execbuf.flags = engine; + + ret = __gem_execbuf(fd, &execbuf); + + if (!ret) + gem_sync(fd, cmd_bo); + + return ret; +} + +#if 0 +static void print_batch(const uint32_t *cmds, const uint32_t sz) +{ + const int commands = sz / 4; + int i; + + igt_info("Batch size %d\n", sz); + for (i = 0; i < commands; i++) + igt_info("0x%08x: 0x%08x\n", i, cmds[i]); +} +#else +#define print_batch(cmds, size) +#endif + +#define exec_batch(fd, engine, bo, cmds, sz, expected) \ + print_batch(cmds, sz); \ + igt_assert_eq(__exec_batch(fd, engine, bo, cmds, sz), expected) + +static void exec_split_batch(int fd, int engine, const uint32_t *cmds, + int size, int expected_ret) +{ + struct drm_i915_gem_execbuffer2 execbuf; + struct drm_i915_gem_exec_object2 obj[1]; + uint32_t cmd_bo; + const uint32_t noop[1024] = { 0 }; + const int alloc_size = 4096 * 2; + const int actual_start_offset = 4096-sizeof(uint32_t); + + /* Allocate and fill a 2-page batch with noops */ + cmd_bo = gem_create(fd, alloc_size); + gem_write(fd, cmd_bo, 0, noop, sizeof(noop)); + gem_write(fd, cmd_bo, 4096, noop, sizeof(noop)); + + /* Write the provided commands such that the first dword + * of the command buffer is the last dword of the first + * page (i.e. the command is split across the two pages). + */ + gem_write(fd, cmd_bo, actual_start_offset, cmds, size); + + memset(obj, 0, sizeof(obj)); + obj[0].handle = cmd_bo; + + memset(&execbuf, 0, sizeof(execbuf)); + execbuf.buffers_ptr = to_user_pointer(obj); + execbuf.buffer_count = 1; + /* NB: We want batch_start_offset and batch_len to point to the block + * of the actual commands (i.e. at the last dword of the first page), + * but have to adjust both the start offset and length to meet the + * kernel driver's requirements on the alignment of those fields. + */ + execbuf.batch_start_offset = actual_start_offset & ~0x7; + execbuf.batch_len = + ALIGN(size + actual_start_offset - execbuf.batch_start_offset, + 0x8); + execbuf.flags = engine; + + igt_assert_eq(__gem_execbuf(fd, &execbuf), expected_ret); + + gem_sync(fd, cmd_bo); + gem_close(fd, cmd_bo); +} + +static void exec_batch_chained(int fd, int engine, + uint32_t cmd_bo, const uint32_t *cmds, + int size, int patch_offset, + uint64_t expected_value, + int expected_return) +{ + struct drm_i915_gem_execbuffer2 execbuf; + struct drm_i915_gem_exec_object2 obj[3]; + struct drm_i915_gem_relocation_entry reloc[1]; + struct drm_i915_gem_relocation_entry first_level_reloc; + + const uint32_t target_bo = gem_create(fd, 4096); + const uint32_t first_level_bo = gem_create(fd, 4096); + uint64_t actual_value = 0; + int ret; + + const uint32_t first_level_cmds[] = { + MI_BATCH_BUFFER_START | MI_BATCH_NON_SECURE_I965 | 1, + 0, + 0, + MI_BATCH_BUFFER_END, + }; + + gem_write(fd, first_level_bo, 0, + first_level_cmds, sizeof(first_level_cmds)); + gem_write(fd, cmd_bo, 0, cmds, size); + + memset(obj, 0, sizeof(obj)); + obj[0].handle = target_bo; + obj[1].handle = cmd_bo; + obj[2].handle = first_level_bo; + + memset(reloc, 0, sizeof(reloc)); + reloc[0].offset = patch_offset; + reloc[0].delta = 0; + reloc[0].target_handle = target_bo; + reloc[0].read_domains = I915_GEM_DOMAIN_COMMAND; + reloc[0].write_domain = I915_GEM_DOMAIN_COMMAND; + reloc[0].presumed_offset = -1; + + obj[1].relocation_count = 1; + obj[1].relocs_ptr = to_user_pointer(&reloc); + + memset(&first_level_reloc, 0, sizeof(first_level_reloc)); + first_level_reloc.offset = 4; + first_level_reloc.delta = 0; + first_level_reloc.target_handle = cmd_bo; + first_level_reloc.read_domains = I915_GEM_DOMAIN_COMMAND; + first_level_reloc.write_domain = 0; + obj[2].relocation_count = 1; + obj[2].relocs_ptr = to_user_pointer(&first_level_reloc); + + memset(&execbuf, 0, sizeof(execbuf)); + execbuf.buffers_ptr = to_user_pointer(obj); + execbuf.buffer_count = 3; + execbuf.batch_len = sizeof(first_level_cmds); + execbuf.flags = engine; + + ret = __gem_execbuf(fd, &execbuf); + if (expected_return && ret == expected_return) + goto out; + + gem_sync(fd, cmd_bo); + + gem_read(fd,target_bo, 0, &actual_value, sizeof(actual_value)); + +out: + if (!expected_return) + igt_assert_eq(expected_value, actual_value); + else + igt_assert_neq(expected_value, actual_value); + + gem_close(fd, first_level_bo); + gem_close(fd, target_bo); +} + +static void test_secure_batches(const int fd) +{ + int v = -1; + drm_i915_getparam_t gp; + + gp.param = I915_PARAM_HAS_SECURE_BATCHES; + gp.value = &v; + + igt_assert_eq(drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp), 0); + igt_assert_eq(v, 0); + + igt_assert(!gem_engine_has_mutable_submission(fd, I915_EXEC_BLT)); +} + +struct cmd { + uint32_t cmd; + int len; + const char *name; +}; + +#define CMD(C, L) { .cmd = (C), .len = (L), .name = #C } +#define CMD_N(C) { .cmd = (C), .len = 1, .name = #C } + +static const struct cmd allowed_cmds[] = { + CMD_N(MI_NOOP), + CMD_N(MI_USER_INTERRUPT), + CMD_N(MI_WAIT_FOR_EVENT), + CMD(MI_FLUSH_DW, 5), + CMD_N(MI_ARB_CHECK), + CMD_N(MI_REPORT_HEAD), + CMD_N(MI_FLUSH), + CMD_N(MI_ARB_ON_OFF), + CMD_N(MI_SUSPEND_FLUSH), + CMD(MI_LOAD_SCAN_LINES_INCL, 2), + CMD(MI_LOAD_SCAN_LINES_EXCL, 2), +}; + +static uint32_t *inject_cmd(uint32_t *batch, const uint32_t cmd, int len) +{ + int i = 0; + + batch[i++] = cmd; + + while (--len) + batch[i++] = 0; + + return &batch[i]; +} + +static unsigned long batch_num_cmds(const uint32_t * const batch_start, + const uint32_t * const batch_end) +{ + igt_assert_lte((unsigned long)batch_start, (unsigned long)batch_end); + + return batch_end - batch_start; +} + +static unsigned long batch_bytes(const uint32_t * const batch_start, + const uint32_t * const batch_end) +{ + const unsigned long bytes = batch_num_cmds(batch_start, batch_end) * 4; + + igt_assert(!(bytes & 0x7)); + + return bytes; +} + +static void test_allowed_all(const int fd, const uint32_t handle) +{ + uint32_t batch[4096]; + uint32_t *b = &batch[0]; + + for (int i = 0; i < ARRAY_SIZE(allowed_cmds); i++) + b = inject_cmd(b, allowed_cmds[i].cmd, + allowed_cmds[i].len); + + if (!(batch_num_cmds(batch, b) % 2)) + b = inject_cmd(b, MI_NOOP, 1); + + b = inject_cmd(b, MI_BATCH_BUFFER_END, 1); + + exec_batch(fd, I915_EXEC_BLT, handle, batch, batch_bytes(batch, b), 0); +} + +static void test_allowed_single(const int fd, const uint32_t handle) +{ + uint32_t batch[4096]; + int ret; + + for (int i = 0; i < ARRAY_SIZE(allowed_cmds); i++) { + uint32_t *b = &batch[0]; + + b = inject_cmd(b, allowed_cmds[i].cmd, + allowed_cmds[i].len); + + if (!(batch_num_cmds(batch, b) % 2)) + b = inject_cmd(b, MI_NOOP, 1); + + b = inject_cmd(b, MI_BATCH_BUFFER_END, 1); + + ret = __exec_batch(fd, I915_EXEC_BLT, handle, + batch, batch_bytes(batch, b)); + + igt_assert_eq(ret, 0); + }; +} + +static void test_bb_secure(const int fd, const uint32_t handle) +{ + struct drm_i915_gem_execbuffer2 execbuf; + struct drm_i915_gem_exec_object2 obj[1]; + struct drm_i915_gem_relocation_entry reloc[1]; + int ret; + + const uint32_t batch_secure[] = { + MI_BATCH_BUFFER_START | 1, + 12, + 0, + MI_NOOP, + MI_NOOP, + MI_BATCH_BUFFER_END, + }; + + gem_write(fd, handle, 0, batch_secure, sizeof(batch_secure)); + + memset(obj, 0, sizeof(obj)); + obj[0].handle = handle; + + memset(reloc, 0, sizeof(reloc)); + reloc[0].offset = 1 * sizeof(uint32_t); + reloc[0].target_handle = handle; + reloc[0].delta = 4 * sizeof(uint32_t); + reloc[0].read_domains = I915_GEM_DOMAIN_COMMAND; + reloc[0].write_domain = 0; + reloc[0].presumed_offset = -1; + + obj[0].relocs_ptr = to_user_pointer(reloc); + obj[0].relocation_count = 1; + + memset(&execbuf, 0, sizeof(execbuf)); + execbuf.buffers_ptr = to_user_pointer(obj); + execbuf.buffer_count = 1; + execbuf.batch_len = sizeof(batch_secure); + execbuf.flags = I915_EXEC_BLT; + + ret = __gem_execbuf(fd, &execbuf); + + igt_assert_eq(ret, -EACCES); +} + +#define BB_START_PARAM 0 +#define BB_START_OUT 1 +#define BB_START_CMD 2 + +static void test_bb_start(const int fd, const uint32_t handle, int test) +{ + struct drm_i915_gem_execbuffer2 execbuf; + struct drm_i915_gem_exec_object2 obj[2]; + struct drm_i915_gem_relocation_entry reloc[3]; + const uint32_t target_bo = gem_create(fd, 4096); + uint32_t *dst; + int ret; + unsigned int jump_off; + + const uint32_t batch[] = { + MI_NOOP, + MI_NOOP, + MI_NOOP, + MI_NOOP, + MI_STORE_DWORD_IMM, + 0, + 0, + 1, + MI_STORE_DWORD_IMM, + 4, + 0, + 2, + MI_COND_BATCH_BUFFER_END | 1, + 0, + 0, + 0, + MI_BATCH_BUFFER_START | MI_BATCH_NON_SECURE_I965 | 1, + 0, + 0, + MI_BATCH_BUFFER_END, + }; + + igt_require(gem_can_store_dword(fd, I915_EXEC_BLT)); + + switch (test) { + case BB_START_PARAM: + jump_off = 5 * sizeof(uint32_t); + break; + case BB_START_CMD: + jump_off = 8 * sizeof(uint32_t); + break; + default: + jump_off = 0xf00d0000; + } + + gem_write(fd, handle, 0, batch, sizeof(batch)); + + memset(obj, 0, sizeof(obj)); + obj[0].handle = target_bo; + obj[1].handle = handle; + + memset(reloc, 0, sizeof(reloc)); + reloc[0].offset = 5 * sizeof(uint32_t); + reloc[0].target_handle = obj[0].handle; + reloc[0].delta = 0; + reloc[0].read_domains = I915_GEM_DOMAIN_COMMAND; + reloc[0].write_domain = I915_GEM_DOMAIN_COMMAND; + reloc[0].presumed_offset = -1; + + reloc[1].offset = 9 * sizeof(uint32_t); + reloc[1].target_handle = obj[0].handle; + reloc[1].delta = 1 * sizeof(uint32_t); + reloc[1].read_domains = I915_GEM_DOMAIN_COMMAND; + reloc[1].write_domain = I915_GEM_DOMAIN_COMMAND; + reloc[1].presumed_offset = -1; + + reloc[2].offset = 17 * sizeof(uint32_t); + reloc[2].target_handle = obj[1].handle; + reloc[2].delta = jump_off; + reloc[2].read_domains = I915_GEM_DOMAIN_COMMAND; + reloc[2].write_domain = 0; + reloc[2].presumed_offset = -1; + + obj[1].relocs_ptr = to_user_pointer(reloc); + obj[1].relocation_count = 3; + + memset(&execbuf, 0, sizeof(execbuf)); + execbuf.buffers_ptr = to_user_pointer(obj); + execbuf.buffer_count = 2; + execbuf.batch_len = sizeof(batch); + execbuf.flags = I915_EXEC_BLT; + + dst = gem_mmap__cpu(fd, obj[0].handle, 0, 4096, + PROT_READ | PROT_WRITE); + + igt_assert_eq(dst[0], 0); + igt_assert_eq(dst[1], 0); + + ret = __gem_execbuf(fd, &execbuf); + + switch (test) { + case BB_START_PARAM: + igt_assert_eq(ret, -EINVAL); + break; + case BB_START_CMD: + igt_assert_eq(ret, 0); + + while (READ_ONCE(dst[0]) == 0) + ; + + while (READ_ONCE(dst[1]) == 0) + ; + + igt_assert_eq(dst[0], 1); + igt_assert_eq(dst[1], 2); + + igt_info("values now %x %x\n", dst[0], dst[1]); + + dst[0] = 0; + + igt_info("values now %x %x\n", dst[0], dst[1]); + + gem_sync(fd, handle); + + igt_info("values now %x %x\n", dst[0], dst[1]); + + igt_assert_eq(dst[0], 0); + igt_assert_eq(dst[1], 2); + + break; + + case BB_START_OUT: + igt_assert_eq(ret, -EINVAL); + break; + } + + gem_sync(fd, handle); + gem_munmap(dst, 4096); + gem_close(fd, target_bo); +} + +static void test_bb_chained(const int fd, const uint32_t handle) +{ + const uint32_t batch[] = { + (0x20 << 23) | 2, /* MI_STORE_DATA_IMM */ + 0, + 0, + 0xbaadf00d, + MI_NOOP, + MI_BATCH_BUFFER_END, + }; + + exec_batch_chained(fd, I915_EXEC_RENDER, + handle, + batch, sizeof(batch), + 4, + 0xbaadf00d, + 0); + + exec_batch_chained(fd, I915_EXEC_BLT, + handle, + batch, sizeof(batch), + 4, + 0xbaadf00d, + EPERM); +} + +static void test_cmd_crossing_page(const int fd, const uint32_t handle) +{ + const uint32_t lri_ok[] = { + MI_LOAD_REGISTER_IMM, + BCS_GPR(0), + 0xbaadf00d, + MI_BATCH_BUFFER_END, + }; + const uint32_t store_reg[] = { + MI_STORE_REGISTER_MEM | (4 - 2), + BCS_GPR(0), + 0, /* reloc */ + 0, /* reloc */ + MI_NOOP, + MI_BATCH_BUFFER_END, + }; + + exec_split_batch(fd, I915_EXEC_BLT, + lri_ok, sizeof(lri_ok), + 0); + + exec_batch_patched(fd, I915_EXEC_BLT, handle, + store_reg, sizeof(store_reg), + 2 * sizeof(uint32_t), /* reloc */ + 0xbaadf00d); +} + +static void test_invalid_length(const int fd, const uint32_t handle) +{ + const uint32_t ok_val = 0xbaadf00d; + const uint32_t bad_val = 0xf00dbaad; + const uint32_t noops[8192] = { 0, }; + + const uint32_t lri_ok[] = { + MI_LOAD_REGISTER_IMM, + BCS_GPR(0), + ok_val, + MI_BATCH_BUFFER_END, + }; + + const uint32_t lri_bad[] = { + MI_LOAD_REGISTER_IMM, + BCS_GPR(0), + bad_val, + MI_BATCH_BUFFER_END, + }; + + const uint32_t store_reg[] = { + MI_STORE_REGISTER_MEM | (4 - 2), + BCS_GPR(0), + 0, /* reloc */ + 0, /* reloc */ + MI_NOOP, + MI_BATCH_BUFFER_END, + }; + + exec_batch(fd, I915_EXEC_BLT, handle, + lri_ok, sizeof(lri_ok), + 0); + + exec_batch_patched(fd, I915_EXEC_BLT, handle, + store_reg, sizeof(store_reg), + 2 * sizeof(uint32_t), /* reloc */ + ok_val); + + exec_batch(fd, I915_EXEC_BLT, handle, + lri_bad, 0, + 0); + + exec_batch_patched(fd, I915_EXEC_BLT, handle, + store_reg, sizeof(store_reg), + 2 * sizeof(uint32_t), /* reloc */ + ok_val); + + exec_batch(fd, I915_EXEC_BLT, handle, + lri_ok, 4096, + 0); + + igt_assert_eq(__gem_write(fd, handle, 0, noops, 4097), -EINVAL); +} + +struct reg { + uint32_t addr; + uint32_t mask; + bool masked_write; + bool privileged; +}; + +#define REG_M(ADDR, MASK, WM, P) { (ADDR), (MASK), (WM), (P) } +#define REG(ADDR) REG_M(ADDR, 0xffffffff, false, false) +#define REG_P(ADDR) REG_M(ADDR, 0xffffffff, false, true) + +static const struct reg regs[] = { + REG_M(BCS_SWCTRL, 0x3, true, false), + REG(BCS_GPR(0)), + REG(BCS_GPR_UDW(0)), + REG(BCS_GPR(1)), + REG(BCS_GPR_UDW(1)), + REG(BCS_GPR(2)), + REG(BCS_GPR_UDW(2)), + REG(BCS_GPR(3)), + REG(BCS_GPR_UDW(3)), + REG(BCS_GPR(4)), + REG(BCS_GPR_UDW(4)), + REG(BCS_GPR(5)), + REG(BCS_GPR_UDW(5)), + REG(BCS_GPR(6)), + REG(BCS_GPR_UDW(6)), + REG(BCS_GPR(7)), + REG(BCS_GPR_UDW(7)), + REG(BCS_GPR(8)), + REG(BCS_GPR_UDW(8)), + REG(BCS_GPR(9)), + REG(BCS_GPR_UDW(9)), + REG(BCS_GPR(10)), + REG(BCS_GPR_UDW(10)), + REG(BCS_GPR(11)), + REG(BCS_GPR_UDW(11)), + REG(BCS_GPR(12)), + REG(BCS_GPR_UDW(12)), + REG(BCS_GPR(13)), + REG(BCS_GPR_UDW(13)), + REG(BCS_GPR(14)), + REG(BCS_GPR_UDW(14)), + REG(BCS_GPR(15)), + REG(BCS_GPR_UDW(15)), + + REG_P(0), + REG_P(200000), + + REG_P(BCS_SWCTRL - 1), + REG_P(BCS_SWCTRL - 2), + REG_P(BCS_SWCTRL - 3), + REG_P(BCS_SWCTRL - 4), + REG_P(BCS_SWCTRL + 4), + + REG_P(BCS_GPR(0) - 1), + REG_P(BCS_GPR(0) - 2), + REG_P(BCS_GPR(0) - 3), + REG_P(BCS_GPR(0) - 4), + REG_P(BCS_GPR_UDW(15) + 4), +}; + +static void test_register(const int fd, const uint32_t handle, + const struct reg *r) +{ + const uint32_t lri_zero[] = { + MI_LOAD_REGISTER_IMM, + r->addr, + r->masked_write ? 0xffff0000 : 0, + MI_BATCH_BUFFER_END, + }; + + const uint32_t lri_mask[] = { + MI_LOAD_REGISTER_IMM, + r->addr, + r->masked_write ? (r->mask << 16) | r->mask : r->mask, + MI_BATCH_BUFFER_END, + }; + + const uint32_t store_reg[] = { + MI_STORE_REGISTER_MEM | (4 - 2), + r->addr, + 0, /* reloc */ + 0, /* reloc */ + MI_NOOP, + MI_BATCH_BUFFER_END, + }; + + exec_batch(fd, I915_EXEC_BLT, handle, + lri_mask, sizeof(lri_mask), + r->privileged ? -EACCES : 0); + + exec_batch_patched(fd, I915_EXEC_BLT, handle, + store_reg, sizeof(store_reg), + 2 * sizeof(uint32_t), /* reloc */ + r->privileged ? -EACCES : r->mask); + + exec_batch(fd, I915_EXEC_BLT, handle, + lri_zero, sizeof(lri_zero), + r->privileged ? -EACCES : 0); + + exec_batch_patched(fd, I915_EXEC_BLT, handle, + store_reg, sizeof(store_reg), + 2 * sizeof(uint32_t), /* reloc */ + r->privileged ? -EACCES : 0); +} + +static void test_valid_registers(const int fd, const uint32_t handle) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(regs); i++) + test_register(fd, handle, ®s[i]); +} + +static long int read_reg(const int fd, const uint32_t handle, + const uint32_t addr) +{ + const uint32_t store_reg[] = { + MI_STORE_REGISTER_MEM | (4 - 2), + addr, + 0, /* reloc */ + 0, /* reloc */ + MI_NOOP, + MI_BATCH_BUFFER_END, + }; + uint32_t target_bo; + uint32_t value; + long int ret; + + target_bo = gem_create(fd, HANDLE_SIZE); + + ret = __exec_batch_patched(fd, I915_EXEC_BLT, handle, + store_reg, sizeof(store_reg), + target_bo, 2 * sizeof(uint32_t), 0); + + if (ret) { + igt_assert_lt(ret, 0); + gem_close(fd, target_bo); + return ret; + } + + gem_sync(fd, handle); + + gem_read(fd, target_bo, 0, &value, sizeof(value)); + + gem_close(fd, target_bo); + + return value; +} + +static int write_reg(const int fd, const uint32_t handle, + const uint32_t addr, const uint32_t val) +{ + const uint32_t lri[] = { + MI_LOAD_REGISTER_IMM, + addr, + val, + MI_BATCH_BUFFER_END, + }; + + return __exec_batch(fd, I915_EXEC_BLT, handle, + lri, sizeof(lri)); +} + +static void test_unaligned_access(const int fd, const uint32_t handle) +{ + const uint32_t addr = BCS_GPR(4); + const uint32_t val = 0xbaadfead; + const uint32_t pre = 0x12345678; + const uint32_t post = 0x87654321; + + igt_assert_eq(write_reg(fd, handle, addr - 4, pre), 0); + igt_assert_eq(write_reg(fd, handle, addr, val), 0); + igt_assert_eq(write_reg(fd, handle, addr + 4, post), 0); + + igt_assert_eq(read_reg(fd, handle, addr - 4), pre); + igt_assert_eq(read_reg(fd, handle, addr), val); + igt_assert_eq(read_reg(fd, handle, addr + 4), post); + + for (int i = 0; i < 4; i++) { + igt_assert_eq(write_reg(fd, handle, addr + i, val), 0); + igt_assert_eq(read_reg(fd, handle, addr), val); + + igt_assert_eq(read_reg(fd, handle, addr + 1), val); + igt_assert_eq(read_reg(fd, handle, addr + 2), val); + igt_assert_eq(read_reg(fd, handle, addr + 3), val); + igt_assert_eq(read_reg(fd, handle, addr + 4), post); + igt_assert_eq(read_reg(fd, handle, addr - 3), pre); + igt_assert_eq(read_reg(fd, handle, addr - 2), pre); + igt_assert_eq(read_reg(fd, handle, addr - 1), pre); + } +} + +igt_main +{ + uint32_t handle; + int fd; + + igt_fixture { + fd = drm_open_driver(DRIVER_INTEL); + igt_require_gem(fd); + gem_require_blitter(fd); + + parser_version = command_parser_version(fd); + /* igt_require(parser_version == 10); */ + + igt_require(gem_uses_ppgtt(fd)); + igt_require(gem_has_blt(fd)); + igt_require(intel_gen(intel_get_drm_devid(fd)) == 9); + + handle = gem_create(fd, HANDLE_SIZE); + + igt_fork_hang_detector(fd); + } + + igt_subtest("secure-batches") + test_secure_batches(fd); + + igt_subtest("allowed-all") + test_allowed_all(fd, handle); + + igt_subtest("allowed-single") + test_allowed_single(fd, handle); + + igt_subtest("bb-start-param") + test_bb_start(fd, handle, BB_START_PARAM); + + igt_subtest("bb-start-out") + test_bb_start(fd, handle, BB_START_OUT); + + igt_subtest("bb-secure") + test_bb_secure(fd, handle); + + igt_subtest("bb-chained") + test_bb_chained(fd, handle); + + igt_subtest("cmd-crossing-page") + test_cmd_crossing_page(fd, handle); + + igt_subtest("batch-without-end") { + const uint32_t noop[1024] = { 0 }; + + exec_batch(fd, I915_EXEC_BLT, handle, + noop, sizeof(noop), + -EINVAL); + } + + igt_subtest("batch-zero-length") { + const uint32_t noop[] = { 0, MI_BATCH_BUFFER_END }; + + exec_batch(fd, I915_EXEC_BLT, handle, + noop, 0, + -EINVAL); + } + + igt_subtest("batch-invalid-length") + test_invalid_length(fd, handle); + + igt_subtest("basic-rejected") { + const uint32_t invalid_cmd[] = { + INSTR_INVALID_CLIENT << INSTR_CLIENT_SHIFT, + MI_BATCH_BUFFER_END, + }; + const uint32_t invalid_set_context[] = { + MI_SET_CONTEXT | 32, /* invalid length */ + MI_BATCH_BUFFER_END, + }; + + exec_batch(fd, I915_EXEC_BLT, handle, + invalid_cmd, sizeof(invalid_cmd), + -EINVAL); + + exec_batch(fd, I915_EXEC_BLT, handle, + invalid_set_context, sizeof(invalid_set_context), + -EINVAL); + } + + igt_subtest("valid-registers") + test_valid_registers(fd, handle); + + igt_subtest("unaligned-access") + test_unaligned_access(fd, handle); + + igt_subtest_group { + igt_hang_t hang; + + igt_fixture igt_allow_hang(fd, 0, 0); + + igt_subtest("bb-start-cmd") + test_bb_start(fd, handle, BB_START_CMD); + + igt_fixture igt_disallow_hang(fd, hang); + } + + igt_fixture { + igt_stop_hang_detector(); + gem_close(fd, handle); + + close(fd); + } +} diff --git a/tests/intel-ci/fast-feedback.testlist b/tests/intel-ci/fast-feedback.testlist index 9dd27b42..a3c66b42 100644 --- a/tests/intel-ci/fast-feedback.testlist +++ b/tests/intel-ci/fast-feedback.testlist @@ -203,3 +203,4 @@ igt@i915_module_load@reload igt@i915_module_load@reload-no-display igt@i915_module_load@reload-with-fault-injection igt@i915_pm_rpm@module-reload +igt@gem_blt_parse@bb-start #expected hang so last diff --git a/tests/meson.build b/tests/meson.build index 98f2db55..43899b95 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -148,6 +148,7 @@ i915_progs = [ 'gem_exec_parallel', 'gem_exec_params', 'gem_exec_parse', + 'gem_blt_parse', 'gem_exec_reloc', 'gem_exec_reuse', 'gem_exec_schedule', From patchwork Wed Nov 13 15:49:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Kuoppala X-Patchwork-Id: 11242161 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4E18F1709 for ; Wed, 13 Nov 2019 15:49:39 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3698322CAD for ; Wed, 13 Nov 2019 15:49:39 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3698322CAD Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D00A16ED7E; Wed, 13 Nov 2019 15:49:38 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by gabe.freedesktop.org (Postfix) with ESMTPS id 414F26ED70; Wed, 13 Nov 2019 15:49:31 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 13 Nov 2019 07:49:30 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.68,300,1569308400"; d="scan'208";a="379263996" Received: from rosetta.fi.intel.com ([10.237.72.194]) by orsmga005.jf.intel.com with ESMTP; 13 Nov 2019 07:49:27 -0800 Received: by rosetta.fi.intel.com (Postfix, from userid 1000) id 7AF778402E8; Wed, 13 Nov 2019 17:49:17 +0200 (EET) From: Mika Kuoppala To: intel-gfx@lists.freedesktop.org Date: Wed, 13 Nov 2019 17:49:12 +0200 Message-Id: <20191113154913.8787-6-mika.kuoppala@linux.intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191113154913.8787-1-mika.kuoppala@linux.intel.com> References: <20191113154913.8787-1-mika.kuoppala@linux.intel.com> Subject: [Intel-gfx] [PATCH i-g-t 6/7] lib/igt_aux: Add helper to query suspend-to-mem modes X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: igt-dev@lists.freedesktop.org MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" From: Imre Deak Add a helper to query the supported and currently selected suspend-to-mem modes. v2: - Fix for old kernels where the mem_sleep sysfs file didn't yet exist. Signed-off-by: Imre Deak --- lib/igt_aux.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++ lib/igt_aux.h | 24 +++++++++++++++ 2 files changed, 105 insertions(+) diff --git a/lib/igt_aux.c b/lib/igt_aux.c index 578f8579..f2cb3247 100644 --- a/lib/igt_aux.c +++ b/lib/igt_aux.c @@ -827,6 +827,87 @@ static uint32_t get_supported_suspend_states(int power_dir) return state_mask; } +static const char *suspend_to_mem_mode_name[] = { + [SUSPEND_TO_MEM_S2IDLE] = "s2idle", + [SUSPEND_TO_MEM_SHALLOW] = "shallow", + [SUSPEND_TO_MEM_DEEP] = "deep", +}; + +static uint32_t +get_supported_suspend_to_mem_modes(int power_dir, + enum igt_suspend_to_mem_mode *selected_mode) +{ + char *modes; + char *mode_name; + uint32_t mode_mask; + bool selected_found = false; + + /* + * Other modes than deep sleep were only introduced with the mem_sleep + * sysfs file. + */ + modes = igt_sysfs_get(power_dir, "mem_sleep"); + if (!modes) { + *selected_mode = SUSPEND_TO_MEM_DEEP; + return 1 << SUSPEND_TO_MEM_DEEP; + } + + mode_mask = 0; + for (mode_name = strtok(modes, " "); mode_name; + mode_name = strtok(NULL, " ")) { + enum igt_suspend_to_mem_mode mode; + bool selected = false; + + if (mode_name[0] == '[') { + char *e = &mode_name[strlen(mode_name) - 1]; + + igt_assert(!selected_found); + igt_assert(*e == ']'); + mode_name++; + *e = '\0'; + + selected = true; + } + + for (mode = SUSPEND_TO_MEM_S2IDLE; + mode < SUSPEND_TO_MEM_NUM; + mode++) + if (strcmp(mode_name, + suspend_to_mem_mode_name[mode]) == 0) + break; + igt_assert(mode < SUSPEND_TO_MEM_NUM); + mode_mask |= 1 << mode; + if (selected) { + selected_found = true; + if (selected_mode) + *selected_mode = mode; + } + } + + igt_assert(selected_found); + + free(modes); + + return mode_mask; +} + +/** + * igt_get_suspend_to_mem_mode: + * + * Returns the currently selected @igt_suspend_to_mem_mode. + */ +enum igt_suspend_to_mem_mode igt_get_suspend_to_mem_mode(void) +{ + int power_dir; + enum igt_suspend_to_mem_mode mode; + + igt_require((power_dir = open("/sys/power", O_RDONLY)) >= 0); + (void)get_supported_suspend_to_mem_modes(power_dir, &mode); + close(power_dir); + + return mode; +} + /** * igt_system_suspend_autoresume: * @state: an #igt_suspend_state, the target suspend state diff --git a/lib/igt_aux.h b/lib/igt_aux.h index 04d22904..7ccaa8c4 100644 --- a/lib/igt_aux.h +++ b/lib/igt_aux.h @@ -184,10 +184,34 @@ enum igt_suspend_test { SUSPEND_TEST_NUM, }; +/** + * igt_suspend_to_mem_mode: + * @SUSPEND_TO_MEM_S2IDLE: suspend to mem maps to @SUSPEND_STATE_FREEZE + * @SUSPEND_TO_MEM_SHALLOW: suspend to mem maps to @SUSPEND_STATE_STANDBY + * @SUSPEND_TO_MEM_DEEP: suspend to mem will target the ACPI S3 state + * + * The target system state when suspending to mem: + * - Suspending with @SUSPEND_STATE_MEM/@SUSPEND_TO_MEM_S2IDLE is equivalent to + * suspending with @SUSPEND_STATE_FREEZE. + * - Suspending with @SUSPEND_STATE_MEM/@SUSPEND_TO_MEM_SHALLOW is equivalent to + * suspending with @SUSPEND_STATE_STANDBY. + * - Suspending with @SUSPEND_STATE_MEM/@SUSPEND_TO_MEM_DEEP will target the + * ACPI S3 state. + */ +enum igt_suspend_to_mem_mode { + SUSPEND_TO_MEM_S2IDLE, + SUSPEND_TO_MEM_SHALLOW, + SUSPEND_TO_MEM_DEEP, + + /*< private >*/ + SUSPEND_TO_MEM_NUM, +}; + void igt_system_suspend_autoresume(enum igt_suspend_state state, enum igt_suspend_test test); void igt_set_autoresume_delay(int delay_secs); int igt_get_autoresume_delay(enum igt_suspend_state state); +enum igt_suspend_to_mem_mode igt_get_suspend_to_mem_mode(void); /* dropping priviledges */ void igt_drop_root(void); From patchwork Wed Nov 13 15:49:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Mika Kuoppala X-Patchwork-Id: 11242155 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5EF9F1709 for ; Wed, 13 Nov 2019 15:49:33 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 47C1A22C9D for ; Wed, 13 Nov 2019 15:49:33 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 47C1A22C9D Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 7FD8B6ED70; Wed, 13 Nov 2019 15:49:31 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTPS id 770A46ED71; Wed, 13 Nov 2019 15:49:28 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 13 Nov 2019 07:49:28 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.68,300,1569308400"; d="scan'208";a="235312612" Received: from rosetta.fi.intel.com ([10.237.72.194]) by fmsmga002.fm.intel.com with ESMTP; 13 Nov 2019 07:49:26 -0800 Received: by rosetta.fi.intel.com (Postfix, from userid 1000) id 7D0FF840758; Wed, 13 Nov 2019 17:49:17 +0200 (EET) From: Mika Kuoppala To: intel-gfx@lists.freedesktop.org Date: Wed, 13 Nov 2019 17:49:13 +0200 Message-Id: <20191113154913.8787-7-mika.kuoppala@linux.intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191113154913.8787-1-mika.kuoppala@linux.intel.com> References: <20191113154913.8787-1-mika.kuoppala@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t 7/7] test/i915: Add i915_rc6_ctx_corruption X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: igt-dev@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" From: Imre Deak Add a test to exercise the kernel's mechanism to detection of RC6 context corruptions, take the necessary action in response (disable RC6 and runtime PM) and recover when possible (after system suspend/resume). v2: - Skip test on non-existing engines. - Fix for old kernels where the command parser returned EINVAL instead of EACCESS for a banned privilidged command. Signed-off-by: Imre Deak --- tests/Makefile.sources | 3 + tests/i915/i915_rc6_ctx_corruption.c | 196 +++++++++++++++++++++++++++ tests/meson.build | 1 + 3 files changed, 200 insertions(+) create mode 100644 tests/i915/i915_rc6_ctx_corruption.c diff --git a/tests/Makefile.sources b/tests/Makefile.sources index 75c79edb..c0f401c7 100644 --- a/tests/Makefile.sources +++ b/tests/Makefile.sources @@ -529,6 +529,9 @@ i915_pm_sseu_SOURCES = i915/i915_pm_sseu.c TESTS_progs += i915_query i915_query_SOURCES = i915/i915_query.c +TESTS_progs += i915_rc6_ctx_corruption +i915_rc6_ctx_corruption_SOURCES = i915/i915_rc6_ctx_corruption.c + TESTS_progs += i915_selftest i915_selftest_SOURCES = i915/i915_selftest.c diff --git a/tests/i915/i915_rc6_ctx_corruption.c b/tests/i915/i915_rc6_ctx_corruption.c new file mode 100644 index 00000000..a3326307 --- /dev/null +++ b/tests/i915/i915_rc6_ctx_corruption.c @@ -0,0 +1,196 @@ +/* + * Copyright © 2019 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 + +#include "igt.h" +#include "igt_gt.h" +#include "igt_device.h" + +#define CTX_INFO_REG 0xA300 + +static int drm_fd; +static struct pci_device *pci_dev; +static uint32_t devid; + +static int read_reg_on_engine(const struct intel_execution_engine2 *engine, + int reg_address, uint32_t *reg_val) +{ + const bool r64b = intel_gen(devid) >= 8; + struct drm_i915_gem_exec_object2 obj[2]; + struct drm_i915_gem_relocation_entry reloc[1]; + struct drm_i915_gem_execbuffer2 execbuf; + uint32_t *batch; + uint32_t *dst_buf; + int ret; + int i; + + memset(obj, 0, sizeof(obj)); + obj[0].handle = gem_create(drm_fd, 4096); + obj[1].handle = gem_create(drm_fd, 4096); + obj[1].relocs_ptr = to_user_pointer(reloc); + obj[1].relocation_count = 1; + + batch = gem_mmap__cpu(drm_fd, obj[1].handle, 0, 4096, PROT_WRITE); + gem_set_domain(drm_fd, obj[1].handle, + I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU); + + i = 0; + batch[i++] = 0x24 << 23 | (1 + r64b); /* SRM */ + batch[i++] = reg_address; + reloc[0].target_handle = obj[0].handle; + reloc[0].presumed_offset = obj[0].offset; + reloc[0].offset = i * sizeof(uint32_t); + reloc[0].delta = 0; + reloc[0].read_domains = I915_GEM_DOMAIN_RENDER; + reloc[0].write_domain = I915_GEM_DOMAIN_RENDER; + batch[i++] = reloc[0].delta; + if (r64b) + batch[i++] = 0; + + batch[i++] = MI_BATCH_BUFFER_END; + munmap(batch, 4096); + + memset(&execbuf, 0, sizeof(execbuf)); + execbuf.buffers_ptr = to_user_pointer(obj); + execbuf.buffer_count = 2; + execbuf.flags = engine->flags; + + ret = __gem_execbuf(drm_fd, &execbuf); + gem_close(drm_fd, obj[1].handle); + + if (ret) + goto err; + + if (reg_val) { + dst_buf = gem_mmap__cpu(drm_fd, obj[0].handle, 0, 4096, + PROT_READ); + gem_set_domain(drm_fd, obj[0].handle, I915_GEM_DOMAIN_CPU, 0); + + *reg_val = dst_buf[0]; + munmap(dst_buf, 4096); + } + +err: + gem_close(drm_fd, obj[0].handle); + + return ret; +} + +static bool need_ctx_corruption_wa(void) +{ + return IS_BROADWELL(devid) || intel_gen(devid) == 9; +} + +static void test_read_on_engine(const struct intel_execution_engine2 *engine) +{ + int ret; + + gem_require_ring(drm_fd, engine->flags); + + /* + * Recovery is only possible via an S3 suspend/resume or reboot, so + * skip the test if there's no means to recover. Currently this is + * only the case when the selected suspend-to-mem mode is 'deep' (S3). + */ + igt_require(!need_ctx_corruption_wa() || + igt_get_suspend_to_mem_mode() == SUSPEND_TO_MEM_DEEP); + + ret = read_reg_on_engine(engine, CTX_INFO_REG, NULL); + + /* + * Do we have the blitter engine parser in place, catching the bad + * SRM? + */ + if ((ret == -EACCES || ret == -EINVAL) && + engine->class == I915_ENGINE_CLASS_COPY) + return; + + igt_assert_eq(ret, 0); + + /* + * On a plarform not affected by the corruption issue we are done here + * if not yet hung. + */ + if (!need_ctx_corruption_wa()) + return; + + /* Let it suspend if it can. */ + sleep(1); + + /* + * Due to detection of the corruption, runtime suspend should be + * disabled now. + */ + igt_assert(igt_wait_for_pm_status(IGT_RUNTIME_PM_STATUS_ACTIVE)); + + /* + * Let's check now if system suspend/resume recovers from the problem + * as it should. + */ + igt_system_suspend_autoresume(SUSPEND_STATE_MEM, SUSPEND_TEST_NONE); + igt_assert(igt_wait_for_pm_status(IGT_RUNTIME_PM_STATUS_SUSPENDED)); +} + +static void setup_environment(void) +{ + drmModeRes *res; + + drm_fd = drm_open_driver(DRIVER_INTEL); + igt_require_gem(drm_fd); + pci_dev = intel_get_pci_device(); + devid = pci_dev->device_id; + + igt_require(igt_setup_runtime_pm()); + + kmstest_set_vt_graphics_mode(); + + res = drmModeGetResources(drm_fd); + igt_assert(res); + + kmstest_unset_all_crtcs(drm_fd, res); + + igt_require(igt_wait_for_pm_status(IGT_RUNTIME_PM_STATUS_SUSPENDED)); +} + +static void cleanup_environment(void) +{ + close(drm_fd); +} + +igt_main { + const struct intel_execution_engine2 *e; + + igt_fixture { + setup_environment(); + } + + for (e = intel_execution_engines2; e->name; e++) { + igt_subtest_f("basic-%s", e->name) + test_read_on_engine(e); + } + + igt_fixture { + cleanup_environment(); + } +} diff --git a/tests/meson.build b/tests/meson.build index 43899b95..56107695 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -237,6 +237,7 @@ i915_progs = [ 'i915_pm_dc', 'i915_pm_rps', 'i915_pm_sseu', + 'i915_rc6_ctx_corruption', 'i915_query', 'i915_selftest', 'i915_suspend',