Re: [PATCH 15/22] drm/i915: Make request allocation caches global

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On 04/02/2019 13:22, Chris Wilson wrote
As kmem_caches share the same properties (size, allocation/free behaviour)
for all potential devices, we can use global caches. While this
potential has worse fragmentation behaviour (one can argue that
different devices would have different activity lifetimes, but you can
also argue that activity is temporal across the system) it is the
default behaviour of the system at large to amalgamate matching caches.

The benefit for us is much reduced pointer dancing along the frequent
allocation paths.

Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx>
---
  drivers/gpu/drm/i915/Makefile                 |  1 +
  drivers/gpu/drm/i915/i915_active.c            |  9 ++-
  drivers/gpu/drm/i915/i915_active.h            |  1 +
  drivers/gpu/drm/i915/i915_drv.h               |  3 -
  drivers/gpu/drm/i915/i915_gem.c               | 32 +--------
  drivers/gpu/drm/i915/i915_globals.c           | 49 ++++++++++++++
  drivers/gpu/drm/i915/i915_globals.h           | 14 ++++
  drivers/gpu/drm/i915/i915_pci.c               |  8 ++-
  drivers/gpu/drm/i915/i915_request.c           | 53 ++++++++++++---
  drivers/gpu/drm/i915/i915_request.h           | 10 +++
  drivers/gpu/drm/i915/i915_scheduler.c         | 66 +++++++++++++++----
  drivers/gpu/drm/i915/i915_scheduler.h         | 34 ++++++++--
  drivers/gpu/drm/i915/intel_guc_submission.c   |  3 +-
  drivers/gpu/drm/i915/intel_lrc.c              |  6 +-
  drivers/gpu/drm/i915/intel_ringbuffer.h       | 17 -----
  drivers/gpu/drm/i915/selftests/intel_lrc.c    |  2 +-
  drivers/gpu/drm/i915/selftests/mock_engine.c  | 48 +++++++-------
  .../gpu/drm/i915/selftests/mock_gem_device.c  | 26 --------
  drivers/gpu/drm/i915/selftests/mock_request.c | 12 ++--
  drivers/gpu/drm/i915/selftests/mock_request.h |  7 --
  20 files changed, 248 insertions(+), 153 deletions(-)
  create mode 100644 drivers/gpu/drm/i915/i915_globals.c
  create mode 100644 drivers/gpu/drm/i915/i915_globals.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 1787e1299b1b..a1d834068765 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -77,6 +77,7 @@ i915-y += \
  	  i915_gem_tiling.o \
  	  i915_gem_userptr.o \
  	  i915_gemfs.o \
+	  i915_globals.o \
  	  i915_query.o \
  	  i915_request.o \
  	  i915_scheduler.o \
diff --git a/drivers/gpu/drm/i915/i915_active.c b/drivers/gpu/drm/i915/i915_active.c
index 64661c41532b..d23092d8c89f 100644
--- a/drivers/gpu/drm/i915/i915_active.c
+++ b/drivers/gpu/drm/i915/i915_active.c
@@ -251,7 +251,7 @@ void i915_active_fini(struct i915_active *ref)
  #include "selftests/i915_active.c"
  #endif
-int __init i915_global_active_init(void)
+int i915_global_active_init(void)

These can't remain __init, since they are only called from the global __init one?

  {
  	global.slab_cache = KMEM_CACHE(active_node, SLAB_HWCACHE_ALIGN);
  	if (!global.slab_cache)
@@ -260,7 +260,12 @@ int __init i915_global_active_init(void)
  	return 0;
  }
-void __exit i915_global_active_exit(void)
+void i915_global_active_shrink(void)
+{
+	kmem_cache_shrink(global.slab_cache);
+}
+
+void i915_global_active_exit(void)
  {
  	kmem_cache_destroy(global.slab_cache);
  }
diff --git a/drivers/gpu/drm/i915/i915_active.h b/drivers/gpu/drm/i915/i915_active.h
index 179b47aeec33..6c56d10b1f59 100644
--- a/drivers/gpu/drm/i915/i915_active.h
+++ b/drivers/gpu/drm/i915/i915_active.h
@@ -71,6 +71,7 @@ static inline void i915_active_fini(struct i915_active *ref) { }
  #endif
int i915_global_active_init(void);
+void i915_global_active_shrink(void);
  void i915_global_active_exit(void);
