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

Reply via email to