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.

devres: add devm_remove_action_nowarn()

devm_remove_action() warns if the action to remove does not exist
(anymore).

The Rust devres abstraction, however, has a use-case to call
devm_remove_action() at a point where it can't be guaranteed that the
corresponding action hasn't been released yet.

In particular, an instance of `Devres<T>` may be dropped after the
action has been released. So far, `Devres<T>` worked around this by
keeping the inner type alive.

Hence, add devm_remove_action_nowarn(), which returns an error code if
the action has been removed already.

A subsequent patch uses devm_remove_action_nowarn() to remove the action
when `Devres<T>` is dropped.

Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Link: https://lore.kernel.org/r/20250107122609.8135-1-dakr@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Danilo Krummrich and committed by
Greg Kroah-Hartman
f1725160 827ed8b1

+35 -6
+18 -5
drivers/base/devres.c
··· 750 750 EXPORT_SYMBOL_GPL(__devm_add_action); 751 751 752 752 /** 753 - * devm_remove_action() - removes previously added custom action 753 + * devm_remove_action_nowarn() - removes previously added custom action 754 754 * @dev: Device that owns the action 755 755 * @action: Function implementing the action 756 756 * @data: Pointer to data passed to @action implementation 757 757 * 758 758 * Removes instance of @action previously added by devm_add_action(). 759 759 * Both action and data should match one of the existing entries. 760 + * 761 + * In contrast to devm_remove_action(), this function does not WARN() if no 762 + * entry could have been found. 763 + * 764 + * This should only be used if the action is contained in an object with 765 + * independent lifetime management, e.g. the Devres rust abstraction. 766 + * 767 + * Causing the warning from regular driver code most likely indicates an abuse 768 + * of the devres API. 769 + * 770 + * Returns: 0 on success, -ENOENT if no entry could have been found. 760 771 */ 761 - void devm_remove_action(struct device *dev, void (*action)(void *), void *data) 772 + int devm_remove_action_nowarn(struct device *dev, 773 + void (*action)(void *), 774 + void *data) 762 775 { 763 776 struct action_devres devres = { 764 777 .data = data, 765 778 .action = action, 766 779 }; 767 780 768 - WARN_ON(devres_destroy(dev, devm_action_release, devm_action_match, 769 - &devres)); 781 + return devres_destroy(dev, devm_action_release, devm_action_match, 782 + &devres); 770 783 } 771 - EXPORT_SYMBOL_GPL(devm_remove_action); 784 + EXPORT_SYMBOL_GPL(devm_remove_action_nowarn); 772 785 773 786 /** 774 787 * devm_release_action() - release previously added custom action
+17 -1
include/linux/device.h
··· 399 399 #endif 400 400 401 401 /* allows to add/remove a custom action to devres stack */ 402 - void devm_remove_action(struct device *dev, void (*action)(void *), void *data); 402 + int devm_remove_action_nowarn(struct device *dev, void (*action)(void *), void *data); 403 + 404 + /** 405 + * devm_remove_action() - removes previously added custom action 406 + * @dev: Device that owns the action 407 + * @action: Function implementing the action 408 + * @data: Pointer to data passed to @action implementation 409 + * 410 + * Removes instance of @action previously added by devm_add_action(). 411 + * Both action and data should match one of the existing entries. 412 + */ 413 + static inline 414 + void devm_remove_action(struct device *dev, void (*action)(void *), void *data) 415 + { 416 + WARN_ON(devm_remove_action_nowarn(dev, action, data)); 417 + } 418 + 403 419 void devm_release_action(struct device *dev, void (*action)(void *), void *data); 404 420 405 421 int __devm_add_action(struct device *dev, void (*action)(void *), void *data, const char *name);