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

drivers/base/devres: introduce devm_release_action()

Patch series "mm/devm_memremap_pages: Fix page release race", v2.

Logan audited the devm_memremap_pages() shutdown path and noticed that
it was possible to proceed to arch_remove_memory() before all potential
page references have been reaped.

Introduce a new ->cleanup() callback to do the work of waiting for any
straggling page references and then perform the percpu_ref_exit() in
devm_memremap_pages_release() context.

For p2pdma this involves some deeper reworks to reference count
resources on a per-instance basis rather than a per pci-device basis. A
modified genalloc api is introduced to convey a driver-private pointer
through gen_pool_{alloc,free}() interfaces. Also, a
devm_memunmap_pages() api is introduced since p2pdma does not
auto-release resources on a setup failure.

The dax and pmem changes pass the nvdimm unit tests, and the p2pdma
changes should now pass testing with the pci_p2pdma_release() fix.
Jrme, how does this look for HMM?

This patch (of 6):

The devm_add_action() facility allows a resource allocation routine to
add custom devm semantics. One such user is devm_memremap_pages().

There is now a need to manually trigger
devm_memremap_pages_release(). Introduce devm_release_action() so the
release action can be triggered via a new devm_memunmap_pages() api in a
follow-on change.

Link: http://lkml.kernel.org/r/155727336530.292046.2926860263201336366.stgit@dwillia2-desk3.amr.corp.intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Reviewed-by: Ira Weiny <ira.weiny@intel.com>
Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: "Jérôme Glisse" <jglisse@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Dan Williams and committed by
Linus Torvalds
2374b682 a58f2cef

+24 -1
+23 -1
drivers/base/devres.c
··· 755 755 756 756 WARN_ON(devres_destroy(dev, devm_action_release, devm_action_match, 757 757 &devres)); 758 - 759 758 } 760 759 EXPORT_SYMBOL_GPL(devm_remove_action); 760 + 761 + /** 762 + * devm_release_action() - release previously added custom action 763 + * @dev: Device that owns the action 764 + * @action: Function implementing the action 765 + * @data: Pointer to data passed to @action implementation 766 + * 767 + * Releases and removes instance of @action previously added by 768 + * devm_add_action(). Both action and data should match one of the 769 + * existing entries. 770 + */ 771 + void devm_release_action(struct device *dev, void (*action)(void *), void *data) 772 + { 773 + struct action_devres devres = { 774 + .data = data, 775 + .action = action, 776 + }; 777 + 778 + WARN_ON(devres_release(dev, devm_action_release, devm_action_match, 779 + &devres)); 780 + 781 + } 782 + EXPORT_SYMBOL_GPL(devm_release_action); 761 783 762 784 /* 763 785 * Managed kmalloc/kfree
+1
include/linux/device.h
··· 713 713 /* allows to add/remove a custom action to devres stack */ 714 714 int devm_add_action(struct device *dev, void (*action)(void *), void *data); 715 715 void devm_remove_action(struct device *dev, void (*action)(void *), void *data); 716 + void devm_release_action(struct device *dev, void (*action)(void *), void *data); 716 717 717 718 static inline int devm_add_action_or_reset(struct device *dev, 718 719 void (*action)(void *), void *data)