Before this commit, drmcg limits are updated but enforcement is delayed
until the next time the driver check against the new limit.  While this
is sufficient for certain resources, a more proactive enforcement may be
needed for other resources.

Introducing an optional drmcg_limit_updated callback for the DRM
drivers.  When defined, it will be called in two scenarios:
1) When limits are updated for a particular cgroup, the callback will be
triggered for each task in the updated cgroup.
2) When a task is migrated from one cgroup to another, the callback will
be triggered for each resource type for the migrated task.

Change-Id: I68187a72818b855b5f295aefcb241cda8ab63b00
Signed-off-by: Kenny Ho <kenny...@amd.com>
---
 include/drm/drm_drv.h | 10 ++++++++
 kernel/cgroup/drm.c   | 57 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+)

diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index c8a37a08d98d..7e588b874a27 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -669,6 +669,16 @@ struct drm_driver {
        void (*drmcg_custom_init)(struct drm_device *dev,
                        struct drmcg_props *props);
 
+       /**
+        * @drmcg_limit_updated
+        *
+        * Optional callback
+        */
+       void (*drmcg_limit_updated)(struct drm_device *dev,
+                       struct task_struct *task,\
+                       struct drmcg_device_resource *ddr,
+                       enum drmcg_res_type res_type);
+
        /**
         * @gem_vm_ops: Driver private ops for this object
         */
diff --git a/kernel/cgroup/drm.c b/kernel/cgroup/drm.c
index 18c4368e2c29..99772e5d9ccc 100644
--- a/kernel/cgroup/drm.c
+++ b/kernel/cgroup/drm.c
@@ -621,6 +621,23 @@ static void drmcg_nested_limit_parse(struct 
kernfs_open_file *of,
        }
 }
 
+static void drmcg_limit_updated(struct drm_device *dev, struct drmcg *drmcg,
+               enum drmcg_res_type res_type)
+{
+       struct drmcg_device_resource *ddr =
+               drmcg->dev_resources[dev->primary->index];
+       struct css_task_iter it;
+       struct task_struct *task;
+
+       css_task_iter_start(&drmcg->css.cgroup->self,
+                       CSS_TASK_ITER_PROCS, &it);
+       while ((task = css_task_iter_next(&it))) {
+               dev->driver->drmcg_limit_updated(dev, task,
+                               ddr, res_type);
+       }
+       css_task_iter_end(&it);
+}
+
 static ssize_t drmcg_limit_write(struct kernfs_open_file *of, char *buf,
                size_t nbytes, loff_t off)
 {
@@ -726,6 +743,10 @@ static ssize_t drmcg_limit_write(struct kernfs_open_file 
*of, char *buf,
                default:
                        break;
                }
+
+               if (dm->dev->driver->drmcg_limit_updated)
+                       drmcg_limit_updated(dm->dev, drmcg, type);
+
                drm_dev_put(dm->dev); /* release from drm_minor_acquire */
        }
 
@@ -863,9 +884,45 @@ struct cftype files[] = {
        { }     /* terminate */
 };
 
+static int drmcg_attach_fn(int id, void *ptr, void *data)
+{
+       struct drm_minor *minor = ptr;
+       struct task_struct *task = data;
+       struct drm_device *dev;
+
+       if (minor->type != DRM_MINOR_PRIMARY)
+               return 0;
+
+       dev = minor->dev;
+
+       if (dev->driver->drmcg_limit_updated) {
+               struct drmcg *drmcg = drmcg_get(task);
+               struct drmcg_device_resource *ddr =
+                       drmcg->dev_resources[minor->index];
+               enum drmcg_res_type type;
+
+               for (type = 0; type < __DRMCG_TYPE_LAST; type++)
+                       dev->driver->drmcg_limit_updated(dev, task, ddr, type);
+
+               drmcg_put(drmcg);
+       }
+
+       return 0;
+}
+
+static void drmcg_attach(struct cgroup_taskset *tset)
+{
+       struct task_struct *task;
+       struct cgroup_subsys_state *css;
+
+       cgroup_taskset_for_each(task, css, tset)
+               drm_minor_for_each(&drmcg_attach_fn, task);
+}
+
 struct cgroup_subsys drm_cgrp_subsys = {
        .css_alloc      = drmcg_css_alloc,
        .css_free       = drmcg_css_free,
+       .attach         = drmcg_attach,
        .early_init     = false,
        .legacy_cftypes = files,
        .dfl_cftypes    = files,
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to