[PATCH RFC 2/5] cgroup: Add mechanism to register vendor specific DRM devices

Christian K├Ânig ckoenig.leichtzumerken at gmail.com
Wed Nov 21 09:53:54 UTC 2018


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 at amd.com>
> ---
>   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);



More information about the amd-gfx mailing list