To enable adding DRM cgroup support to the DRM scheduler we need a way for updating the relative scheduling weights per entity at the point the controller invokes a call-back notifying the driver of a new relative scheduling weight for a client.
We add two helpers which will allow drivers to opt-in into the tracking and they are responsible to call them at the correct times respective to the entity lifetime. Signed-off-by: Tvrtko Ursulin <tvrtko.ursu...@igalia.com> --- drivers/gpu/drm/drm_file.c | 3 ++ drivers/gpu/drm/scheduler/sched_entity.c | 25 ++++++++++++++++ include/drm/drm_file.h | 5 ++++ include/drm/gpu_scheduler.h | 38 ++++++++++++++++++++++++ 4 files changed, 71 insertions(+) diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c index 7500b2b14fd5..9d6ec64e58ad 100644 --- a/drivers/gpu/drm/drm_file.c +++ b/drivers/gpu/drm/drm_file.c @@ -46,6 +46,7 @@ #include <drm/drm_file.h> #include <drm/drm_gem.h> #include <drm/drm_print.h> +#include <drm/gpu_scheduler.h> #include "drm_crtc_internal.h" #include "drm_internal.h" @@ -160,6 +161,8 @@ struct drm_file *drm_file_alloc(struct drm_minor *minor) mutex_init(&file->event_read_lock); mutex_init(&file->client_name_lock); + drm_sched_cgroup_init_drm_file(file); + if (drm_core_check_feature(dev, DRIVER_GEM)) drm_gem_open(dev, file); diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c index bc890f735552..8729d3068449 100644 --- a/drivers/gpu/drm/scheduler/sched_entity.c +++ b/drivers/gpu/drm/scheduler/sched_entity.c @@ -25,6 +25,7 @@ #include <linux/slab.h> #include <linux/completion.h> +#include <drm/drm_file.h> #include <drm/drm_print.h> #include <drm/gpu_scheduler.h> @@ -121,6 +122,10 @@ int drm_sched_entity_init(struct drm_sched_entity *entity, atomic_set(&entity->fence_seq, 0); entity->fence_context = dma_fence_context_alloc(2); +#if IS_ENABLED(CONFIG_CGROUP_DRM) + INIT_LIST_HEAD(&entity->drm_file_link); +#endif + return 0; } EXPORT_SYMBOL(drm_sched_entity_init); @@ -603,3 +608,23 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job) } } EXPORT_SYMBOL(drm_sched_entity_push_job); + +#if IS_ENABLED(CONFIG_CGROUP_DRM) +void drm_sched_cgroup_track_sched_entity(struct drm_file *file_priv, + struct drm_sched_entity *entity) +{ + spin_lock(&file_priv->sched_entities.lock); + list_add_tail(&entity->drm_file_link, &file_priv->sched_entities.list); + spin_unlock(&file_priv->sched_entities.lock); +} +EXPORT_SYMBOL(drm_sched_cgroup_track_sched_entity); + +void drm_sched_cgroup_untrack_sched_entity(struct drm_file *file_priv, + struct drm_sched_entity *entity) +{ + spin_lock(&file_priv->sched_entities.lock); + list_del(&entity->drm_file_link); + spin_unlock(&file_priv->sched_entities.lock); +} +EXPORT_SYMBOL(drm_sched_cgroup_untrack_sched_entity); +#endif diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h index 76b194c0fc52..cb6775af337b 100644 --- a/include/drm/drm_file.h +++ b/include/drm/drm_file.h @@ -299,6 +299,11 @@ struct drm_file { #if IS_ENABLED(CONFIG_CGROUP_DRM) struct cgroup_subsys_state *__css; struct list_head clink; + + struct { + spinlock_t lock; + struct list_head list; + } sched_entities; #endif /** diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h index fd488ccece9a..efd00059a814 100644 --- a/include/drm/gpu_scheduler.h +++ b/include/drm/gpu_scheduler.h @@ -237,6 +237,9 @@ struct drm_sched_entity { */ struct rb_node rb_tree_node; +#if IS_ENABLED(CONFIG_CGROUP_DRM) + struct list_head drm_file_link; +#endif }; /** @@ -665,4 +668,39 @@ void drm_sched_entity_modify_sched(struct drm_sched_entity *entity, struct drm_gpu_scheduler **sched_list, unsigned int num_sched_list); +#if IS_ENABLED(CONFIG_CGROUP_DRM) +#include <linux/list.h> +#include <linux/spinlock.h> + +#include <drm/drm_file.h> + +/* Static inline to allow drm.ko and gpu-sched.ko as modules. */ +static inline void drm_sched_cgroup_init_drm_file(struct drm_file *file_priv) +{ + spin_lock_init(&file_priv->sched_entities.lock); + INIT_LIST_HEAD(&file_priv->sched_entities.list); +} + +void drm_sched_cgroup_track_sched_entity(struct drm_file *file_priv, + struct drm_sched_entity *entity); +void drm_sched_cgroup_untrack_sched_entity(struct drm_file *file_priv, + struct drm_sched_entity *entity); +#else +static inline void drm_sched_cgroup_init_drm_file(struct drm_file *file_priv) +{ +} + +static inline void +drm_sched_cgroup_track_sched_entity(struct drm_file *file_priv, + struct drm_sched_entity *entity) +{ +} + +static inline void +drm_sched_cgroup_untrack_sched_entity(struct drm_file *file_priv, + struct drm_sched_entity *entity) +{ +} +#endif + #endif -- 2.48.0