From patchwork Wed Jan 30 17:25:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Wilson X-Patchwork-Id: 10789073 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EFC5813BF for ; Wed, 30 Jan 2019 17:25:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DF2FE2F8BF for ; Wed, 30 Jan 2019 17:25:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D37912F8CF; Wed, 30 Jan 2019 17:25: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 5E3072F8BF for ; Wed, 30 Jan 2019 17:25:29 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C78316E613; Wed, 30 Jan 2019 17:25:28 +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 4DC8D6E613 for ; Wed, 30 Jan 2019 17:25:27 +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 15406286-1500050 for multiple; Wed, 30 Jan 2019 17:25:13 +0000 From: Chris Wilson To: intel-gfx@lists.freedesktop.org Date: Wed, 30 Jan 2019 17:25:07 +0000 Message-Id: <20190130172507.4207-1-chris@chris-wilson.co.uk> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190130021906.17933-6-chris@chris-wilson.co.uk> References: <20190130021906.17933-6-chris@chris-wilson.co.uk> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH v3] drm/i915: Allocate active tracking nodes from a slabcache 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: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP Wrap the active tracking for a GPU references in a slabcache for faster allocations, and keep track of inflight nodes so we can reap the stale entries upon idling (thereby trimming our memory usage). v2: Automatically discard the trees everytime the tracker idles; they should be rarely used and fast to allocate as required. v3: Nothing device specific left, it's just a slabcache that we can make global. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_active.c | 61 ++++++++++++++++++++++++------ drivers/gpu/drm/i915/i915_active.h | 11 ++++-- drivers/gpu/drm/i915/i915_gem.c | 10 +++-- drivers/gpu/drm/i915/i915_pci.c | 3 ++ 4 files changed, 65 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_active.c b/drivers/gpu/drm/i915/i915_active.c index e0182e19cb8b..d05fd92dbc82 100644 --- a/drivers/gpu/drm/i915/i915_active.c +++ b/drivers/gpu/drm/i915/i915_active.c @@ -9,6 +9,17 @@ #define BKL(ref) (&(ref)->i915->drm.struct_mutex) +/* + * Active refs memory management + * + * To be more economical with memory, we reap all the i915_active trees as + * they idle (when we know the active requests are inactive) and allocate the + * nodes from a local slab cache to hopefully reduce the fragmentation. + */ +static struct i915_global_active { + struct kmem_cache *slab_cache; +} global; + struct active_node { struct i915_gem_active base; struct i915_active *ref; @@ -16,12 +27,29 @@ struct active_node { u64 timeline; }; +static void +__active_park(struct i915_active *ref) +{ + struct active_node *it, *n; + + rbtree_postorder_for_each_entry_safe(it, n, &ref->tree, node) { + GEM_BUG_ON(i915_gem_active_isset(&it->base)); + kmem_cache_free(global.slab_cache, it); + } + ref->tree = RB_ROOT; +} + static void __active_retire(struct i915_active *ref) { GEM_BUG_ON(!ref->count); - if (!--ref->count) - ref->retire(ref); + if (--ref->count) + return; + + /* return the unused nodes to our slabcache */ + __active_park(ref); + + ref->retire(ref); } static void @@ -79,11 +107,11 @@ active_instance(struct i915_active *ref, u64 idx) p = &parent->rb_left; } - node = kmalloc(sizeof(*node), GFP_KERNEL); + node = kmem_cache_alloc(global.slab_cache, GFP_KERNEL); /* kmalloc may retire the ref->last (thanks shrinker)! */ if (unlikely(!i915_gem_active_raw(&ref->last, BKL(ref)))) { - kfree(node); + kmem_cache_free(global.slab_cache, node); goto out; } @@ -174,7 +202,7 @@ int i915_active_wait(struct i915_active *ref) return ret; GEM_BUG_ON(i915_gem_active_isset(&it->base)); - kfree(it); + kmem_cache_free(global.slab_cache, it); } ref->tree = RB_ROOT; @@ -208,17 +236,26 @@ int i915_request_await_active(struct i915_request *rq, struct i915_active *ref) return 0; } +#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM) void i915_active_fini(struct i915_active *ref) { - struct active_node *it, *n; - GEM_BUG_ON(i915_gem_active_isset(&ref->last)); + GEM_BUG_ON(!RB_EMPTY_ROOT(&ref->tree)); +} +#endif - rbtree_postorder_for_each_entry_safe(it, n, &ref->tree, node) { - GEM_BUG_ON(i915_gem_active_isset(&it->base)); - kfree(it); - } - ref->tree = RB_ROOT; +int __init i915_global_active_init(void) +{ + global.slab_cache = KMEM_CACHE(active_node, SLAB_HWCACHE_ALIGN); + if (!global.slab_cache) + return -ENOMEM; + + return 0; +} + +void __exit i915_global_active_exit(void) +{ + kmem_cache_destroy(global.slab_cache); } #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) diff --git a/drivers/gpu/drm/i915/i915_active.h b/drivers/gpu/drm/i915/i915_active.h index c0729a046f98..48fdb1497883 100644 --- a/drivers/gpu/drm/i915/i915_active.h +++ b/drivers/gpu/drm/i915/i915_active.h @@ -9,10 +9,6 @@ #include "i915_active_types.h" -#include - -#include "i915_request.h" - /* * GPU activity tracking * @@ -61,6 +57,13 @@ i915_active_is_idle(const struct i915_active *ref) return !ref->count; } +#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM) void i915_active_fini(struct i915_active *ref); +#else +static inline void i915_active_fini(struct i915_active *ref) { } +#endif + +int i915_global_active_init(void); +void i915_global_active_exit(void); #endif /* _I915_ACTIVE_H_ */ diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index caccff87a2a1..843b7fd93331 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -5002,11 +5002,11 @@ int i915_gem_init(struct drm_i915_private *dev_priv) ret = i915_gem_init_userptr(dev_priv); if (ret) - return ret; + goto err_timelines; ret = intel_uc_init_misc(dev_priv); if (ret) - return ret; + goto err_userptr; ret = intel_wopcm_init(&dev_priv->wopcm); if (ret) @@ -5122,10 +5122,12 @@ int i915_gem_init(struct drm_i915_private *dev_priv) err_uc_misc: intel_uc_fini_misc(dev_priv); - if (ret != -EIO) { +err_userptr: + if (ret != -EIO) i915_gem_cleanup_userptr(dev_priv); +err_timelines: + if (ret != -EIO) i915_timelines_fini(dev_priv); - } if (ret == -EIO) { mutex_lock(&dev_priv->drm.struct_mutex); diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 44c23ac60347..751a787c83d1 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -793,6 +793,8 @@ static int __init i915_init(void) bool use_kms = true; int err; + i915_global_active_init(); + err = i915_mock_selftests(); if (err) return err > 0 ? 0 : err; @@ -824,6 +826,7 @@ static void __exit i915_exit(void) return; pci_unregister_driver(&i915_pci_driver); + i915_global_active_exit(); } module_init(i915_init);