Message ID | 20190305210657.28474-1-chris@chris-wilson.co.uk (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm/i915: Use i915_global_register() | expand |
On 05/03/2019 21:06, Chris Wilson wrote: > Rather than manually add every new global into each hook, use > i915_global_register() function and keep a list of registered globals to > invoke instead. > > However, I haven't found a way for random drivers to add an .init table > to avoid having to manually add ourselves to i915_globals_init() each > time. > > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> > --- > drivers/gpu/drm/i915/i915_active.c | 28 +++++++----- > drivers/gpu/drm/i915/i915_active.h | 2 - > drivers/gpu/drm/i915/i915_gem_context.c | 28 +++++++----- > drivers/gpu/drm/i915/i915_gem_context.h | 2 - > drivers/gpu/drm/i915/i915_gem_object.c | 28 +++++++----- > drivers/gpu/drm/i915/i915_gem_object.h | 2 - > drivers/gpu/drm/i915/i915_globals.c | 59 +++++++++++++------------ > drivers/gpu/drm/i915/i915_globals.h | 11 +++++ > drivers/gpu/drm/i915/i915_request.c | 36 +++++++++------ > drivers/gpu/drm/i915/i915_request.h | 2 - > drivers/gpu/drm/i915/i915_scheduler.c | 32 +++++++++----- > drivers/gpu/drm/i915/i915_scheduler.h | 2 - > drivers/gpu/drm/i915/i915_vma.c | 28 +++++++----- > drivers/gpu/drm/i915/i915_vma.h | 2 - > 14 files changed, 156 insertions(+), 106 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_active.c b/drivers/gpu/drm/i915/i915_active.c > index d9f6471ac16c..863ae12707ba 100644 > --- a/drivers/gpu/drm/i915/i915_active.c > +++ b/drivers/gpu/drm/i915/i915_active.c > @@ -6,6 +6,7 @@ > > #include "i915_drv.h" > #include "i915_active.h" > +#include "i915_globals.h" > > #define BKL(ref) (&(ref)->i915->drm.struct_mutex) > > @@ -17,6 +18,7 @@ > * nodes from a local slab cache to hopefully reduce the fragmentation. > */ > static struct i915_global_active { > + struct i915_global base; > struct kmem_cache *slab_cache; > } global; > > @@ -285,21 +287,27 @@ void i915_active_retire_noop(struct i915_active_request *active, > #include "selftests/i915_active.c" > #endif > > -int __init i915_global_active_init(void) > +static void i915_global_active_shrink(void) > { > - global.slab_cache = KMEM_CACHE(active_node, SLAB_HWCACHE_ALIGN); > - if (!global.slab_cache) > - return -ENOMEM; > - > - return 0; > + kmem_cache_shrink(global.slab_cache); > } > > -void i915_global_active_shrink(void) > +static void i915_global_active_exit(void) > { > - kmem_cache_shrink(global.slab_cache); > + kmem_cache_destroy(global.slab_cache); > } > > -void i915_global_active_exit(void) > +static struct i915_global_active global = { { > + .shrink = i915_global_active_shrink, > + .exit = i915_global_active_exit, > +} }; > + > +int __init i915_global_active_init(void) > { > - kmem_cache_destroy(global.slab_cache); > + global.slab_cache = KMEM_CACHE(active_node, SLAB_HWCACHE_ALIGN); > + if (!global.slab_cache) > + return -ENOMEM; > + > + i915_global_register(&global.base); > + return 0; > } > diff --git a/drivers/gpu/drm/i915/i915_active.h b/drivers/gpu/drm/i915/i915_active.h > index 5fbd9102384b..575c01846875 100644 > --- a/drivers/gpu/drm/i915/i915_active.h > +++ b/drivers/gpu/drm/i915/i915_active.h > @@ -420,7 +420,5 @@ 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_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c > index 1e3211e909f1..b9f321947982 100644 > --- a/drivers/gpu/drm/i915/i915_gem_context.c > +++ b/drivers/gpu/drm/i915/i915_gem_context.c > @@ -88,6 +88,7 @@ > #include <linux/log2.h> > #include <drm/i915_drm.h> > #include "i915_drv.h" > +#include "i915_globals.h" > #include "i915_trace.h" > #include "intel_lrc_reg.h" > #include "intel_workarounds.h" > @@ -95,6 +96,7 @@ > #define ALL_L3_SLICES(dev) (1 << NUM_L3_SLICES(dev)) - 1 > > static struct i915_global_context { > + struct i915_global base; > struct kmem_cache *slab_luts; > } global; > > @@ -1423,21 +1425,27 @@ int __i915_gem_context_pin_hw_id(struct i915_gem_context *ctx) > #include "selftests/i915_gem_context.c" > #endif > > -int __init i915_global_context_init(void) > +static void i915_global_context_shrink(void) > { > - global.slab_luts = KMEM_CACHE(i915_lut_handle, 0); > - if (!global.slab_luts) > - return -ENOMEM; > - > - return 0; > + kmem_cache_shrink(global.slab_luts); > } > > -void i915_global_context_shrink(void) > +static void i915_global_context_exit(void) > { > - kmem_cache_shrink(global.slab_luts); > + kmem_cache_destroy(global.slab_luts); > } > > -void i915_global_context_exit(void) > +static struct i915_global_context global = { { > + .shrink = i915_global_context_shrink, > + .exit = i915_global_context_exit, > +} }; > + > +int __init i915_global_context_init(void) > { > - kmem_cache_destroy(global.slab_luts); > + global.slab_luts = KMEM_CACHE(i915_lut_handle, 0); > + if (!global.slab_luts) > + return -ENOMEM; > + > + i915_global_register(&global.base); > + return 0; > } > diff --git a/drivers/gpu/drm/i915/i915_gem_context.h b/drivers/gpu/drm/i915/i915_gem_context.h > index be63666ffaac..b59107248b54 100644 > --- a/drivers/gpu/drm/i915/i915_gem_context.h > +++ b/drivers/gpu/drm/i915/i915_gem_context.h > @@ -412,7 +412,5 @@ struct i915_lut_handle *i915_lut_handle_alloc(void); > void i915_lut_handle_free(struct i915_lut_handle *lut); > > int i915_global_context_init(void); > -void i915_global_context_shrink(void); > -void i915_global_context_exit(void); > > #endif /* !__I915_GEM_CONTEXT_H__ */ > diff --git a/drivers/gpu/drm/i915/i915_gem_object.c b/drivers/gpu/drm/i915/i915_gem_object.c > index 4aeb8c3b87e4..ac6a5ab84586 100644 > --- a/drivers/gpu/drm/i915/i915_gem_object.c > +++ b/drivers/gpu/drm/i915/i915_gem_object.c > @@ -24,8 +24,10 @@ > > #include "i915_drv.h" > #include "i915_gem_object.h" > +#include "i915_globals.h" > > static struct i915_global_object { > + struct i915_global base; > struct kmem_cache *slab_objects; > } global; > > @@ -61,6 +63,21 @@ void i915_gem_object_set_cache_coherency(struct drm_i915_gem_object *obj, > !(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_WRITE); > } > > +static void i915_global_objects_shrink(void) > +{ > + kmem_cache_shrink(global.slab_objects); > +} > + > +static void i915_global_objects_exit(void) > +{ > + kmem_cache_destroy(global.slab_objects); > +} > + > +static struct i915_global_object global = { { > + .shrink = i915_global_objects_shrink, > + .exit = i915_global_objects_exit, > +} }; > + > int __init i915_global_objects_init(void) > { > global.slab_objects = > @@ -68,15 +85,6 @@ int __init i915_global_objects_init(void) > if (!global.slab_objects) > return -ENOMEM; > > + i915_global_register(&global.base); > return 0; > } > - > -void i915_global_objects_shrink(void) > -{ > - kmem_cache_shrink(global.slab_objects); > -} > - > -void i915_global_objects_exit(void) > -{ > - kmem_cache_destroy(global.slab_objects); > -} > diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h > index 0eaa2b3aeb62..75d49fe12d18 100644 > --- a/drivers/gpu/drm/i915/i915_gem_object.h > +++ b/drivers/gpu/drm/i915/i915_gem_object.h > @@ -503,7 +503,5 @@ void i915_gem_object_set_cache_coherency(struct drm_i915_gem_object *obj, > void i915_gem_object_flush_if_display(struct drm_i915_gem_object *obj); > > int i915_global_objects_init(void); > -void i915_global_objects_shrink(void); > -void i915_global_objects_exit(void); > > #endif > diff --git a/drivers/gpu/drm/i915/i915_globals.c b/drivers/gpu/drm/i915/i915_globals.c > index cfd0bc462f58..383b43d86e71 100644 > --- a/drivers/gpu/drm/i915/i915_globals.c > +++ b/drivers/gpu/drm/i915/i915_globals.c > @@ -15,62 +15,70 @@ > #include "i915_scheduler.h" > #include "i915_vma.h" > > +static LIST_HEAD(globals); > + > +void __init i915_global_register(struct i915_global *global) > +{ > + GEM_BUG_ON(!global->shrink); > + GEM_BUG_ON(!global->exit); > + > + list_add_tail(&global->link, &globals); > +} > + > +static void __i915_globals_cleanup(void) > +{ > + struct i915_global *global, *next; > + > + list_for_each_entry_safe_reverse(global, next, &globals, link) > + global->exit(); > +} > + > int __init i915_globals_init(void) > { > int err; > > err = i915_global_active_init(); > if (err) > - return err; > + goto err; > > err = i915_global_context_init(); > if (err) > - goto err_active; > + goto err; > > err = i915_global_objects_init(); > if (err) > - goto err_context; > + goto err; > > err = i915_global_request_init(); > if (err) > - goto err_objects; > + goto err; > > err = i915_global_scheduler_init(); > if (err) > - goto err_request; > + goto err; > > err = i915_global_vma_init(); > if (err) > - goto err_scheduler; > + goto err; > > return 0; > > -err_scheduler: > - i915_global_scheduler_exit(); > -err_request: > - i915_global_request_exit(); > -err_objects: > - i915_global_objects_exit(); > -err_context: > - i915_global_context_exit(); > -err_active: > - i915_global_active_exit(); > +err: > + __i915_globals_cleanup(); > return err; > } > > static void i915_globals_shrink(void) > { > + struct i915_global *global; > + > /* > * kmem_cache_shrink() discards empty slabs and reorders partially > * filled slabs to prioritise allocating from the mostly full slabs, > * with the aim of reducing fragmentation. > */ > - i915_global_active_shrink(); > - i915_global_context_shrink(); > - i915_global_objects_shrink(); > - i915_global_request_shrink(); > - i915_global_scheduler_shrink(); > - i915_global_vma_shrink(); > + list_for_each_entry(global, &globals, link) > + global->shrink(); > } > > static atomic_t active; > @@ -128,12 +136,7 @@ void __exit i915_globals_exit(void) > rcu_barrier(); > flush_scheduled_work(); > > - i915_global_vma_exit(); > - i915_global_scheduler_exit(); > - i915_global_request_exit(); > - i915_global_objects_exit(); > - i915_global_context_exit(); > - i915_global_active_exit(); > + __i915_globals_cleanup(); > > /* And ensure that our DESTROY_BY_RCU slabs are truly destroyed */ > rcu_barrier(); > diff --git a/drivers/gpu/drm/i915/i915_globals.h b/drivers/gpu/drm/i915/i915_globals.h > index e468f0413a73..b924ec8d1156 100644 > --- a/drivers/gpu/drm/i915/i915_globals.h > +++ b/drivers/gpu/drm/i915/i915_globals.h > @@ -7,6 +7,17 @@ > #ifndef _I915_GLOBALS_H_ > #define _I915_GLOBALS_H_ > > +typedef void (*i915_global_func_t)(void); > + > +struct i915_global { > + struct list_head link; > + > + i915_global_func_t shrink; > + i915_global_func_t exit; > +}; > + > +void i915_global_register(struct i915_global *global); > + > int i915_globals_init(void); > void i915_globals_park(void); > void i915_globals_unpark(void); > diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c > index bcf3c1a155e2..f8a63495114c 100644 > --- a/drivers/gpu/drm/i915/i915_request.c > +++ b/drivers/gpu/drm/i915/i915_request.c > @@ -31,6 +31,7 @@ > > #include "i915_drv.h" > #include "i915_active.h" > +#include "i915_globals.h" > #include "i915_reset.h" > > struct execute_cb { > @@ -40,6 +41,7 @@ struct execute_cb { > }; > > static struct i915_global_request { > + struct i915_global base; > struct kmem_cache *slab_requests; > struct kmem_cache *slab_dependencies; > struct kmem_cache *slab_execute_cbs; > @@ -1338,6 +1340,25 @@ void i915_retire_requests(struct drm_i915_private *i915) > #include "selftests/i915_request.c" > #endif > > +static void i915_global_request_shrink(void) > +{ > + kmem_cache_shrink(global.slab_dependencies); > + kmem_cache_shrink(global.slab_execute_cbs); > + kmem_cache_shrink(global.slab_requests); > +} > + > +static void i915_global_request_exit(void) > +{ > + kmem_cache_destroy(global.slab_dependencies); > + kmem_cache_destroy(global.slab_execute_cbs); > + kmem_cache_destroy(global.slab_requests); > +} > + > +static struct i915_global_request global = { { > + .shrink = i915_global_request_shrink, > + .exit = i915_global_request_exit, > +} }; > + > int __init i915_global_request_init(void) > { > global.slab_requests = KMEM_CACHE(i915_request, > @@ -1360,6 +1381,7 @@ int __init i915_global_request_init(void) > if (!global.slab_dependencies) > goto err_execute_cbs; > > + i915_global_register(&global.base); > return 0; > > err_execute_cbs: > @@ -1368,17 +1390,3 @@ int __init i915_global_request_init(void) > 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_execute_cbs); > - kmem_cache_shrink(global.slab_requests); > -} > - > -void i915_global_request_exit(void) > -{ > - kmem_cache_destroy(global.slab_dependencies); > - kmem_cache_destroy(global.slab_execute_cbs); > - 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 4dd1dea1d1af..15a46b6cd5ec 100644 > --- a/drivers/gpu/drm/i915/i915_request.h > +++ b/drivers/gpu/drm/i915/i915_request.h > @@ -407,7 +407,5 @@ static inline void i915_request_mark_complete(struct i915_request *rq) > void i915_retire_requests(struct drm_i915_private *i915); > > 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 3f0a4d56bd37..e0f609d01564 100644 > --- a/drivers/gpu/drm/i915/i915_scheduler.c > +++ b/drivers/gpu/drm/i915/i915_scheduler.c > @@ -7,10 +7,12 @@ > #include <linux/mutex.h> > > #include "i915_drv.h" > +#include "i915_globals.h" > #include "i915_request.h" > #include "i915_scheduler.h" > > static struct i915_global_scheduler { > + struct i915_global base; > struct kmem_cache *slab_dependencies; > struct kmem_cache *slab_priorities; > } global; > @@ -437,6 +439,23 @@ void __i915_priolist_free(struct i915_priolist *p) > kmem_cache_free(global.slab_priorities, p); > } > > +static void i915_global_scheduler_shrink(void) > +{ > + kmem_cache_shrink(global.slab_dependencies); > + kmem_cache_shrink(global.slab_priorities); > +} > + > +static void i915_global_scheduler_exit(void) > +{ > + kmem_cache_destroy(global.slab_dependencies); > + kmem_cache_destroy(global.slab_priorities); > +} > + > +static struct i915_global_scheduler global = { { > + .shrink = i915_global_scheduler_shrink, > + .exit = i915_global_scheduler_exit, > +} }; > + > int __init i915_global_scheduler_init(void) > { > global.slab_dependencies = KMEM_CACHE(i915_dependency, > @@ -449,21 +468,10 @@ int __init i915_global_scheduler_init(void) > if (!global.slab_priorities) > goto err_priorities; > > + i915_global_register(&global.base); > 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 6ce450cf63fa..544709019d48 100644 > --- a/drivers/gpu/drm/i915/i915_scheduler.h > +++ b/drivers/gpu/drm/i915/i915_scheduler.h > @@ -135,7 +135,5 @@ static inline void i915_priolist_free(struct i915_priolist *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/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c > index 757a33998bbf..36726392e737 100644 > --- a/drivers/gpu/drm/i915/i915_vma.c > +++ b/drivers/gpu/drm/i915/i915_vma.c > @@ -25,12 +25,14 @@ > #include "i915_vma.h" > > #include "i915_drv.h" > +#include "i915_globals.h" > #include "intel_ringbuffer.h" > #include "intel_frontbuffer.h" > > #include <drm/drm_gem.h> > > static struct i915_global_vma { > + struct i915_global base; > struct kmem_cache *slab_vmas; > } global; > > @@ -1054,21 +1056,27 @@ int i915_vma_unbind(struct i915_vma *vma) > #include "selftests/i915_vma.c" > #endif > > -int __init i915_global_vma_init(void) > +static void i915_global_vma_shrink(void) > { > - global.slab_vmas = KMEM_CACHE(i915_vma, SLAB_HWCACHE_ALIGN); > - if (!global.slab_vmas) > - return -ENOMEM; > - > - return 0; > + kmem_cache_shrink(global.slab_vmas); > } > > -void i915_global_vma_shrink(void) > +static void i915_global_vma_exit(void) > { > - kmem_cache_shrink(global.slab_vmas); > + kmem_cache_destroy(global.slab_vmas); > } > > -void i915_global_vma_exit(void) > +static struct i915_global_vma global = { { > + .shrink = i915_global_vma_shrink, > + .exit = i915_global_vma_exit, > +} }; > + > +int __init i915_global_vma_init(void) > { > - kmem_cache_destroy(global.slab_vmas); > + global.slab_vmas = KMEM_CACHE(i915_vma, SLAB_HWCACHE_ALIGN); > + if (!global.slab_vmas) > + return -ENOMEM; > + > + i915_global_register(&global.base); > + return 0; > } > diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h > index 37f93358aa3c..3c3de52cc0d7 100644 > --- a/drivers/gpu/drm/i915/i915_vma.h > +++ b/drivers/gpu/drm/i915/i915_vma.h > @@ -444,7 +444,5 @@ struct i915_vma *i915_vma_alloc(void); > void i915_vma_free(struct i915_vma *vma); > > int i915_global_vma_init(void); > -void i915_global_vma_shrink(void); > -void i915_global_vma_exit(void); > > #endif > Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Regards, Tvrtko
diff --git a/drivers/gpu/drm/i915/i915_active.c b/drivers/gpu/drm/i915/i915_active.c index d9f6471ac16c..863ae12707ba 100644 --- a/drivers/gpu/drm/i915/i915_active.c +++ b/drivers/gpu/drm/i915/i915_active.c @@ -6,6 +6,7 @@ #include "i915_drv.h" #include "i915_active.h" +#include "i915_globals.h" #define BKL(ref) (&(ref)->i915->drm.struct_mutex) @@ -17,6 +18,7 @@ * nodes from a local slab cache to hopefully reduce the fragmentation. */ static struct i915_global_active { + struct i915_global base; struct kmem_cache *slab_cache; } global; @@ -285,21 +287,27 @@ void i915_active_retire_noop(struct i915_active_request *active, #include "selftests/i915_active.c" #endif -int __init i915_global_active_init(void) +static void i915_global_active_shrink(void) { - global.slab_cache = KMEM_CACHE(active_node, SLAB_HWCACHE_ALIGN); - if (!global.slab_cache) - return -ENOMEM; - - return 0; + kmem_cache_shrink(global.slab_cache); } -void i915_global_active_shrink(void) +static void i915_global_active_exit(void) { - kmem_cache_shrink(global.slab_cache); + kmem_cache_destroy(global.slab_cache); } -void i915_global_active_exit(void) +static struct i915_global_active global = { { + .shrink = i915_global_active_shrink, + .exit = i915_global_active_exit, +} }; + +int __init i915_global_active_init(void) { - kmem_cache_destroy(global.slab_cache); + global.slab_cache = KMEM_CACHE(active_node, SLAB_HWCACHE_ALIGN); + if (!global.slab_cache) + return -ENOMEM; + + i915_global_register(&global.base); + return 0; } diff --git a/drivers/gpu/drm/i915/i915_active.h b/drivers/gpu/drm/i915/i915_active.h index 5fbd9102384b..575c01846875 100644 --- a/drivers/gpu/drm/i915/i915_active.h +++ b/drivers/gpu/drm/i915/i915_active.h @@ -420,7 +420,5 @@ 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_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 1e3211e909f1..b9f321947982 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -88,6 +88,7 @@ #include <linux/log2.h> #include <drm/i915_drm.h> #include "i915_drv.h" +#include "i915_globals.h" #include "i915_trace.h" #include "intel_lrc_reg.h" #include "intel_workarounds.h" @@ -95,6 +96,7 @@ #define ALL_L3_SLICES(dev) (1 << NUM_L3_SLICES(dev)) - 1 static struct i915_global_context { + struct i915_global base; struct kmem_cache *slab_luts; } global; @@ -1423,21 +1425,27 @@ int __i915_gem_context_pin_hw_id(struct i915_gem_context *ctx) #include "selftests/i915_gem_context.c" #endif -int __init i915_global_context_init(void) +static void i915_global_context_shrink(void) { - global.slab_luts = KMEM_CACHE(i915_lut_handle, 0); - if (!global.slab_luts) - return -ENOMEM; - - return 0; + kmem_cache_shrink(global.slab_luts); } -void i915_global_context_shrink(void) +static void i915_global_context_exit(void) { - kmem_cache_shrink(global.slab_luts); + kmem_cache_destroy(global.slab_luts); } -void i915_global_context_exit(void) +static struct i915_global_context global = { { + .shrink = i915_global_context_shrink, + .exit = i915_global_context_exit, +} }; + +int __init i915_global_context_init(void) { - kmem_cache_destroy(global.slab_luts); + global.slab_luts = KMEM_CACHE(i915_lut_handle, 0); + if (!global.slab_luts) + return -ENOMEM; + + i915_global_register(&global.base); + return 0; } diff --git a/drivers/gpu/drm/i915/i915_gem_context.h b/drivers/gpu/drm/i915/i915_gem_context.h index be63666ffaac..b59107248b54 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.h +++ b/drivers/gpu/drm/i915/i915_gem_context.h @@ -412,7 +412,5 @@ struct i915_lut_handle *i915_lut_handle_alloc(void); void i915_lut_handle_free(struct i915_lut_handle *lut); int i915_global_context_init(void); -void i915_global_context_shrink(void); -void i915_global_context_exit(void); #endif /* !__I915_GEM_CONTEXT_H__ */ diff --git a/drivers/gpu/drm/i915/i915_gem_object.c b/drivers/gpu/drm/i915/i915_gem_object.c index 4aeb8c3b87e4..ac6a5ab84586 100644 --- a/drivers/gpu/drm/i915/i915_gem_object.c +++ b/drivers/gpu/drm/i915/i915_gem_object.c @@ -24,8 +24,10 @@ #include "i915_drv.h" #include "i915_gem_object.h" +#include "i915_globals.h" static struct i915_global_object { + struct i915_global base; struct kmem_cache *slab_objects; } global; @@ -61,6 +63,21 @@ void i915_gem_object_set_cache_coherency(struct drm_i915_gem_object *obj, !(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_WRITE); } +static void i915_global_objects_shrink(void) +{ + kmem_cache_shrink(global.slab_objects); +} + +static void i915_global_objects_exit(void) +{ + kmem_cache_destroy(global.slab_objects); +} + +static struct i915_global_object global = { { + .shrink = i915_global_objects_shrink, + .exit = i915_global_objects_exit, +} }; + int __init i915_global_objects_init(void) { global.slab_objects = @@ -68,15 +85,6 @@ int __init i915_global_objects_init(void) if (!global.slab_objects) return -ENOMEM; + i915_global_register(&global.base); return 0; } - -void i915_global_objects_shrink(void) -{ - kmem_cache_shrink(global.slab_objects); -} - -void i915_global_objects_exit(void) -{ - kmem_cache_destroy(global.slab_objects); -} diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h index 0eaa2b3aeb62..75d49fe12d18 100644 --- a/drivers/gpu/drm/i915/i915_gem_object.h +++ b/drivers/gpu/drm/i915/i915_gem_object.h @@ -503,7 +503,5 @@ void i915_gem_object_set_cache_coherency(struct drm_i915_gem_object *obj, void i915_gem_object_flush_if_display(struct drm_i915_gem_object *obj); int i915_global_objects_init(void); -void i915_global_objects_shrink(void); -void i915_global_objects_exit(void); #endif diff --git a/drivers/gpu/drm/i915/i915_globals.c b/drivers/gpu/drm/i915/i915_globals.c index cfd0bc462f58..383b43d86e71 100644 --- a/drivers/gpu/drm/i915/i915_globals.c +++ b/drivers/gpu/drm/i915/i915_globals.c @@ -15,62 +15,70 @@ #include "i915_scheduler.h" #include "i915_vma.h" +static LIST_HEAD(globals); + +void __init i915_global_register(struct i915_global *global) +{ + GEM_BUG_ON(!global->shrink); + GEM_BUG_ON(!global->exit); + + list_add_tail(&global->link, &globals); +} + +static void __i915_globals_cleanup(void) +{ + struct i915_global *global, *next; + + list_for_each_entry_safe_reverse(global, next, &globals, link) + global->exit(); +} + int __init i915_globals_init(void) { int err; err = i915_global_active_init(); if (err) - return err; + goto err; err = i915_global_context_init(); if (err) - goto err_active; + goto err; err = i915_global_objects_init(); if (err) - goto err_context; + goto err; err = i915_global_request_init(); if (err) - goto err_objects; + goto err; err = i915_global_scheduler_init(); if (err) - goto err_request; + goto err; err = i915_global_vma_init(); if (err) - goto err_scheduler; + goto err; return 0; -err_scheduler: - i915_global_scheduler_exit(); -err_request: - i915_global_request_exit(); -err_objects: - i915_global_objects_exit(); -err_context: - i915_global_context_exit(); -err_active: - i915_global_active_exit(); +err: + __i915_globals_cleanup(); return err; } static void i915_globals_shrink(void) { + struct i915_global *global; + /* * kmem_cache_shrink() discards empty slabs and reorders partially * filled slabs to prioritise allocating from the mostly full slabs, * with the aim of reducing fragmentation. */ - i915_global_active_shrink(); - i915_global_context_shrink(); - i915_global_objects_shrink(); - i915_global_request_shrink(); - i915_global_scheduler_shrink(); - i915_global_vma_shrink(); + list_for_each_entry(global, &globals, link) + global->shrink(); } static atomic_t active; @@ -128,12 +136,7 @@ void __exit i915_globals_exit(void) rcu_barrier(); flush_scheduled_work(); - i915_global_vma_exit(); - i915_global_scheduler_exit(); - i915_global_request_exit(); - i915_global_objects_exit(); - i915_global_context_exit(); - i915_global_active_exit(); + __i915_globals_cleanup(); /* And ensure that our DESTROY_BY_RCU slabs are truly destroyed */ rcu_barrier(); diff --git a/drivers/gpu/drm/i915/i915_globals.h b/drivers/gpu/drm/i915/i915_globals.h index e468f0413a73..b924ec8d1156 100644 --- a/drivers/gpu/drm/i915/i915_globals.h +++ b/drivers/gpu/drm/i915/i915_globals.h @@ -7,6 +7,17 @@ #ifndef _I915_GLOBALS_H_ #define _I915_GLOBALS_H_ +typedef void (*i915_global_func_t)(void); + +struct i915_global { + struct list_head link; + + i915_global_func_t shrink; + i915_global_func_t exit; +}; + +void i915_global_register(struct i915_global *global); + int i915_globals_init(void); void i915_globals_park(void); void i915_globals_unpark(void); diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index bcf3c1a155e2..f8a63495114c 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c @@ -31,6 +31,7 @@ #include "i915_drv.h" #include "i915_active.h" +#include "i915_globals.h" #include "i915_reset.h" struct execute_cb { @@ -40,6 +41,7 @@ struct execute_cb { }; static struct i915_global_request { + struct i915_global base; struct kmem_cache *slab_requests; struct kmem_cache *slab_dependencies; struct kmem_cache *slab_execute_cbs; @@ -1338,6 +1340,25 @@ void i915_retire_requests(struct drm_i915_private *i915) #include "selftests/i915_request.c" #endif +static void i915_global_request_shrink(void) +{ + kmem_cache_shrink(global.slab_dependencies); + kmem_cache_shrink(global.slab_execute_cbs); + kmem_cache_shrink(global.slab_requests); +} + +static void i915_global_request_exit(void) +{ + kmem_cache_destroy(global.slab_dependencies); + kmem_cache_destroy(global.slab_execute_cbs); + kmem_cache_destroy(global.slab_requests); +} + +static struct i915_global_request global = { { + .shrink = i915_global_request_shrink, + .exit = i915_global_request_exit, +} }; + int __init i915_global_request_init(void) { global.slab_requests = KMEM_CACHE(i915_request, @@ -1360,6 +1381,7 @@ int __init i915_global_request_init(void) if (!global.slab_dependencies) goto err_execute_cbs; + i915_global_register(&global.base); return 0; err_execute_cbs: @@ -1368,17 +1390,3 @@ int __init i915_global_request_init(void) 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_execute_cbs); - kmem_cache_shrink(global.slab_requests); -} - -void i915_global_request_exit(void) -{ - kmem_cache_destroy(global.slab_dependencies); - kmem_cache_destroy(global.slab_execute_cbs); - 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 4dd1dea1d1af..15a46b6cd5ec 100644 --- a/drivers/gpu/drm/i915/i915_request.h +++ b/drivers/gpu/drm/i915/i915_request.h @@ -407,7 +407,5 @@ static inline void i915_request_mark_complete(struct i915_request *rq) void i915_retire_requests(struct drm_i915_private *i915); 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 3f0a4d56bd37..e0f609d01564 100644 --- a/drivers/gpu/drm/i915/i915_scheduler.c +++ b/drivers/gpu/drm/i915/i915_scheduler.c @@ -7,10 +7,12 @@ #include <linux/mutex.h> #include "i915_drv.h" +#include "i915_globals.h" #include "i915_request.h" #include "i915_scheduler.h" static struct i915_global_scheduler { + struct i915_global base; struct kmem_cache *slab_dependencies; struct kmem_cache *slab_priorities; } global; @@ -437,6 +439,23 @@ void __i915_priolist_free(struct i915_priolist *p) kmem_cache_free(global.slab_priorities, p); } +static void i915_global_scheduler_shrink(void) +{ + kmem_cache_shrink(global.slab_dependencies); + kmem_cache_shrink(global.slab_priorities); +} + +static void i915_global_scheduler_exit(void) +{ + kmem_cache_destroy(global.slab_dependencies); + kmem_cache_destroy(global.slab_priorities); +} + +static struct i915_global_scheduler global = { { + .shrink = i915_global_scheduler_shrink, + .exit = i915_global_scheduler_exit, +} }; + int __init i915_global_scheduler_init(void) { global.slab_dependencies = KMEM_CACHE(i915_dependency, @@ -449,21 +468,10 @@ int __init i915_global_scheduler_init(void) if (!global.slab_priorities) goto err_priorities; + i915_global_register(&global.base); 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 6ce450cf63fa..544709019d48 100644 --- a/drivers/gpu/drm/i915/i915_scheduler.h +++ b/drivers/gpu/drm/i915/i915_scheduler.h @@ -135,7 +135,5 @@ static inline void i915_priolist_free(struct i915_priolist *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/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 757a33998bbf..36726392e737 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -25,12 +25,14 @@ #include "i915_vma.h" #include "i915_drv.h" +#include "i915_globals.h" #include "intel_ringbuffer.h" #include "intel_frontbuffer.h" #include <drm/drm_gem.h> static struct i915_global_vma { + struct i915_global base; struct kmem_cache *slab_vmas; } global; @@ -1054,21 +1056,27 @@ int i915_vma_unbind(struct i915_vma *vma) #include "selftests/i915_vma.c" #endif -int __init i915_global_vma_init(void) +static void i915_global_vma_shrink(void) { - global.slab_vmas = KMEM_CACHE(i915_vma, SLAB_HWCACHE_ALIGN); - if (!global.slab_vmas) - return -ENOMEM; - - return 0; + kmem_cache_shrink(global.slab_vmas); } -void i915_global_vma_shrink(void) +static void i915_global_vma_exit(void) { - kmem_cache_shrink(global.slab_vmas); + kmem_cache_destroy(global.slab_vmas); } -void i915_global_vma_exit(void) +static struct i915_global_vma global = { { + .shrink = i915_global_vma_shrink, + .exit = i915_global_vma_exit, +} }; + +int __init i915_global_vma_init(void) { - kmem_cache_destroy(global.slab_vmas); + global.slab_vmas = KMEM_CACHE(i915_vma, SLAB_HWCACHE_ALIGN); + if (!global.slab_vmas) + return -ENOMEM; + + i915_global_register(&global.base); + return 0; } diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h index 37f93358aa3c..3c3de52cc0d7 100644 --- a/drivers/gpu/drm/i915/i915_vma.h +++ b/drivers/gpu/drm/i915/i915_vma.h @@ -444,7 +444,5 @@ struct i915_vma *i915_vma_alloc(void); void i915_vma_free(struct i915_vma *vma); int i915_global_vma_init(void); -void i915_global_vma_shrink(void); -void i915_global_vma_exit(void); #endif
Rather than manually add every new global into each hook, use i915_global_register() function and keep a list of registered globals to invoke instead. However, I haven't found a way for random drivers to add an .init table to avoid having to manually add ourselves to i915_globals_init() each time. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> --- drivers/gpu/drm/i915/i915_active.c | 28 +++++++----- drivers/gpu/drm/i915/i915_active.h | 2 - drivers/gpu/drm/i915/i915_gem_context.c | 28 +++++++----- drivers/gpu/drm/i915/i915_gem_context.h | 2 - drivers/gpu/drm/i915/i915_gem_object.c | 28 +++++++----- drivers/gpu/drm/i915/i915_gem_object.h | 2 - drivers/gpu/drm/i915/i915_globals.c | 59 +++++++++++++------------ drivers/gpu/drm/i915/i915_globals.h | 11 +++++ drivers/gpu/drm/i915/i915_request.c | 36 +++++++++------ drivers/gpu/drm/i915/i915_request.h | 2 - drivers/gpu/drm/i915/i915_scheduler.c | 32 +++++++++----- drivers/gpu/drm/i915/i915_scheduler.h | 2 - drivers/gpu/drm/i915/i915_vma.c | 28 +++++++----- drivers/gpu/drm/i915/i915_vma.h | 2 - 14 files changed, 156 insertions(+), 106 deletions(-)