[RFC 21/23] drm/sched: Add helper for tracking entities per client
Tvrtko Ursulin
tvrtko.ursulin at igalia.com
Fri May 2 12:32:54 UTC 2025
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.ursulin at 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
More information about the amd-gfx
mailing list