#endif /* _I915_ACTIVE_H_ */
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 3e4538ce5276..e48e3c228d9c 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1459,9 +1459,6 @@ struct drm_i915_private {
  	struct kmem_cache *objects;
  	struct kmem_cache *vmas;
  	struct kmem_cache *luts;
-	struct kmem_cache *requests;
-	struct kmem_cache *dependencies;
-	struct kmem_cache *priorities;
const struct intel_device_info __info; /* Use INTEL_INFO() to access. */
  	struct intel_runtime_info __runtime; /* Use RUNTIME_INFO() to access. */
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 2c6161c89cc7..d82e4f990586 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -42,6 +42,7 @@
  #include "i915_drv.h"
  #include "i915_gem_clflush.h"
  #include "i915_gemfs.h"
+#include "i915_globals.h"
  #include "i915_reset.h"
  #include "i915_trace.h"
  #include "i915_vgpu.h"
@@ -2916,12 +2917,11 @@ static void shrink_caches(struct drm_i915_private *i915)
  	 * filled slabs to prioritise allocating from the mostly full slabs,
  	 * with the aim of reducing fragmentation.
  	 */
-	kmem_cache_shrink(i915->priorities);
-	kmem_cache_shrink(i915->dependencies);
-	kmem_cache_shrink(i915->requests);
  	kmem_cache_shrink(i915->luts);
  	kmem_cache_shrink(i915->vmas);
  	kmem_cache_shrink(i915->objects);
+
+	i915_globals_shrink();

This is the main bit which worries me.

Global caches are what we want I think, exactly for what you wrote in the commit message. But would one device going idle have the potential to inject some latency into another potentially very busy client?

Perhaps we could have some sort of aggregated idle signal and defer shrinking cached to that point. Like a bitmask of global clients reporting their idle/active status to global core, and then shrink happens only if all are idle.

  }
struct sleep_rcu_work {
@@ -5264,23 +5264,6 @@ int i915_gem_init_early(struct drm_i915_private *dev_priv)
  	if (!dev_priv->luts)
  		goto err_vmas;
- dev_priv->requests = KMEM_CACHE(i915_request,
-					SLAB_HWCACHE_ALIGN |
-					SLAB_RECLAIM_ACCOUNT |
-					SLAB_TYPESAFE_BY_RCU);
-	if (!dev_priv->requests)
-		goto err_luts;
-
-	dev_priv->dependencies = KMEM_CACHE(i915_dependency,
-					    SLAB_HWCACHE_ALIGN |
-					    SLAB_RECLAIM_ACCOUNT);
-	if (!dev_priv->dependencies)
-		goto err_requests;
-
-	dev_priv->priorities = KMEM_CACHE(i915_priolist, SLAB_HWCACHE_ALIGN);
-	if (!dev_priv->priorities)
-		goto err_dependencies;
-
  	INIT_LIST_HEAD(&dev_priv->gt.active_rings);
  	INIT_LIST_HEAD(&dev_priv->gt.closed_vma);
@@ -5305,12 +5288,6 @@ int i915_gem_init_early(struct drm_i915_private *dev_priv) return 0; -err_dependencies:
-	kmem_cache_destroy(dev_priv->dependencies);
-err_requests:
-	kmem_cache_destroy(dev_priv->requests);
-err_luts:
-	kmem_cache_destroy(dev_priv->luts);
  err_vmas:
  	kmem_cache_destroy(dev_priv->vmas);
  err_objects:
@@ -5328,9 +5305,6 @@ void i915_gem_cleanup_early(struct drm_i915_private *dev_priv)
cleanup_srcu_struct(&dev_priv->gpu_error.srcu); - kmem_cache_destroy(dev_priv->priorities);
-	kmem_cache_destroy(dev_priv->dependencies);
-	kmem_cache_destroy(dev_priv->requests);
  	kmem_cache_destroy(dev_priv->luts);
  	kmem_cache_destroy(dev_priv->vmas);
  	kmem_cache_destroy(dev_priv->objects);
diff --git a/drivers/gpu/drm/i915/i915_globals.c b/drivers/gpu/drm/i915/i915_globals.c
new file mode 100644
index 000000000000..2ecf9897fd16
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_globals.c
@@ -0,0 +1,49 @@
+/*
+ * SPDX-License-Identifier: MIT
+ *
+ * Copyright © 2019 Intel Corporation
+ */
+
+#include "i915_active.h"
+#include "i915_globals.h"
+#include "i915_request.h"
+#include "i915_scheduler.h"
+
+int __init i915_globals_init(void)
+{
+	int err;
+
+	err = i915_global_active_init();
+	if (err)
+		return err;
+
+	err = i915_global_request_init();
+	if (err)
+		goto err_active;
+
+	err = i915_global_scheduler_init();
+	if (err)
+		goto err_request;
+
+	return 0;
+
+err_request:
+	i915_global_request_exit();
+err_active:
+	i915_global_active_exit();
+	return err;
+}
+
+void i915_globals_shrink(void)
+{
+	i915_global_active_shrink();
+	i915_global_request_shrink();
+	i915_global_scheduler_shrink();
+}
+
+void __exit i915_globals_exit(void)
+{
+	i915_global_scheduler_exit();
+	i915_global_request_exit();
+	i915_global_active_exit();
+}
diff --git a/drivers/gpu/drm/i915/i915_globals.h b/drivers/gpu/drm/i915/i915_globals.h
new file mode 100644
index 000000000000..903f52c0a1d2
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_globals.h
@@ -0,0 +1,14 @@
+/*
+ * SPDX-License-Identifier: MIT
+ *
+ * Copyright © 2019 Intel Corporation
+ */
+
+#ifndef _I915_GLOBALS_H_
+#define _I915_GLOBALS_H_
+
+int i915_globals_init(void);
+void i915_globals_shrink(void);
+void i915_globals_exit(void);
+
+#endif /* _I915_GLOBALS_H_ */
diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 852b6b4e8ed8..0d684eb530c3 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -28,8 +28,8 @@
#include <drm/drm_drv.h> -#include "i915_active.h"
  #include "i915_drv.h"
+#include "i915_globals.h"
  #include "i915_selftest.h"
#define PLATFORM(x) .platform = (x), .platform_mask = BIT(x)
@@ -801,7 +801,9 @@ static int __init i915_init(void)
  	bool use_kms = true;
  	int err;
- i915_global_active_init();
+	err = i915_globals_init();
+	if (err)
+		return err;
err = i915_mock_selftests();
  	if (err)
@@ -834,7 +836,7 @@ static void __exit i915_exit(void)
  		return;
pci_unregister_driver(&i915_pci_driver);
-	i915_global_active_exit();
+	i915_globals_exit();
  }
