From patchwork Tue Jul 3 08:30:15 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Wilson X-Patchwork-Id: 10503427 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 68AC360225 for ; Tue, 3 Jul 2018 08:30:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 59A182888E for ; Tue, 3 Jul 2018 08:30:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4DB5828894; Tue, 3 Jul 2018 08:30:29 +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 514ED2888E for ; Tue, 3 Jul 2018 08:30:28 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 9C53B6E5A5; Tue, 3 Jul 2018 08:30:27 +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 BB4186E5A5 for ; Tue, 3 Jul 2018 08:30:25 +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 12233767-1500050 for multiple; Tue, 03 Jul 2018 09:30:14 +0100 From: Chris Wilson To: intel-gfx@lists.freedesktop.org Date: Tue, 3 Jul 2018 09:30:15 +0100 Message-Id: <20180703083015.29904-1-chris@chris-wilson.co.uk> X-Mailer: git-send-email 2.18.0 Subject: [Intel-gfx] [PATCH] drm/i915/selftests: Let other struct_mutex users have their gpu time 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 live_gtt is a very slow test to run, simply because it tries to allocate and use as much as the 48b address space as possibly can and in the process will try to own all of the system memory. This leads to resource exhaustion and CPU starvation; the latter impacts us when the NMI watchdog declares a task hung due to a mutex contention with ourselves. This we can prevent by releasing the struct_mutex around cond_resched(), to allow e.g. the i915_gem_free_objects_work to acquire the mutex and cleanup. References: https://bugs.freedesktop.org/show_bug.cgi?id=107094 Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 58 ++++++++++++++----- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c index a28ee0cc6a63..789add200720 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c @@ -32,6 +32,14 @@ #include "mock_drm.h" #include "mock_gem_device.h" +static void schedule_locked(struct drm_i915_private *i915) +{ + /* Let anyone else who wants the context take it */ + mutex_unlock(&i915->drm.struct_mutex); + cond_resched(); + mutex_lock(&i915->drm.struct_mutex); +} + static void fake_free_pages(struct drm_i915_gem_object *obj, struct sg_table *pages) { @@ -132,18 +140,18 @@ fake_dma_object(struct drm_i915_private *i915, u64 size) static int igt_ppgtt_alloc(void *arg) { - struct drm_i915_private *dev_priv = arg; + struct drm_i915_private *i915 = arg; struct i915_hw_ppgtt *ppgtt; u64 size, last; int err = 0; /* Allocate a ppggt and try to fill the entire range */ - if (!USES_PPGTT(dev_priv)) + if (!USES_PPGTT(i915)) return 0; - mutex_lock(&dev_priv->drm.struct_mutex); - ppgtt = __hw_ppgtt_create(dev_priv); + mutex_lock(&i915->drm.struct_mutex); + ppgtt = __hw_ppgtt_create(i915); if (IS_ERR(ppgtt)) { err = PTR_ERR(ppgtt); goto err_unlock; @@ -169,6 +177,8 @@ static int igt_ppgtt_alloc(void *arg) ppgtt->vm.clear_range(&ppgtt->vm, 0, size); } + schedule_locked(i915); + /* Check we can incrementally allocate the entire range */ for (last = 0, size = 4096; size <= ppgtt->vm.total; @@ -189,7 +199,7 @@ static int igt_ppgtt_alloc(void *arg) ppgtt->vm.cleanup(&ppgtt->vm); kfree(ppgtt); err_unlock: - mutex_unlock(&dev_priv->drm.struct_mutex); + mutex_unlock(&i915->drm.struct_mutex); return err; } @@ -291,6 +301,8 @@ static int lowlevel_hole(struct drm_i915_private *i915, i915_gem_object_put(obj); kfree(order); + + schedule_locked(i915); } return 0; @@ -519,6 +531,7 @@ static int fill_hole(struct drm_i915_private *i915, } close_object_list(&objects, vm); + schedule_locked(i915); } return 0; @@ -605,6 +618,8 @@ static int walk_hole(struct drm_i915_private *i915, i915_gem_object_put(obj); if (err) return err; + + schedule_locked(i915); } return 0; @@ -676,6 +691,8 @@ static int pot_hole(struct drm_i915_private *i915, err = -EINTR; goto err; } + + schedule_locked(i915); } err: @@ -789,6 +806,8 @@ static int drunk_hole(struct drm_i915_private *i915, kfree(order); if (err) return err; + + schedule_locked(i915); } return 0; @@ -854,6 +873,8 @@ static int __shrink_hole(struct drm_i915_private *i915, err = -EINTR; break; } + + schedule_locked(i915); } close_object_list(&objects, vm); @@ -949,6 +970,7 @@ static int shrink_boom(struct drm_i915_private *i915, i915_gem_object_put(explode); memset(&vm->fault_attr, 0, sizeof(vm->fault_attr)); + schedule_locked(i915); } return 0; @@ -961,7 +983,7 @@ static int shrink_boom(struct drm_i915_private *i915, return err; } -static int exercise_ppgtt(struct drm_i915_private *dev_priv, +static int exercise_ppgtt(struct drm_i915_private *i915, int (*func)(struct drm_i915_private *i915, struct i915_address_space *vm, u64 hole_start, u64 hole_end, @@ -972,15 +994,15 @@ static int exercise_ppgtt(struct drm_i915_private *dev_priv, IGT_TIMEOUT(end_time); int err; - if (!USES_FULL_PPGTT(dev_priv)) + if (!USES_FULL_PPGTT(i915)) return 0; - file = mock_file(dev_priv); + file = mock_file(i915); if (IS_ERR(file)) return PTR_ERR(file); - mutex_lock(&dev_priv->drm.struct_mutex); - ppgtt = i915_ppgtt_create(dev_priv, file->driver_priv, "mock"); + mutex_lock(&i915->drm.struct_mutex); + ppgtt = i915_ppgtt_create(i915, file->driver_priv, "mock"); if (IS_ERR(ppgtt)) { err = PTR_ERR(ppgtt); goto out_unlock; @@ -988,14 +1010,14 @@ static int exercise_ppgtt(struct drm_i915_private *dev_priv, GEM_BUG_ON(offset_in_page(ppgtt->vm.total)); GEM_BUG_ON(ppgtt->vm.closed); - err = func(dev_priv, &ppgtt->vm, 0, ppgtt->vm.total, end_time); + err = func(i915, &ppgtt->vm, 0, ppgtt->vm.total, end_time); i915_ppgtt_close(&ppgtt->vm); i915_ppgtt_put(ppgtt); out_unlock: - mutex_unlock(&dev_priv->drm.struct_mutex); + mutex_unlock(&i915->drm.struct_mutex); - mock_file_free(dev_priv, file); + mock_file_free(i915, file); return err; } @@ -1315,6 +1337,8 @@ static int igt_gtt_reserve(void *arg) } } + schedule_locked(i915); + /* Now we start forcing evictions */ for (total = I915_GTT_PAGE_SIZE; total + 2*I915_GTT_PAGE_SIZE <= i915->ggtt.vm.total; @@ -1364,6 +1388,8 @@ static int igt_gtt_reserve(void *arg) } } + schedule_locked(i915); + /* And then try at random */ list_for_each_entry_safe(obj, on, &objects, st_link) { struct i915_vma *vma; @@ -1517,6 +1543,8 @@ static int igt_gtt_insert(void *arg) GEM_BUG_ON(!drm_mm_node_allocated(&vma->node)); } + schedule_locked(i915); + list_for_each_entry(obj, &objects, st_link) { struct i915_vma *vma; @@ -1535,6 +1563,8 @@ static int igt_gtt_insert(void *arg) __i915_vma_unpin(vma); } + schedule_locked(i915); + /* If we then reinsert, we should find the same hole */ list_for_each_entry_safe(obj, on, &objects, st_link) { struct i915_vma *vma; @@ -1575,6 +1605,8 @@ static int igt_gtt_insert(void *arg) } } + schedule_locked(i915); + /* And then force evictions */ for (total = 0; total + 2*I915_GTT_PAGE_SIZE <= i915->ggtt.vm.total;