kref_init() initializes the ref count to 1. An extra kref is taken on the dax_region to be used by the caller. If devm_add_action_or_reset() fails this extra reference is leaked.
Drop the extra reference on error. Fixes: d7fe1a67f658 ("dax: add region 'id', 'size', and 'align' attributes") Cc: Dan Williams <dan.j.willi...@intel.com Suggested-by: Paul Cassella <casse...@hpe.com> Signed-off-by: Ira Weiny <ira.we...@intel.com> --- drivers/dax/bus.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/dax/bus.c b/drivers/dax/bus.c index 227800053309..899e29d107b4 100644 --- a/drivers/dax/bus.c +++ b/drivers/dax/bus.c @@ -583,6 +583,7 @@ static void dax_region_unregister(void *region) dax_region_put(dax_region); } +/* The dax_region reference returned should be dropped with dax_region_put() */ struct dax_region *alloc_dax_region(struct device *parent, int region_id, struct range *range, int target_node, unsigned int align, unsigned long flags) @@ -625,9 +626,13 @@ struct dax_region *alloc_dax_region(struct device *parent, int region_id, return NULL; } + /* Hold a reference to return to the caller */ kref_get(&dax_region->kref); - if (devm_add_action_or_reset(parent, dax_region_unregister, dax_region)) + if (devm_add_action_or_reset(parent, dax_region_unregister, + dax_region)) { + kref_put(&dax_region->kref, dax_region_free); return NULL; + } return dax_region; } EXPORT_SYMBOL_GPL(alloc_dax_region); -- 2.40.0