From d44ba950ffb324c17af8d6104fe96cf930bc7108 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 17 May 2017 13:10:04 +0100 Subject: [PATCH] drm/i915: Create a kmem_cache to allocate struct i915_priolist from The i915_priolist are allocated within an atomic context on a path where we wish to minimise latency. If we use a dedicated kmem_cache, we have the advantage of a local freelist from which to service new requests that should keep the latency impact of an allocation small. Though currently we expect the majority of requests to be at default priority (and so hit the preallocate priolist), once userspace starts using priorities they are likely to use many fine grained policies improving the utilisation of a private slab. Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/20170517121007.27224-9-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_gem.c | 9 ++++++++- drivers/gpu/drm/i915/i915_guc_submission.c | 2 +- drivers/gpu/drm/i915/intel_lrc.c | 4 ++-- drivers/gpu/drm/i915/selftests/mock_gem_device.c | 9 ++++++++- 5 files changed, 20 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index a6f20471b4cd7..08ee5c8834fb2 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2027,6 +2027,7 @@ struct drm_i915_private { struct kmem_cache *vmas; struct kmem_cache *requests; struct kmem_cache *dependencies; + struct kmem_cache *priorities; const struct intel_device_info info; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 3d9161c8c1a1e..0680bd2e635a0 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4866,12 +4866,16 @@ i915_gem_load_init(struct drm_i915_private *dev_priv) if (!dev_priv->dependencies) goto err_requests; + dev_priv->priorities = KMEM_CACHE(i915_priolist, SLAB_HWCACHE_ALIGN); + if (!dev_priv->priorities) + goto err_dependencies; + mutex_lock(&dev_priv->drm.struct_mutex); INIT_LIST_HEAD(&dev_priv->gt.timelines); err = i915_gem_timeline_init__global(dev_priv); mutex_unlock(&dev_priv->drm.struct_mutex); if (err) - goto err_dependencies; + goto err_priorities; INIT_LIST_HEAD(&dev_priv->context_list); INIT_WORK(&dev_priv->mm.free_work, __i915_gem_free_work); @@ -4895,6 +4899,8 @@ i915_gem_load_init(struct drm_i915_private *dev_priv) return 0; +err_priorities: + kmem_cache_destroy(dev_priv->priorities); err_dependencies: kmem_cache_destroy(dev_priv->dependencies); err_requests: @@ -4918,6 +4924,7 @@ void i915_gem_load_cleanup(struct drm_i915_private *dev_priv) WARN_ON(!list_empty(&dev_priv->gt.timelines)); mutex_unlock(&dev_priv->drm.struct_mutex); + kmem_cache_destroy(dev_priv->priorities); kmem_cache_destroy(dev_priv->dependencies); kmem_cache_destroy(dev_priv->requests); kmem_cache_destroy(dev_priv->vmas); diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 3b9cdb0907c21..b3da056ea8f11 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -704,7 +704,7 @@ static bool i915_guc_dequeue(struct intel_engine_cs *engine) rb_erase(&p->node, &engine->execlist_queue); INIT_LIST_HEAD(&p->requests); if (p->priority != I915_PRIORITY_NORMAL) - kfree(p); + kmem_cache_free(engine->i915->priorities, p); } done: engine->execlist_first = rb; diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 626db6185a21e..8529746dd7cc9 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -499,7 +499,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine) rb_erase(&p->node, &engine->execlist_queue); INIT_LIST_HEAD(&p->requests); if (p->priority != I915_PRIORITY_NORMAL) - kfree(p); + kmem_cache_free(engine->i915->priorities, p); } done: engine->execlist_first = rb; @@ -661,7 +661,7 @@ find_priolist: if (prio == I915_PRIORITY_NORMAL) { p = &engine->default_priolist; } else { - p = kmalloc(sizeof(*p), GFP_ATOMIC); + p = kmem_cache_alloc(engine->i915->priorities, GFP_ATOMIC); /* Convert an allocation failure to a priority bump */ if (unlikely(!p)) { prio = I915_PRIORITY_NORMAL; /* recurses just once */ diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c index f321bdfe0b5bc..3d0e313497d08 100644 --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c @@ -74,6 +74,7 @@ static void mock_device_release(struct drm_device *dev) destroy_workqueue(i915->wq); + kmem_cache_destroy(i915->priorities); kmem_cache_destroy(i915->dependencies); kmem_cache_destroy(i915->requests); kmem_cache_destroy(i915->vmas); @@ -186,12 +187,16 @@ struct drm_i915_private *mock_gem_device(void) if (!i915->dependencies) goto err_requests; + i915->priorities = KMEM_CACHE(i915_priolist, SLAB_HWCACHE_ALIGN); + if (!i915->priorities) + goto err_dependencies; + mutex_lock(&i915->drm.struct_mutex); INIT_LIST_HEAD(&i915->gt.timelines); err = i915_gem_timeline_init__global(i915); if (err) { mutex_unlock(&i915->drm.struct_mutex); - goto err_dependencies; + goto err_priorities; } mock_init_ggtt(i915); @@ -211,6 +216,8 @@ struct drm_i915_private *mock_gem_device(void) err_engine: for_each_engine(engine, i915, id) mock_engine_free(engine); +err_priorities: + kmem_cache_destroy(i915->priorities); err_dependencies: kmem_cache_destroy(i915->dependencies); err_requests: -- 2.39.5