From patchwork Fri Apr 13 14:14:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Wilson X-Patchwork-Id: 10340213 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id C401A60329 for ; Fri, 13 Apr 2018 14:14:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D844D2886E for ; Fri, 13 Apr 2018 14:14:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CB38728884; Fri, 13 Apr 2018 14:14:20 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00, MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 19CA62886E for ; Fri, 13 Apr 2018 14:14:19 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5BF7E6E1B5; Fri, 13 Apr 2018 14:14:18 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from fireflyinternet.com (mail.fireflyinternet.com [109.228.58.192]) by gabe.freedesktop.org (Postfix) with ESMTPS id 361FE6E1B5 for ; Fri, 13 Apr 2018 14:14:16 +0000 (UTC) X-Default-Received-SPF: pass (skip=forwardok (res=PASS)) x-ip-name=78.156.65.138; Received: from haswell.alporthouse.com (unverified [78.156.65.138]) by fireflyinternet.com (Firefly Internet (M1)) with ESMTP id 11362081-1500050 for multiple; Fri, 13 Apr 2018 15:14:11 +0100 Received: by haswell.alporthouse.com (sSMTP sendmail emulation); Fri, 13 Apr 2018 15:14:10 +0100 From: Chris Wilson To: intel-gfx@lists.freedesktop.org Date: Fri, 13 Apr 2018 15:14:09 +0100 Message-Id: <20180413141409.8774-1-chris@chris-wilson.co.uk> X-Mailer: git-send-email 2.17.0 X-Originating-IP: 78.156.65.138 X-Country: code=GB country="United Kingdom" ip=78.156.65.138 Subject: [Intel-gfx] [PATCH igt] igt/gem_exec_schedule: Exercise preemption timeout 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: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP Set up a unpreemptible spinner such that the only way we can inject a high priority request onto the GPU is by resetting the spinner. The test fails if we trigger hangcheck rather than the fast timeout mechanism. Signed-off-by: Chris Wilson Reviewed-by: Antonio Argenziano --- lib/i915/gem_context.c | 72 +++++++++++++++++++++++++++++++-------- lib/i915/gem_context.h | 3 ++ lib/igt_dummyload.c | 12 +++++-- lib/igt_dummyload.h | 3 ++ tests/gem_exec_schedule.c | 34 ++++++++++++++++++ 5 files changed, 106 insertions(+), 18 deletions(-) diff --git a/lib/i915/gem_context.c b/lib/i915/gem_context.c index 669bd318c..c76f78d97 100644 --- a/lib/i915/gem_context.c +++ b/lib/i915/gem_context.c @@ -112,15 +112,17 @@ uint32_t gem_context_create(int fd) int __gem_context_destroy(int fd, uint32_t ctx_id) { struct drm_i915_gem_context_destroy destroy; - int ret; + int err; memset(&destroy, 0, sizeof(destroy)); destroy.ctx_id = ctx_id; - ret = igt_ioctl(fd, DRM_IOCTL_I915_GEM_CONTEXT_DESTROY, &destroy); - if (ret) - return -errno; - return 0; + err = 0; + if (igt_ioctl(fd, DRM_IOCTL_I915_GEM_CONTEXT_DESTROY, &destroy)) + err = -errno; + + errno = 0; + return err; } /** @@ -142,11 +144,14 @@ void gem_context_destroy(int fd, uint32_t ctx_id) int __gem_context_get_param(int fd, struct drm_i915_gem_context_param *p) { + int err; + + err = 0; if (igt_ioctl(fd, DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM, p)) - return -errno; + err = -errno; errno = 0; - return 0; + return err; } /** @@ -159,17 +164,20 @@ int __gem_context_get_param(int fd, struct drm_i915_gem_context_param *p) */ void gem_context_get_param(int fd, struct drm_i915_gem_context_param *p) { - igt_assert(__gem_context_get_param(fd, p) == 0); + igt_assert_eq(__gem_context_get_param(fd, p), 0); } int __gem_context_set_param(int fd, struct drm_i915_gem_context_param *p) { + int err; + + err = 0; if (igt_ioctl(fd, DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, p)) - return -errno; + err = -errno; errno = 0; - return 0; + return err; } /** * gem_context_set_param: @@ -181,7 +189,7 @@ int __gem_context_set_param(int fd, struct drm_i915_gem_context_param *p) */ void gem_context_set_param(int fd, struct drm_i915_gem_context_param *p) { - igt_assert(__gem_context_set_param(fd, p) == 0); + igt_assert_eq(__gem_context_set_param(fd, p), 0); } /** @@ -234,8 +242,6 @@ void gem_context_require_bannable(int fd) igt_require(has_ban_period || has_bannable); } -#define DRM_I915_CONTEXT_PARAM_PRIORITY 0x6 - /** * __gem_context_set_priority: * @fd: open i915 drm file descriptor @@ -255,7 +261,7 @@ int __gem_context_set_priority(int fd, uint32_t ctx_id, int prio) memset(&p, 0, sizeof(p)); p.ctx_id = ctx_id; p.size = 0; - p.param = DRM_I915_CONTEXT_PARAM_PRIORITY; + p.param = I915_CONTEXT_PARAM_PRIORITY; p.value = prio; return __gem_context_set_param(fd, &p); @@ -271,5 +277,41 @@ int __gem_context_set_priority(int fd, uint32_t ctx_id, int prio) */ void gem_context_set_priority(int fd, uint32_t ctx_id, int prio) { - igt_assert(__gem_context_set_priority(fd, ctx_id, prio) == 0); + igt_assert_eq(__gem_context_set_priority(fd, ctx_id, prio), 0); +} + +/** + * __gem_context_set_preempt_timeout: + * @fd: open i915 drm file descriptor + * @ctx_id: i915 context id + * @timeout_ns: desired preempt_timeout + * + * Returns: An integer equal to zero for success and negative for failure + */ +int __gem_context_set_preempt_timeout(int fd, uint32_t ctx, uint64_t timeout_ns) +{ +#define LOCAL_CONTEXT_PARAM_PREEMPT_TIMEOUT 7 + struct drm_i915_gem_context_param p; + + memset(&p, 0, sizeof(p)); + p.ctx_id = ctx; + p.size = 0; + p.param = LOCAL_CONTEXT_PARAM_PREEMPT_TIMEOUT; + p.value = timeout_ns; + + return __gem_context_set_param(fd, &p); +} + +/** + * gem_context_set_preempt_timeout: + * @fd: open i915 drm file descriptor + * @ctx: i915 context id + * @timeout_ns: desired preempt timeout + * + * Like __gem_context_set_priority(), except we assert on failure. + */ +void gem_context_set_preempt_timeout(int fd, uint32_t ctx, uint64_t timeout_ns) +{ + igt_assert_eq(__gem_context_set_preempt_timeout(fd, ctx, timeout_ns), + 0); } diff --git a/lib/i915/gem_context.h b/lib/i915/gem_context.h index aef68dda6..634bf584e 100644 --- a/lib/i915/gem_context.h +++ b/lib/i915/gem_context.h @@ -45,4 +45,7 @@ int __gem_context_get_param(int fd, struct drm_i915_gem_context_param *p); int __gem_context_set_priority(int fd, uint32_t ctx, int prio); void gem_context_set_priority(int fd, uint32_t ctx, int prio); +int __gem_context_set_preempt_timeout(int fd, uint32_t ctx, uint64_t timeout_ns); +void gem_context_set_preempt_timeout(int fd, uint32_t ctx, uint64_t timeout_ns); + #endif /* GEM_CONTEXT_H */ diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c index ba917ba58..13aea704c 100644 --- a/lib/igt_dummyload.c +++ b/lib/igt_dummyload.c @@ -77,6 +77,7 @@ fill_reloc(struct drm_i915_gem_relocation_entry *reloc, #define OUT_FENCE (1 << 0) #define POLL_RUN (1 << 1) +#define NO_PREEMPTION (1 << 2) static int emit_recursive_batch(igt_spin_t *spin, int fd, uint32_t ctx, unsigned engine, @@ -192,7 +193,8 @@ emit_recursive_batch(igt_spin_t *spin, int fd, uint32_t ctx, unsigned engine, spin->handle = obj[BATCH].handle; /* Allow ourselves to be preempted */ - *batch++ = MI_ARB_CHK; + if (!(flags & NO_PREEMPTION)) + *batch++ = MI_ARB_CHK; /* Pad with a few nops so that we do not completely hog the system. * @@ -365,6 +367,12 @@ __igt_spin_batch_new_poll(int fd, uint32_t ctx, unsigned engine) return ___igt_spin_batch_new(fd, ctx, engine, 0, POLL_RUN); } +igt_spin_t * +__igt_spin_batch_new_hang(int fd, uint32_t ctx, unsigned engine) +{ + return ___igt_spin_batch_new(fd, ctx, engine, 0, NO_PREEMPTION); +} + /** * igt_spin_batch_new_poll: * @fd: open i915 drm file descriptor @@ -449,8 +457,6 @@ void igt_spin_batch_end(igt_spin_t *spin) if (!spin) return; - igt_assert(*spin->batch == MI_ARB_CHK || - *spin->batch == MI_BATCH_BUFFER_END); *spin->batch = MI_BATCH_BUFFER_END; __sync_synchronize(); } diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h index a8ec213fe..711aa1883 100644 --- a/lib/igt_dummyload.h +++ b/lib/igt_dummyload.h @@ -66,6 +66,9 @@ igt_spin_t *igt_spin_batch_new_poll(int fd, uint32_t ctx, unsigned engine); +igt_spin_t * +__igt_spin_batch_new_hang(int fd, uint32_t ctx, unsigned engine); + void igt_spin_batch_set_timeout(igt_spin_t *spin, int64_t ns); void igt_spin_batch_end(igt_spin_t *spin); void igt_spin_batch_free(int fd, igt_spin_t *spin); diff --git a/tests/gem_exec_schedule.c b/tests/gem_exec_schedule.c index 6ff15b6ef..93254945b 100644 --- a/tests/gem_exec_schedule.c +++ b/tests/gem_exec_schedule.c @@ -656,6 +656,37 @@ static void preemptive_hang(int fd, unsigned ring) gem_context_destroy(fd, ctx[HI]); } +static void preempt_timeout(int fd, unsigned ring) +{ + igt_spin_t *spin[3]; + uint32_t ctx; + + igt_require(__gem_context_set_preempt_timeout(fd, 0, 0)); + + ctx = gem_context_create(fd); + gem_context_set_priority(fd, ctx, MIN_PRIO); + spin[0] = __igt_spin_batch_new_hang(fd, ctx, ring); + spin[1] = __igt_spin_batch_new_hang(fd, ctx, ring); + gem_context_destroy(fd, ctx); + + ctx = gem_context_create(fd); + gem_context_set_priority(fd, ctx, MAX_PRIO); + gem_context_set_preempt_timeout(fd, ctx, 1000 * 1000); + spin[2] = __igt_spin_batch_new(fd, ctx, ring, 0); + gem_context_destroy(fd, ctx); + + igt_spin_batch_end(spin[2]); + gem_sync(fd, spin[2]->handle); + + /* spin[0] is kicked, leaving spin[1] running */ + + igt_assert(gem_bo_busy(fd, spin[1]->handle)); + + igt_spin_batch_free(fd, spin[2]); + igt_spin_batch_free(fd, spin[1]); + igt_spin_batch_free(fd, spin[0]); +} + static void deep(int fd, unsigned ring) { #define XS 8 @@ -1120,6 +1151,9 @@ igt_main igt_subtest_f("preempt-self-%s", e->name) preempt_self(fd, e->exec_id | e->flags); + igt_subtest_f("preempt-timeout-%s", e->name) + preempt_timeout(fd, e->exec_id | e->flags); + igt_subtest_f("preempt-other-%s", e->name) preempt_other(fd, e->exec_id | e->flags, 0);