Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm: drv: implement __drm_dev_alloc()

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@kernel.org>
Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Link: https://lore.kernel.org/r/20250410235546.43736-2-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>

+47 -16
+42 -16
drivers/gpu/drm/drm_drv.c
··· 808 808 EXPORT_SYMBOL(__devm_drm_dev_alloc); 809 809 810 810 /** 811 + * __drm_dev_alloc - Allocation of a &drm_device instance 812 + * @parent: Parent device object 813 + * @driver: DRM driver 814 + * @size: the size of the struct which contains struct drm_device 815 + * @offset: the offset of the &drm_device within the container. 816 + * 817 + * This should *NOT* be by any drivers, but is a dedicated interface for the 818 + * corresponding Rust abstraction. 819 + * 820 + * This is the same as devm_drm_dev_alloc(), but without the corresponding 821 + * resource management through the parent device, but not the same as 822 + * drm_dev_alloc(), since the latter is the deprecated version, which does not 823 + * support subclassing. 824 + * 825 + * Returns: A pointer to new DRM device, or an ERR_PTR on failure. 826 + */ 827 + void *__drm_dev_alloc(struct device *parent, 828 + const struct drm_driver *driver, 829 + size_t size, size_t offset) 830 + { 831 + void *container; 832 + struct drm_device *drm; 833 + int ret; 834 + 835 + container = kzalloc(size, GFP_KERNEL); 836 + if (!container) 837 + return ERR_PTR(-ENOMEM); 838 + 839 + drm = container + offset; 840 + ret = drm_dev_init(drm, driver, parent); 841 + if (ret) { 842 + kfree(container); 843 + return ERR_PTR(ret); 844 + } 845 + drmm_add_final_kfree(drm, container); 846 + 847 + return container; 848 + } 849 + EXPORT_SYMBOL(__drm_dev_alloc); 850 + 851 + /** 811 852 * drm_dev_alloc - Allocate new DRM device 812 853 * @driver: DRM driver to allocate device for 813 854 * @parent: Parent device object ··· 863 822 struct drm_device *drm_dev_alloc(const struct drm_driver *driver, 864 823 struct device *parent) 865 824 { 866 - struct drm_device *dev; 867 - int ret; 868 - 869 - dev = kzalloc(sizeof(*dev), GFP_KERNEL); 870 - if (!dev) 871 - return ERR_PTR(-ENOMEM); 872 - 873 - ret = drm_dev_init(dev, driver, parent); 874 - if (ret) { 875 - kfree(dev); 876 - return ERR_PTR(ret); 877 - } 878 - 879 - drmm_add_final_kfree(dev, dev); 880 - 881 - return dev; 825 + return __drm_dev_alloc(parent, driver, sizeof(struct drm_device), 0); 882 826 } 883 827 EXPORT_SYMBOL(drm_dev_alloc); 884 828
+5
include/drm/drm_drv.h
··· 473 473 474 474 struct drm_device *drm_dev_alloc(const struct drm_driver *driver, 475 475 struct device *parent); 476 + 477 + void *__drm_dev_alloc(struct device *parent, 478 + const struct drm_driver *driver, 479 + size_t size, size_t offset); 480 + 476 481 int drm_dev_register(struct drm_device *dev, unsigned long flags); 477 482 void drm_dev_unregister(struct drm_device *dev); 478 483