module_init(i915_init);
diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
index 04c65e6d83b9..3bb4840ba761 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -31,6 +31,11 @@
  #include "i915_drv.h"
  #include "i915_reset.h"
+static struct i915_global_request {
+	struct kmem_cache *slab_requests;
+	struct kmem_cache *slab_dependencies;
+} global;
+
  static const char *i915_fence_get_driver_name(struct dma_fence *fence)
  {
  	return "i915";
@@ -83,7 +88,7 @@ static void i915_fence_release(struct dma_fence *fence)
  	 */
  	i915_sw_fence_fini(&rq->submit);
- kmem_cache_free(rq->i915->requests, rq);
+	kmem_cache_free(global.slab_requests, rq);
  }
const struct dma_fence_ops i915_fence_ops = {
@@ -301,7 +306,7 @@ static void i915_request_retire(struct i915_request *request)
unreserve_gt(request->i915); - i915_sched_node_fini(request->i915, &request->sched);
+	i915_sched_node_fini(&request->sched);
  	i915_request_put(request);
  }
@@ -535,7 +540,7 @@ i915_request_alloc_slow(struct intel_context *ce)
  	ring_retire_requests(ring);
out:
-	return kmem_cache_alloc(ce->gem_context->i915->requests, GFP_KERNEL);
+	return kmem_cache_alloc(global.slab_requests, GFP_KERNEL);
  }
/**
@@ -617,7 +622,7 @@ i915_request_alloc(struct intel_engine_cs *engine, struct i915_gem_context *ctx)
  	 *
  	 * Do not use kmem_cache_zalloc() here!
  	 */
