[PATCH 21/25] drm/i915: Allocate read locks from a slabcache
Chris Wilson
chris at chris-wilson.co.uk
Sat Jan 26 16:53:43 UTC 2019
Wrap the active tracking for a read lock in a slabcache for faster
allocations, and keep track of inflight read locks so we can reap the
stale entries upon parking (trimming our memory usage).
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
drivers/gpu/drm/i915/i915_drv.h | 2 +
drivers/gpu/drm/i915/i915_gem.c | 16 ++++++--
drivers/gpu/drm/i915/i915_read_lock.c | 41 +++++++++++++++++--
drivers/gpu/drm/i915/i915_read_lock.h | 5 +++
.../gpu/drm/i915/selftests/mock_gem_device.c | 9 +++-
5 files changed, 65 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index d072f3369ee1..73ef9b3eba95 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1461,6 +1461,7 @@ struct drm_i915_private {
struct kmem_cache *requests;
struct kmem_cache *dependencies;
struct kmem_cache *priorities;
+ struct kmem_cache *read_locks;
const struct intel_device_info __info; /* Use INTEL_INFO() to access. */
struct intel_runtime_info __runtime; /* Use RUNTIME_INFO() to access. */
@@ -1984,6 +1985,7 @@ struct drm_i915_private {
struct list_head hwsp_free_list;
} timelines;
+ struct list_head active_locks;
struct list_head active_rings;
struct list_head closed_vma;
u32 active_requests;
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 101a0f644787..2ba0098378c8 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -171,6 +171,7 @@ static u32 __i915_gem_park(struct drm_i915_private *i915)
intel_engines_park(i915);
i915_timelines_park(i915);
+ i915_read_locks_park(i915);
i915_pmu_gt_parked(i915);
i915_vma_parked(i915);
@@ -5019,15 +5020,19 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
dev_priv->gt.cleanup_engine = intel_engine_cleanup;
}
+ ret = i915_read_locks_init(dev_priv);
+ if (ret)
+ return ret;
+
i915_timelines_init(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)
@@ -5143,9 +5148,13 @@ 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);
+ i915_read_locks_fini(dev_priv);
}
if (ret == -EIO) {
@@ -5198,6 +5207,7 @@ void i915_gem_fini(struct drm_i915_private *dev_priv)
intel_uc_fini_misc(dev_priv);
i915_gem_cleanup_userptr(dev_priv);
i915_timelines_fini(dev_priv);
+ i915_read_locks_fini(dev_priv);
i915_gem_drain_freed_objects(dev_priv);
diff --git a/drivers/gpu/drm/i915/i915_read_lock.c b/drivers/gpu/drm/i915/i915_read_lock.c
index 736b15dfce3a..f286485201aa 100644
--- a/drivers/gpu/drm/i915/i915_read_lock.c
+++ b/drivers/gpu/drm/i915/i915_read_lock.c
@@ -82,12 +82,12 @@ active_instance(struct i915_read_lock *lock, u64 idx)
p = &parent->rb_left;
}
- active = kmalloc(sizeof(*active), GFP_KERNEL);
+ active = kmem_cache_alloc(lock->i915->read_locks, GFP_KERNEL);
/* kmalloc may retire the lock->last_active (thanks shrinker)! */
if (unlikely(!i915_gem_active_raw(&lock->last_active,
&lock->i915->drm.struct_mutex))) {
- kfree(active);
+ kmem_cache_free(lock->i915->read_locks, active);
goto out;
}
@@ -101,6 +101,9 @@ active_instance(struct i915_read_lock *lock, u64 idx)
rb_link_node(&active->node, parent, p);
rb_insert_color(&active->node, &lock->active);
+ if (list_empty(&lock->active_link))
+ list_add(&lock->active_link, &lock->i915->gt.active_locks);
+
replace:
/*
* Overwrite the previous active slot in the rbtree with last_active,
@@ -131,6 +134,7 @@ void i915_read_lock_init(struct drm_i915_private *i915,
lock->retire = retire;
lock->active = RB_ROOT;
init_request_active(&lock->last_active, read_lock_last_retire);
+ INIT_LIST_HEAD(&lock->active_link);
lock->count = 0;
}
@@ -186,11 +190,42 @@ void i915_read_lock_fini(struct i915_read_lock *lock)
{
struct read_lock_active *iter, *n;
+ lockdep_assert_held(&lock->i915->drm.struct_mutex);
GEM_BUG_ON(i915_gem_active_isset(&lock->last_active));
+ if (list_empty(&lock->active_link))
+ return;
+
rbtree_postorder_for_each_entry_safe(iter, n, &lock->active, node) {
GEM_BUG_ON(i915_gem_active_isset(&iter->base));
- kfree(iter);
+ kmem_cache_free(lock->i915->read_locks, iter);
}
lock->active = RB_ROOT;
+
+ list_del_init(&lock->active_link);
+}
+
+int i915_read_locks_init(struct drm_i915_private *i915)
+{
+ i915->read_locks = KMEM_CACHE(i915_read_lock, SLAB_HWCACHE_ALIGN);
+ if (!i915->read_locks)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&i915->gt.active_locks);
+
+ return 0;
+}
+
+void i915_read_locks_park(struct drm_i915_private *i915)
+{
+ struct i915_read_lock *it, *n;
+
+ list_for_each_entry_safe(it, n, &i915->gt.active_locks, active_link)
+ i915_read_lock_fini(it);
+}
+
+void i915_read_locks_fini(struct drm_i915_private *i915)
+{
+ GEM_BUG_ON(!list_empty(&i915->gt.active_locks));
+ kmem_cache_destroy(i915->read_locks);
}
diff --git a/drivers/gpu/drm/i915/i915_read_lock.h b/drivers/gpu/drm/i915/i915_read_lock.h
index af1f1cd0cd5f..63704f719c59 100644
--- a/drivers/gpu/drm/i915/i915_read_lock.h
+++ b/drivers/gpu/drm/i915/i915_read_lock.h
@@ -15,6 +15,7 @@ struct drm_i915_private;
struct i915_read_lock {
struct drm_i915_private *i915;
+ struct list_head active_link;
struct rb_root active;
struct i915_gem_active last_active;
@@ -42,4 +43,8 @@ static inline bool i915_read_lock_is_idle(const struct i915_read_lock *lock)
void i915_read_lock_fini(struct i915_read_lock *lock);
+int i915_read_locks_init(struct drm_i915_private *i915);
+void i915_read_locks_park(struct drm_i915_private *i915);
+void i915_read_locks_fini(struct drm_i915_private *i915);
+
#endif /* _I915_READ_LOCK_H_ */
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index 14ae46fda49f..378b4c13d96a 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -66,9 +66,9 @@ static void mock_device_release(struct drm_device *dev)
for_each_engine(engine, i915, id)
mock_engine_free(engine);
i915_gem_contexts_fini(i915);
- mutex_unlock(&i915->drm.struct_mutex);
-
i915_timelines_fini(i915);
+ i915_read_locks_fini(i915);
+ mutex_unlock(&i915->drm.struct_mutex);
drain_workqueue(i915->wq);
i915_gem_drain_freed_objects(i915);
@@ -227,6 +227,9 @@ struct drm_i915_private *mock_gem_device(void)
if (!i915->priorities)
goto err_dependencies;
+ if (i915_read_locks_init(i915))
+ goto err_priorities;
+
i915_timelines_init(i915);
INIT_LIST_HEAD(&i915->gt.active_rings);
@@ -256,6 +259,8 @@ struct drm_i915_private *mock_gem_device(void)
err_unlock:
mutex_unlock(&i915->drm.struct_mutex);
i915_timelines_fini(i915);
+ i915_read_locks_fini(i915);
+err_priorities:
kmem_cache_destroy(i915->priorities);
err_dependencies:
kmem_cache_destroy(i915->dependencies);
--
2.20.1
More information about the Intel-gfx-trybot
mailing list