[PATCH v2 1/8] drm: drv: implement __drm_dev_alloc()
Alyssa Rosenzweig
alyssa at rosenzweig.io
Mon Apr 14 13:27:43 UTC 2025
Reviewed-by: Alyssa Rosenzweig <alyssa at rosenzweig.io>
Le Fri , Apr 11, 2025 at 01:55:20AM +0200, Danilo Krummrich a écrit :
> In the Rust DRM device abstraction we need to allocate a struct
> drm_device.
>
> Currently, there are two options, the deprecated drm_dev_alloc() (which
> does not support subclassing) and devm_drm_dev_alloc(). The latter
> supports subclassing, but also manages the initial reference through
> devres for the parent device.
>
> In Rust we want to conform with the subclassing pattern, but do not want
> to get the initial reference managed for us, since Rust has its own,
> idiomatic ways to properly deal with it.
>
> There are two options to achieve this.
>
> 1) Allocate the memory ourselves with a KBox.
> 2) Implement __drm_dev_alloc(), which supports subclassing, but is
> unmanged.
>
> While (1) would be possible, it would be cumbersome, since it would
> require exporting drm_dev_init() and drmm_add_final_kfree().
>
> Hence, go with option (2) and implement __drm_dev_alloc().
>
> Reviewed-by: Maxime Ripard <mripard at kernel.org>
> Signed-off-by: Danilo Krummrich <dakr at kernel.org>
> ---
> drivers/gpu/drm/drm_drv.c | 58 ++++++++++++++++++++++++++++-----------
> include/drm/drm_drv.h | 5 ++++
> 2 files changed, 47 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> index 17fc5dc708f4..ebb648f1c7a9 100644
> --- a/drivers/gpu/drm/drm_drv.c
> +++ b/drivers/gpu/drm/drm_drv.c
> @@ -808,36 +808,62 @@ void *__devm_drm_dev_alloc(struct device *parent,
> EXPORT_SYMBOL(__devm_drm_dev_alloc);
>
> /**
> - * drm_dev_alloc - Allocate new DRM device
> - * @driver: DRM driver to allocate device for
> + * __drm_dev_alloc - Allocation of a &drm_device instance
> * @parent: Parent device object
> + * @driver: DRM driver
> + * @size: the size of the struct which contains struct drm_device
> + * @offset: the offset of the &drm_device within the container.
> *
> - * This is the deprecated version of devm_drm_dev_alloc(), which does not support
> - * subclassing through embedding the struct &drm_device in a driver private
> - * structure, and which does not support automatic cleanup through devres.
> + * This should *NOT* be by any drivers, but is a dedicated interface for the
> + * corresponding Rust abstraction.
> *
> - * RETURNS:
> - * Pointer to new DRM device, or ERR_PTR on failure.
> + * This is the same as devm_drm_dev_alloc(), but without the corresponding
> + * resource management through the parent device, but not the same as
> + * drm_dev_alloc(), since the latter is the deprecated version, which does not
> + * support subclassing.
> + *
> + * Returns: A pointer to new DRM device, or an ERR_PTR on failure.
> */
> -struct drm_device *drm_dev_alloc(const struct drm_driver *driver,
> - struct device *parent)
> +void *__drm_dev_alloc(struct device *parent,
> + const struct drm_driver *driver,
> + size_t size, size_t offset)
> {
> - struct drm_device *dev;
> + void *container;
> + struct drm_device *drm;
> int ret;
>
> - dev = kzalloc(sizeof(*dev), GFP_KERNEL);
> - if (!dev)
> + container = kzalloc(size, GFP_KERNEL);
> + if (!container)
> return ERR_PTR(-ENOMEM);
>
> - ret = drm_dev_init(dev, driver, parent);
> + drm = container + offset;
> + ret = drm_dev_init(drm, driver, parent);
> if (ret) {
> - kfree(dev);
> + kfree(container);
> return ERR_PTR(ret);
> }
> + drmm_add_final_kfree(drm, container);
>
> - drmm_add_final_kfree(dev, dev);
> + return container;
> +}
> +EXPORT_SYMBOL(__drm_dev_alloc);
>
> - return dev;
> +/**
> + * drm_dev_alloc - Allocate new DRM device
> + * @driver: DRM driver to allocate device for
> + * @parent: Parent device object
> + *
> + * This is the deprecated version of devm_drm_dev_alloc(), which does not support
> + * subclassing through embedding the struct &drm_device in a driver private
> + * structure, and which does not support automatic cleanup through devres.
> + *
> + * RETURNS:
> + * Pointer to new DRM device, or ERR_PTR on failure.
> + */
> +struct drm_device *drm_dev_alloc(const struct drm_driver *driver,
> + struct device *parent)
> +{
> + return __drm_dev_alloc(parent, driver, sizeof(struct drm_device), 0);
> }
> EXPORT_SYMBOL(drm_dev_alloc);
>
> diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
> index a43d707b5f36..63b51942d606 100644
> --- a/include/drm/drm_drv.h
> +++ b/include/drm/drm_drv.h
> @@ -473,6 +473,11 @@ drmm_cgroup_register_region(struct drm_device *dev,
>
> struct drm_device *drm_dev_alloc(const struct drm_driver *driver,
> struct device *parent);
> +
> +void *__drm_dev_alloc(struct device *parent,
> + const struct drm_driver *driver,
> + size_t size, size_t offset);
> +
> int drm_dev_register(struct drm_device *dev, unsigned long flags);
> void drm_dev_unregister(struct drm_device *dev);
>
> --
> 2.49.0
>
More information about the dri-devel
mailing list