Am 20.11.18 um 19:58 schrieb Kenny Ho:
Since many parts of the DRM subsystem has vendor-specific
implementations, we introduce mechanisms for vendor to register their
specific resources and control files to the DRM cgroup subsystem. A
vendor will register itself with the DRM cgroup subsystem first before
registering individual DRM devices to the cgroup subsystem.
In addition to the cgroup_subsys_state that is common to all DRM
devices, a device-specific state is introduced and it is allocated
according to the vendor of the device.
Mhm, it's most likely just a naming issue but I think we should drop the
term "vendor" here and rather use "driver" instead.
Background is that both Intel as well as AMD have multiple drivers for
different hardware generations and we certainly don't want to handle all
drivers from one vendor the same way.
Christian.
Change-Id: I908ee6975ea0585e4c30eafde4599f87094d8c65
Signed-off-by: Kenny Ho <Kenny.Ho@xxxxxxx>
---
include/drm/drm_cgroup.h | 39 ++++++++++++++++
include/drm/drmcgrp_vendors.h | 7 +++
include/linux/cgroup_drm.h | 26 +++++++++++
kernel/cgroup/drm.c | 84 +++++++++++++++++++++++++++++++++++
4 files changed, 156 insertions(+)
create mode 100644 include/drm/drm_cgroup.h
create mode 100644 include/drm/drmcgrp_vendors.h
diff --git a/include/drm/drm_cgroup.h b/include/drm/drm_cgroup.h
new file mode 100644
index 000000000000..26cbea7059a6
--- /dev/null
+++ b/include/drm/drm_cgroup.h
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: MIT
+ * Copyright 2018 Advanced Micro Devices, Inc.
+ */
+#ifndef __DRM_CGROUP_H__
+#define __DRM_CGROUP_H__
+
+#define DRMCGRP_VENDOR(_x) _x ## _drmcgrp_vendor_id,
+enum drmcgrp_vendor_id {
+#include <drm/drmcgrp_vendors.h>
+ DRMCGRP_VENDOR_COUNT,
+};
+#undef DRMCGRP_VENDOR
+
+#define DRMCGRP_VENDOR(_x) extern struct drmcgrp_vendor _x ## _drmcgrp_vendor;
+#include <drm/drmcgrp_vendors.h>
+#undef DRMCGRP_VENDOR
+
+
+
+#ifdef CONFIG_CGROUP_DRM
+
+extern struct drmcgrp_vendor *drmcgrp_vendors[];
+
+int drmcgrp_register_vendor(struct drmcgrp_vendor *vendor, enum drmcgrp_vendor_id id);
+int drmcgrp_register_device(struct drm_device *device, enum drmcgrp_vendor_id id);
+
+#else
+static int drmcgrp_register_vendor(struct drmcgrp_vendor *vendor, enum drmcgrp_vendor_id id)
+{
+ return 0;
+}
+
+static int drmcgrp_register_device(struct drm_device *device, enum drmcgrp_vendor_id id)
+{
+ return 0;
+}
+
+#endif /* CONFIG_CGROUP_DRM */
+#endif /* __DRM_CGROUP_H__ */
diff --git a/include/drm/drmcgrp_vendors.h b/include/drm/drmcgrp_vendors.h
new file mode 100644
index 000000000000..b04d8649851b
--- /dev/null
+++ b/include/drm/drmcgrp_vendors.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: MIT
+ * Copyright 2018 Advanced Micro Devices, Inc.
+ */
+#if IS_ENABLED(CONFIG_CGROUP_DRM)
+
+
+#endif
diff --git a/include/linux/cgroup_drm.h b/include/linux/cgroup_drm.h
index 79ab38b0f46d..a776662d9593 100644
--- a/include/linux/cgroup_drm.h
+++ b/include/linux/cgroup_drm.h
@@ -6,10 +6,36 @@
#ifdef CONFIG_CGROUP_DRM
+#include <linux/mutex.h>
#include <linux/cgroup.h>
+#include <drm/drm_file.h>
+#include <drm/drm_cgroup.h>
+
+/* limit defined per the way drm_minor_alloc operates */
+#define MAX_DRM_DEV (64 * DRM_MINOR_RENDER)
+
+struct drmcgrp_device {
+ enum drmcgrp_vendor_id vid;
+ struct drm_device *dev;
+ struct mutex mutex;
+};
+
+/* vendor-common resource counting goes here */
+/* this struct should be included in the vendor specific resource */
+struct drmcgrp_device_resource {
+ struct drmcgrp_device *ddev;
+};
+
+struct drmcgrp_vendor {
+ struct cftype *(*get_cftypes)(void);
+ struct drmcgrp_device_resource *(*alloc_dev_resource)(void);
+ void (*free_dev_resource)(struct drmcgrp_device_resource *dev_resource);
+};
+
struct drmcgrp {
struct cgroup_subsys_state css;
+ struct drmcgrp_device_resource *dev_resources[MAX_DRM_DEV];
};
static inline struct drmcgrp *css_drmcgrp(struct cgroup_subsys_state *css)
diff --git a/kernel/cgroup/drm.c b/kernel/cgroup/drm.c
index d9e194b9aead..f9630cc389bc 100644
--- a/kernel/cgroup/drm.c
+++ b/kernel/cgroup/drm.c
@@ -1,8 +1,30 @@
// SPDX-License-Identifier: MIT
// Copyright 2018 Advanced Micro Devices, Inc.
+#include <linux/export.h>
#include <linux/slab.h>
#include <linux/cgroup.h>
+#include <linux/fs.h>
+#include <linux/seq_file.h>
+#include <linux/mutex.h>
#include <linux/cgroup_drm.h>
+#include <drm/drm_device.h>
+#include <drm/drm_cgroup.h>
+
+/* generate an array of drm cgroup vendor pointers */
+#define DRMCGRP_VENDOR(_x)[_x ## _drmcgrp_vendor_id] = NULL,
+struct drmcgrp_vendor *drmcgrp_vendors[] = {
+#include <drm/drmcgrp_vendors.h>
+};
+#undef DRMCGRP_VENDOR
+EXPORT_SYMBOL(drmcgrp_vendors);
+
+static DEFINE_MUTEX(drmcgrp_mutex);
+
+/* indexed by drm_minor for access speed */
+static struct drmcgrp_device *known_drmcgrp_devs[MAX_DRM_DEV];
+
+static int max_minor;
+
static u64 drmcgrp_test_read(struct cgroup_subsys_state *css,
struct cftype *cft)
@@ -13,6 +35,12 @@ static u64 drmcgrp_test_read(struct cgroup_subsys_state *css,
static void drmcgrp_css_free(struct cgroup_subsys_state *css)
{
struct drmcgrp *drmcgrp = css_drmcgrp(css);
+ int i;
+
+ for (i = 0; i <= max_minor; i++) {
+ if (drmcgrp->dev_resources[i] != NULL)
+ drmcgrp_vendors[known_drmcgrp_devs[i]->vid]->free_dev_resource(drmcgrp->dev_resources[i]);
+ }
kfree(css_drmcgrp(css));
}
@@ -21,11 +49,27 @@ static struct cgroup_subsys_state *
drmcgrp_css_alloc(struct cgroup_subsys_state *parent_css)
{
struct drmcgrp *drmcgrp;
+ int i;
drmcgrp = kzalloc(sizeof(struct drmcgrp), GFP_KERNEL);
if (!drmcgrp)
return ERR_PTR(-ENOMEM);
+ for (i = 0; i <= max_minor; i++) {
+ if (known_drmcgrp_devs[i] != NULL) {
+ struct drmcgrp_device_resource *ddr =
+ drmcgrp_vendors[known_drmcgrp_devs[i]->vid]->alloc_dev_resource();
+
+ if (IS_ERR(ddr)) {
+ drmcgrp_css_free(&drmcgrp->css);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ drmcgrp->dev_resources[i] = ddr;
+ drmcgrp->dev_resources[i]->ddev = known_drmcgrp_devs[i];
+ }
+ }
+
return &drmcgrp->css;
}
@@ -44,3 +88,43 @@ struct cgroup_subsys drm_cgrp_subsys = {
.legacy_cftypes = files,
.dfl_cftypes = files,
};
+
+int drmcgrp_register_vendor(struct drmcgrp_vendor *vendor, enum drmcgrp_vendor_id id)
+{
+ int rc = 0;
+ struct cftype *cfts;
+
+ // TODO: root css created before any registration
+ if (drmcgrp_vendors[id] == NULL) {
+ drmcgrp_vendors[id] = vendor;
+ cfts = vendor->get_cftypes();
+ if (cfts != NULL)
+ rc = cgroup_add_legacy_cftypes(&drm_cgrp_subsys, cfts);
+ }
+ return rc;
+}
+EXPORT_SYMBOL(drmcgrp_register_vendor);
+
+
+int drmcgrp_register_device(struct drm_device *dev, enum drmcgrp_vendor_id id)
+{
+ struct drmcgrp_device *ddev;
+
+ ddev = kzalloc(sizeof(struct drmcgrp_device), GFP_KERNEL);
+ if (!ddev)
+ return -ENOMEM;
+
+ mutex_lock(&drmcgrp_mutex);
+
+ ddev->vid = id;
+ ddev->dev = dev;
+ mutex_init(&ddev->mutex);
+
+ known_drmcgrp_devs[dev->primary->index] = ddev;
+
+ max_minor = max(max_minor, dev->primary->index);
+
+ mutex_unlock(&drmcgrp_mutex);
+ return 0;
+}
+EXPORT_SYMBOL(drmcgrp_register_device);
_______________________________________________
dri-devel mailing list
dri-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/dri-devel