/** * DOC: managed resources * * Inspired by struct &device managed resources, but tied to the lifetime of * struct &drm_device, which can outlive the underlying physical device, usually * when userspace has some open files and other handles to resources still open. * * Release actions can be added with drmm_add_action(), memory allocations can * be done directly with drmm_kmalloc() and the related functions. Everything * will be released on the final drm_dev_put() in reverse order of how the * release actions have been added and memory has been allocated since driver * loading started with devm_drm_dev_alloc(). * * Note that release actions and managed memory can also be added and removed * during the lifetime of the driver, all the functions are fully concurrent * safe. But it is recommended to use managed resources only for resources that * change rarely, if ever, during the lifetime of the &drm_device instance.
*/
struct drmres { struct drmres_node node; /* * Some archs want to perform DMA into kmalloc caches * and need a guaranteed alignment larger than * the alignment of a 64-bit integer. * Thus we use ARCH_DMA_MINALIGN for data[] which will force the same * alignment for struct drmres when allocated by kmalloc().
*/
u8 __aligned(ARCH_DMA_MINALIGN) data[];
};
/** * drmm_release_action - release a managed action from a &drm_device * @dev: DRM device * @action: function which would be called when @dev is released * @data: opaque pointer, passed to @action * * This function calls the @action previously added by drmm_add_action() * immediately. * The @action is removed from the list of cleanup actions for @dev, * which means that it won't be called in the final drm_dev_put().
*/ void drmm_release_action(struct drm_device *dev,
drmres_release_t action, void *data)
{ struct drmres *dr_match = NULL, *dr; unsignedlong flags;
/** * drmm_kmalloc - &drm_device managed kmalloc() * @dev: DRM device * @size: size of the memory allocation * @gfp: GFP allocation flags * * This is a &drm_device managed version of kmalloc(). The allocated memory is * automatically freed on the final drm_dev_put(). Memory can also be freed * before the final drm_dev_put() by calling drmm_kfree().
*/ 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 = kstrdup_const("kmalloc", gfp);
add_dr(dev, dr);
return dr->data;
}
EXPORT_SYMBOL(drmm_kmalloc);
/** * drmm_kstrdup - &drm_device managed kstrdup() * @dev: DRM device * @s: 0-terminated string to be duplicated * @gfp: GFP allocation flags * * This is a &drm_device managed version of kstrdup(). The allocated memory is * automatically freed on the final drm_dev_put() and works exactly like a * memory allocation obtained by drmm_kmalloc().
*/ char *drmm_kstrdup(struct drm_device *dev, constchar *s, gfp_t gfp)
{
size_t size; char *buf;
/** * drmm_kfree - &drm_device managed kfree() * @dev: DRM device * @data: memory allocation to be freed * * This is a &drm_device managed version of kfree() which can be used to * release memory allocated through drmm_kmalloc() or any of its related * functions before the final drm_dev_put() of @dev.
*/ void drmm_kfree(struct drm_device *dev, void *data)
{ struct drmres *dr_match = NULL, *dr; unsignedlong flags;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.