-	rq = kmem_cache_alloc(i915->requests,
+	rq = kmem_cache_alloc(global.slab_requests,
  			      GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_NOWARN);
  	if (unlikely(!rq)) {
  		rq = i915_request_alloc_slow(ce);
@@ -701,7 +706,7 @@ i915_request_alloc(struct intel_engine_cs *engine, struct i915_gem_context *ctx)
  	GEM_BUG_ON(!list_empty(&rq->sched.signalers_list));
  	GEM_BUG_ON(!list_empty(&rq->sched.waiters_list));
- kmem_cache_free(i915->requests, rq);
+	kmem_cache_free(global.slab_requests, rq);
  err_unreserve:
  	unreserve_gt(i915);
  	intel_context_unpin(ce);
@@ -720,9 +725,7 @@ i915_request_await_request(struct i915_request *to, struct i915_request *from)
  		return 0;
if (to->engine->schedule) {
-		ret = i915_sched_node_add_dependency(to->i915,
-						     &to->sched,
-						     &from->sched);
+		ret = i915_sched_node_add_dependency(&to->sched, &from->sched);
  		if (ret < 0)
  			return ret;
  	}
@@ -1195,3 +1198,37 @@ void i915_retire_requests(struct drm_i915_private *i915)
  #include "selftests/mock_request.c"
  #include "selftests/i915_request.c"
  #endif
+
+int i915_global_request_init(void)
+{
+	global.slab_requests = KMEM_CACHE(i915_request,
+					  SLAB_HWCACHE_ALIGN |
+					  SLAB_RECLAIM_ACCOUNT |
+					  SLAB_TYPESAFE_BY_RCU);
+	if (!global.slab_requests)
+		return -ENOMEM;
+
+	global.slab_dependencies = KMEM_CACHE(i915_dependency,
+					      SLAB_HWCACHE_ALIGN |
+					      SLAB_RECLAIM_ACCOUNT);
+	if (!global.slab_dependencies)
+		goto err_requests;
+
+	return 0;
+
+err_requests:
+	kmem_cache_destroy(global.slab_requests);
+	return -ENOMEM;
+}
+
+void i915_global_request_shrink(void)
+{
+	kmem_cache_shrink(global.slab_dependencies);
+	kmem_cache_shrink(global.slab_requests);
+}
+
+void i915_global_request_exit(void)
+{
+	kmem_cache_destroy(global.slab_dependencies);
+	kmem_cache_destroy(global.slab_requests);
+}
diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h
index 3cffb96203b9..054bd300984b 100644
--- a/drivers/gpu/drm/i915/i915_request.h
+++ b/drivers/gpu/drm/i915/i915_request.h
@@ -29,6 +29,7 @@
#include "i915_gem.h"
  #include "i915_scheduler.h"
+#include "i915_selftest.h"
  #include "i915_sw_fence.h"
#include <uapi/drm/i915_drm.h>
@@ -204,6 +205,11 @@ struct i915_request {
  	struct drm_i915_file_private *file_priv;
  	/** file_priv list entry for this request */
  	struct list_head client_link;
+
+	I915_SELFTEST_DECLARE(struct {
+		struct list_head link;
+		unsigned long delay;
+	} mock;)
  };
#define I915_FENCE_GFP (GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_NOWARN)
@@ -786,4 +792,8 @@ i915_gem_active_retire(struct i915_gem_active *active,
  #define for_each_active(mask, idx) \
  	for (; mask ? idx = ffs(mask) - 1, 1 : 0; mask &= ~BIT(idx))
+int i915_global_request_init(void);
+void i915_global_request_shrink(void);
+void i915_global_request_exit(void);
+
  #endif /* I915_REQUEST_H */
diff --git a/drivers/gpu/drm/i915/i915_scheduler.c b/drivers/gpu/drm/i915/i915_scheduler.c
index d01683167c77..7c1d9ef98374 100644
--- a/drivers/gpu/drm/i915/i915_scheduler.c
+++ b/drivers/gpu/drm/i915/i915_scheduler.c
@@ -10,6 +10,11 @@
  #include "i915_request.h"
  #include "i915_scheduler.h"
+static struct i915_global_scheduler {
+	struct kmem_cache *slab_dependencies;
+	struct kmem_cache *slab_priorities;
+} global;
+
  static DEFINE_SPINLOCK(schedule_lock);
static const struct i915_request *
@@ -32,16 +37,15 @@ void i915_sched_node_init(struct i915_sched_node *node)
  }
static struct i915_dependency *
-i915_dependency_alloc(struct drm_i915_private *i915)
+i915_dependency_alloc(void)
  {
-	return kmem_cache_alloc(i915->dependencies, GFP_KERNEL);
+	return kmem_cache_alloc(global.slab_dependencies, GFP_KERNEL);
  }
static void
-i915_dependency_free(struct drm_i915_private *i915,
-		     struct i915_dependency *dep)
+i915_dependency_free(struct i915_dependency *dep)
  {
-	kmem_cache_free(i915->dependencies, dep);
+	kmem_cache_free(global.slab_dependencies, dep);
  }
bool __i915_sched_node_add_dependency(struct i915_sched_node *node,
@@ -68,25 +72,23 @@ bool __i915_sched_node_add_dependency(struct i915_sched_node *node,
  	return ret;
  }
-int i915_sched_node_add_dependency(struct drm_i915_private *i915,
-				   struct i915_sched_node *node,
+int i915_sched_node_add_dependency(struct i915_sched_node *node,
  				   struct i915_sched_node *signal)
  {
  	struct i915_dependency *dep;
- dep = i915_dependency_alloc(i915);
+	dep = i915_dependency_alloc();
  	if (!dep)
  		return -ENOMEM;
if (!__i915_sched_node_add_dependency(node, signal, dep,
  					      I915_DEPENDENCY_ALLOC))
-		i915_dependency_free(i915, dep);
+		i915_dependency_free(dep);
return 0;
  }
-void i915_sched_node_fini(struct drm_i915_private *i915,
-			  struct i915_sched_node *node)
+void i915_sched_node_fini(struct i915_sched_node *node)
  {
  	struct i915_dependency *dep, *tmp;
@@ -106,7 +108,7 @@ void i915_sched_node_fini(struct drm_i915_private *i915, list_del(&dep->wait_link);
  		if (dep->flags & I915_DEPENDENCY_ALLOC)
-			i915_dependency_free(i915, dep);
+			i915_dependency_free(dep);
  	}
/* Remove ourselves from everyone who depends upon us */
@@ -116,7 +118,7 @@ void i915_sched_node_fini(struct drm_i915_private *i915,
list_del(&dep->signal_link);
  		if (dep->flags & I915_DEPENDENCY_ALLOC)
-			i915_dependency_free(i915, dep);
+			i915_dependency_free(dep);
  	}
spin_unlock(&schedule_lock);
@@ -193,7 +195,7 @@ i915_sched_lookup_priolist(struct intel_engine_cs *engine, int prio)
  	if (prio == I915_PRIORITY_NORMAL) {
  		p = &execlists->default_priolist;
  	} else {
-		p = kmem_cache_alloc(engine->i915->priorities, GFP_ATOMIC);
+		p = kmem_cache_alloc(global.slab_priorities, GFP_ATOMIC);
  		/* Convert an allocation failure to a priority bump */
  		if (unlikely(!p)) {
  			prio = I915_PRIORITY_NORMAL; /* recurses just once */
@@ -408,3 +410,39 @@ void i915_schedule_bump_priority(struct i915_request *rq, unsigned int bump)
spin_unlock_bh(&schedule_lock);
  }
+
+void __i915_priolist_free(struct i915_priolist *p)
+{
+	kmem_cache_free(global.slab_priorities, p);
+}
+
+int i915_global_scheduler_init(void)
+{
+	global.slab_dependencies = KMEM_CACHE(i915_dependency,
+					      SLAB_HWCACHE_ALIGN);
+	if (!global.slab_dependencies)
+		return -ENOMEM;

Right, so this slab is duplicated. It could end up merged by the core, but I am thinking if this is the direction we want to go just to avoid some pointer chasing.

You wouldn't consider i915->global->slab_dependencies or something along those lines?

Regards,

Tvrtko

+
+	global.slab_priorities = KMEM_CACHE(i915_priolist,
+					    SLAB_HWCACHE_ALIGN);
+	if (!global.slab_priorities)
+		goto err_priorities;
+
+	return 0;
+
+err_priorities:
+	kmem_cache_destroy(global.slab_priorities);
+	return -ENOMEM;
+}
+
+void i915_global_scheduler_shrink(void)
+{
+	kmem_cache_shrink(global.slab_dependencies);
+	kmem_cache_shrink(global.slab_priorities);
+}
+
+void i915_global_scheduler_exit(void)
+{
+	kmem_cache_destroy(global.slab_dependencies);
+	kmem_cache_destroy(global.slab_priorities);
+}
diff --git a/drivers/gpu/drm/i915/i915_scheduler.h b/drivers/gpu/drm/i915/i915_scheduler.h
index 54bd6c89817e..5196ce07b6c2 100644
--- a/drivers/gpu/drm/i915/i915_scheduler.h
+++ b/drivers/gpu/drm/i915/i915_scheduler.h
@@ -85,6 +85,23 @@ struct i915_dependency {
  #define I915_DEPENDENCY_ALLOC BIT(0)
  };
+struct i915_priolist {
+	struct list_head requests[I915_PRIORITY_COUNT];
+	struct rb_node node;
+	unsigned long used;
+	int priority;
+};
+
+#define priolist_for_each_request(it, plist, idx) \
+	for (idx = 0; idx < ARRAY_SIZE((plist)->requests); idx++) \
+		list_for_each_entry(it, &(plist)->requests[idx], sched.link)
+
+#define priolist_for_each_request_consume(it, n, plist, idx) \
+	for (; (idx = ffs((plist)->used)); (plist)->used &= ~BIT(idx - 1)) \
+		list_for_each_entry_safe(it, n, \
+					 &(plist)->requests[idx - 1], \
+					 sched.link)
+
  void i915_sched_node_init(struct i915_sched_node *node);
bool __i915_sched_node_add_dependency(struct i915_sched_node *node,
@@ -92,12 +109,10 @@ bool __i915_sched_node_add_dependency(struct i915_sched_node *node,
  				      struct i915_dependency *dep,
  				      unsigned long flags);
-int i915_sched_node_add_dependency(struct drm_i915_private *i915,
-				   struct i915_sched_node *node,
+int i915_sched_node_add_dependency(struct i915_sched_node *node,
  				   struct i915_sched_node *signal);
-void i915_sched_node_fini(struct drm_i915_private *i915,
-			  struct i915_sched_node *node);
+void i915_sched_node_fini(struct i915_sched_node *node);
void i915_schedule(struct i915_request *request,
  		   const struct i915_sched_attr *attr);
@@ -107,4 +122,15 @@ void i915_schedule_bump_priority(struct i915_request *rq, unsigned int bump);
  struct list_head *
  i915_sched_lookup_priolist(struct intel_engine_cs *engine, int prio);
+void __i915_priolist_free(struct i915_priolist *p);
+static inline void i915_priolist_free(struct i915_priolist *p)
+{
+	if (p->priority != I915_PRIORITY_NORMAL)
+		__i915_priolist_free(p);
+}
+
+int i915_global_scheduler_init(void);
+void i915_global_scheduler_shrink(void);
+void i915_global_scheduler_exit(void);
+
  #endif /* _I915_SCHEDULER_H_ */
diff --git a/drivers/gpu/drm/i915/intel_guc_submission.c b/drivers/gpu/drm/i915/intel_guc_submission.c
index 8bc8aa54aa35..4cf94513615d 100644
--- a/drivers/gpu/drm/i915/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/intel_guc_submission.c
@@ -781,8 +781,7 @@ static bool __guc_dequeue(struct intel_engine_cs *engine)
  		}
rb_erase_cached(&p->node, &execlists->queue);
-		if (p->priority != I915_PRIORITY_NORMAL)
-			kmem_cache_free(engine->i915->priorities, p);
+		i915_priolist_free(p);
  	}
  done:
  	execlists->queue_priority_hint =
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 8e301f19036b..e37f207afb5a 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -806,8 +806,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
  		}
rb_erase_cached(&p->node, &execlists->queue);
-		if (p->priority != I915_PRIORITY_NORMAL)
-			kmem_cache_free(engine->i915->priorities, p);
+		i915_priolist_free(p);
  	}
done:
@@ -966,8 +965,7 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine)
  		}
rb_erase_cached(&p->node, &execlists->queue);
-		if (p->priority != I915_PRIORITY_NORMAL)
-			kmem_cache_free(engine->i915->priorities, p);
+		i915_priolist_free(p);
  	}
intel_write_status_page(engine,
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 8183d3441907..5dffccb6740e 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -185,23 +185,6 @@ enum intel_engine_id {
  #define _VECS(n) (VECS + (n))
  };
-struct i915_priolist {
-	struct list_head requests[I915_PRIORITY_COUNT];
-	struct rb_node node;
-	unsigned long used;
-	int priority;
-};
-
-#define priolist_for_each_request(it, plist, idx) \
-	for (idx = 0; idx < ARRAY_SIZE((plist)->requests); idx++) \
-		list_for_each_entry(it, &(plist)->requests[idx], sched.link)
-
-#define priolist_for_each_request_consume(it, n, plist, idx) \
-	for (; (idx = ffs((plist)->used)); (plist)->used &= ~BIT(idx - 1)) \
-		list_for_each_entry_safe(it, n, \
-					 &(plist)->requests[idx - 1], \
-					 sched.link)
-
  struct st_preempt_hang {
  	struct completion completion;
  	unsigned int count;
diff --git a/drivers/gpu/drm/i915/selftests/intel_lrc.c b/drivers/gpu/drm/i915/selftests/intel_lrc.c
index 967cefa118ee..30ab0e04a674 100644
--- a/drivers/gpu/drm/i915/selftests/intel_lrc.c
+++ b/drivers/gpu/drm/i915/selftests/intel_lrc.c
@@ -440,7 +440,7 @@ static struct i915_request *dummy_request(struct intel_engine_cs *engine)
  static void dummy_request_free(struct i915_request *dummy)
  {
  	i915_request_mark_complete(dummy);
-	i915_sched_node_fini(dummy->engine->i915, &dummy->sched);
+	i915_sched_node_fini(&dummy->sched);
  	kfree(dummy);
  }
diff --git a/drivers/gpu/drm/i915/selftests/mock_engine.c b/drivers/gpu/drm/i915/selftests/mock_engine.c
index 08f0cab02e0f..0d35af07867b 100644
--- a/drivers/gpu/drm/i915/selftests/mock_engine.c
+++ b/drivers/gpu/drm/i915/selftests/mock_engine.c
@@ -76,28 +76,27 @@ static void mock_ring_free(struct intel_ring *base)
  	kfree(ring);
  }
-static struct mock_request *first_request(struct mock_engine *engine)
+static struct i915_request *first_request(struct mock_engine *engine)
  {
  	return list_first_entry_or_null(&engine->hw_queue,
-					struct mock_request,
-					link);
+					struct i915_request,
+					mock.link);
  }
-static void advance(struct mock_request *request)
+static void advance(struct i915_request *request)
  {
-	list_del_init(&request->link);
-	intel_engine_write_global_seqno(request->base.engine,
-					request->base.global_seqno);
-	i915_request_mark_complete(&request->base);
-	GEM_BUG_ON(!i915_request_completed(&request->base));
+	list_del_init(&request->mock.link);
+	intel_engine_write_global_seqno(request->engine, request->global_seqno);
+	i915_request_mark_complete(request);
+	GEM_BUG_ON(!i915_request_completed(request));
- intel_engine_queue_breadcrumbs(request->base.engine);
+	intel_engine_queue_breadcrumbs(request->engine);
  }
static void hw_delay_complete(struct timer_list *t)
  {
  	struct mock_engine *engine = from_timer(engine, t, hw_delay);
-	struct mock_request *request;
+	struct i915_request *request;
  	unsigned long flags;
spin_lock_irqsave(&engine->hw_lock, flags);
@@ -112,8 +111,9 @@ static void hw_delay_complete(struct timer_list *t)
  	 * requeue the timer for the next delayed request.
  	 */
  	while ((request = first_request(engine))) {
-		if (request->delay) {
-			mod_timer(&engine->hw_delay, jiffies + request->delay);
+		if (request->mock.delay) {
+			mod_timer(&engine->hw_delay,
+				  jiffies + request->mock.delay);
  			break;
  		}
@@ -171,10 +171,8 @@ mock_context_pin(struct intel_engine_cs *engine, static int mock_request_alloc(struct i915_request *request)
  {
-	struct mock_request *mock = container_of(request, typeof(*mock), base);
-
-	INIT_LIST_HEAD(&mock->link);
-	mock->delay = 0;
+	INIT_LIST_HEAD(&request->mock.link);
+	request->mock.delay = 0;
return 0;
  }
@@ -192,7 +190,6 @@ static u32 *mock_emit_breadcrumb(struct i915_request *request, u32 *cs)
static void mock_submit_request(struct i915_request *request)
  {
-	struct mock_request *mock = container_of(request, typeof(*mock), base);
  	struct mock_engine *engine =
  		container_of(request->engine, typeof(*engine), base);
  	unsigned long flags;
@@ -201,12 +198,13 @@ static void mock_submit_request(struct i915_request *request)
  	GEM_BUG_ON(!request->global_seqno);
spin_lock_irqsave(&engine->hw_lock, flags);
-	list_add_tail(&mock->link, &engine->hw_queue);
-	if (mock->link.prev == &engine->hw_queue) {
-		if (mock->delay)
-			mod_timer(&engine->hw_delay, jiffies + mock->delay);
+	list_add_tail(&request->mock.link, &engine->hw_queue);
+	if (list_is_first(&request->mock.link, &engine->hw_queue)) {
+		if (request->mock.delay)
+			mod_timer(&engine->hw_delay,
+				  jiffies + request->mock.delay);
  		else
-			advance(mock);
+			advance(request);
  	}
  	spin_unlock_irqrestore(&engine->hw_lock, flags);
  }
@@ -266,12 +264,12 @@ void mock_engine_flush(struct intel_engine_cs *engine)
  {
  	struct mock_engine *mock =
  		container_of(engine, typeof(*mock), base);
-	struct mock_request *request, *rn;
+	struct i915_request *request, *rn;
del_timer_sync(&mock->hw_delay); spin_lock_irq(&mock->hw_lock);
-	list_for_each_entry_safe(request, rn, &mock->hw_queue, link)
+	list_for_each_entry_safe(request, rn, &mock->hw_queue, mock.link)
  		advance(request);
  	spin_unlock_irq(&mock->hw_lock);
  }
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index 074a0d9cbf26..17915a2d94fa 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -79,9 +79,6 @@ 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);
  	kmem_cache_destroy(i915->objects);
@@ -211,23 +208,6 @@ struct drm_i915_private *mock_gem_device(void)
  	if (!i915->vmas)
  		goto err_objects;
- i915->requests = KMEM_CACHE(mock_request,
-				    SLAB_HWCACHE_ALIGN |
-				    SLAB_RECLAIM_ACCOUNT |
-				    SLAB_TYPESAFE_BY_RCU);
-	if (!i915->requests)
-		goto err_vmas;
-
-	i915->dependencies = KMEM_CACHE(i915_dependency,
-					SLAB_HWCACHE_ALIGN |
-					SLAB_RECLAIM_ACCOUNT);
-	if (!i915->dependencies)
-		goto err_requests;
-
-	i915->priorities = KMEM_CACHE(i915_priolist, SLAB_HWCACHE_ALIGN);
-	if (!i915->priorities)
-		goto err_dependencies;
-
  	i915_timelines_init(i915);
INIT_LIST_HEAD(&i915->gt.active_rings);
@@ -257,12 +237,6 @@ struct drm_i915_private *mock_gem_device(void)
  err_unlock:
  	mutex_unlock(&i915->drm.struct_mutex);
  	i915_timelines_fini(i915);
-	kmem_cache_destroy(i915->priorities);
-err_dependencies:
-	kmem_cache_destroy(i915->dependencies);
-err_requests:
-	kmem_cache_destroy(i915->requests);
-err_vmas:
  	kmem_cache_destroy(i915->vmas);
  err_objects:
  	kmem_cache_destroy(i915->objects);
diff --git a/drivers/gpu/drm/i915/selftests/mock_request.c b/drivers/gpu/drm/i915/selftests/mock_request.c
index 0dc29e242597..d1a7c9608712 100644
--- a/drivers/gpu/drm/i915/selftests/mock_request.c
+++ b/drivers/gpu/drm/i915/selftests/mock_request.c
@@ -31,29 +31,25 @@ mock_request(struct intel_engine_cs *engine,
  	     unsigned long delay)
  {
  	struct i915_request *request;
-	struct mock_request *mock;
/* NB the i915->requests slab cache is enlarged to fit mock_request */
  	request = i915_request_alloc(engine, context);
  	if (IS_ERR(request))
  		return NULL;
- mock = container_of(request, typeof(*mock), base);
-	mock->delay = delay;
-
-	return &mock->base;
+	request->mock.delay = delay;
+	return request;
  }
bool mock_cancel_request(struct i915_request *request)
  {
-	struct mock_request *mock = container_of(request, typeof(*mock), base);
  	struct mock_engine *engine =
  		container_of(request->engine, typeof(*engine), base);
  	bool was_queued;
spin_lock_irq(&engine->hw_lock);
-	was_queued = !list_empty(&mock->link);
-	list_del_init(&mock->link);
+	was_queued = !list_empty(&request->mock.link);
+	list_del_init(&request->mock.link);
  	spin_unlock_irq(&engine->hw_lock);
if (was_queued)
diff --git a/drivers/gpu/drm/i915/selftests/mock_request.h b/drivers/gpu/drm/i915/selftests/mock_request.h
index 995fb728380c..4acf0211df20 100644
--- a/drivers/gpu/drm/i915/selftests/mock_request.h
+++ b/drivers/gpu/drm/i915/selftests/mock_request.h
@@ -29,13 +29,6 @@
#include "../i915_request.h" -struct mock_request {
-	struct i915_request base;
-
-	struct list_head link;
-	unsigned long delay;
-};
-
  struct i915_request *
  mock_request(struct intel_engine_cs *engine,
  	     struct i915_gem_context *context,

_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/intel-gfx




[Index of Archives]     [AMD Graphics]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux