Am 02.03.20 um 23:25 schrieb Daniel Vetter: <...>
+int __drmm_add_action(struct drm_device *dev,
drmres_release_t action,
void *data, const char *name)
+{
- struct drmres *dr;
- void **void_ptr;
- dr = alloc_dr(action, data ? sizeof(void*) : 0,
GFP_KERNEL | __GFP_ZERO,
dev_to_node(dev->dev));
- if (!dr) {
drm_dbg_drmres(dev, "failed to add action %s for %p\n",
name, data);
return -ENOMEM;
- }
- dr->node.name = name;
Maybe do a kstrdup_const() on name and later a kfree_const() during release. Just in case someone decides to allocate 'name' dynamically.
- if (data) {
void_ptr = (void **)&dr->data;
*void_ptr = data;
- }
- add_dr(dev, dr);
- return 0;
+} +EXPORT_SYMBOL(__drmm_add_action);
+void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp) +{
- struct drmres *dr;
- dr = alloc_dr(NULL, size, gfp, dev_to_node(dev->dev));
- if (!dr) {
drm_dbg_drmres(dev, "failed to allocate %zu bytes, %u flags\n",
size, gfp);
return NULL;
- }
- dr->node.name = "kmalloc";
- add_dr(dev, dr);
- return dr->data;
+} +EXPORT_SYMBOL(drmm_kmalloc);
+void drmm_kfree(struct drm_device *dev, void *data) +{
- struct drmres *dr_match = NULL, *dr;
- unsigned long flags;
- if (!data)
return;
- spin_lock_irqsave(&dev->managed.lock, flags);
- list_for_each_entry(dr, &dev->managed.resources, node.entry) {
if (dr->data == data) {
dr_match = dr;
del_dr(dev, dr_match);
break;
}
- }
- spin_unlock_irqrestore(&dev->managed.lock, flags);
- if (WARN_ON(!dr_match))
return;
- kfree(dr_match);
+} +EXPORT_SYMBOL(drmm_kfree); diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h index bb60a949f416..d39132b477dd 100644 --- a/include/drm/drm_device.h +++ b/include/drm/drm_device.h @@ -67,6 +67,21 @@ struct drm_device { /** @dev: Device structure of bus-device */ struct device *dev;
- /**
* @managed:
*
* Managed resources linked to the lifetime of this &drm_device as
* tracked by @ref.
*/
- struct {
/** @managed.resources: managed resources list */
struct list_head resources;
/** @managed.final_kfree: pointer for final kfree() call */
void *final_kfree;
/** @managed.lock: protects @managed.resources */
spinlock_t lock;
- } managed;
- /** @driver: DRM driver managing the device */ struct drm_driver *driver;
diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h new file mode 100644 index 000000000000..7b5df7d09b19 --- /dev/null +++ b/include/drm/drm_managed.h @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0
+#ifndef _DRM_MANAGED_H_ +#define _DRM_MANAGED_H_
+#include <linux/gfp.h> +#include <linux/types.h>
+struct drm_device;
+typedef void (*drmres_release_t)(struct drm_device *dev, void *res);
+#define drmm_add_action(dev, action, data) \
- __drmm_add_action(dev, action, data, #action)
+int __must_check __drmm_add_action(struct drm_device *dev,
drmres_release_t action,
void *data, const char *name);
+void drmm_add_final_kfree(struct drm_device *dev, void *parent);
+void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp) __malloc; +static inline void *drmm_kzalloc(struct drm_device *dev, size_t size, gfp_t gfp) +{
- return drmm_kmalloc(dev, size, gfp | __GFP_ZERO);
+}
+void drmm_kfree(struct drm_device *dev, void *data);
+#endif diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h index ca7cee8e728a..1c9417430d08 100644 --- a/include/drm/drm_print.h +++ b/include/drm/drm_print.h @@ -313,6 +313,10 @@ enum drm_debug_category { * @DRM_UT_DP: Used in the DP code. */ DRM_UT_DP = 0x100,
- /**
* @DRM_UT_DRMRES: Used in the drm managed resources code.
*/
- DRM_UT_DRMRES = 0x200,
};
static inline bool drm_debug_enabled(enum drm_debug_category category) @@ -442,6 +446,8 @@ void drm_dev_dbg(const struct device *dev, enum drm_debug_category category, drm_dev_dbg((drm)->dev, DRM_UT_LEASE, fmt, ##__VA_ARGS__) #define drm_dbg_dp(drm, fmt, ...) \ drm_dev_dbg((drm)->dev, DRM_UT_DP, fmt, ##__VA_ARGS__) +#define drm_dbg_drmres(drm, fmt, ...) \
- drm_dev_dbg((drm)->dev, DRM_UT_DRMRES, fmt, ##__VA_ARGS__)
/*