Skip to content

Commit d357dd8

Browse files
djbwdavejiang
authored andcommitted
cxl/region: Convert cxl_pmem_region_alloc to scope-based resource management
A recent bugfix to cxl_pmem_region_alloc() to fix an error-unwind-memleak [1], highlighted a use case for scope-based resource management. Delete the goto for releasing @cxl_region_rwsem, and return error codes directly from error condition paths. The caller, devm_cxl_add_pmem_region(), is no longer given @cxlr_pmem directly it must retrieve it from @cxlr->cxlr_pmem. This retrieval from @CXLR was already in place for @cxlr->cxl_nvb, and converting cxl_pmem_region_alloc() to return an int makes it less awkward to handle no_free_ptr(). Cc: Li Zhijian <[email protected]> Reported-by: Jonathan Cameron <[email protected]> Closes: http://lore.kernel.org/r/[email protected] Link: http://lore.kernel.org/r/[email protected] Signed-off-by: Dan Williams <[email protected]> Reviewed-by: Jonathan Cameron <[email protected]> Link: https://lore.kernel.org/r/171451430965.1147997.15782562063090960666.stgit@dwillia2-xfh.jf.intel.com Signed-off-by: Dave Jiang <[email protected]>
1 parent e4ff70a commit d357dd8

File tree

1 file changed

+17
-26
lines changed

1 file changed

+17
-26
lines changed

drivers/cxl/core/region.c

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2816,26 +2816,21 @@ u64 cxl_trace_hpa(struct cxl_region *cxlr, const struct cxl_memdev *cxlmd,
28162816

28172817
static struct lock_class_key cxl_pmem_region_key;
28182818

2819-
static struct cxl_pmem_region *cxl_pmem_region_alloc(struct cxl_region *cxlr)
2819+
static int cxl_pmem_region_alloc(struct cxl_region *cxlr)
28202820
{
28212821
struct cxl_region_params *p = &cxlr->params;
28222822
struct cxl_nvdimm_bridge *cxl_nvb;
2823-
struct cxl_pmem_region *cxlr_pmem;
28242823
struct device *dev;
28252824
int i;
28262825

2827-
down_read(&cxl_region_rwsem);
2828-
if (p->state != CXL_CONFIG_COMMIT) {
2829-
cxlr_pmem = ERR_PTR(-ENXIO);
2830-
goto out;
2831-
}
2826+
guard(rwsem_read)(&cxl_region_rwsem);
2827+
if (p->state != CXL_CONFIG_COMMIT)
2828+
return -ENXIO;
28322829

2833-
cxlr_pmem = kzalloc(struct_size(cxlr_pmem, mapping, p->nr_targets),
2834-
GFP_KERNEL);
2835-
if (!cxlr_pmem) {
2836-
cxlr_pmem = ERR_PTR(-ENOMEM);
2837-
goto out;
2838-
}
2830+
struct cxl_pmem_region *cxlr_pmem __free(kfree) =
2831+
kzalloc(struct_size(cxlr_pmem, mapping, p->nr_targets), GFP_KERNEL);
2832+
if (!cxlr_pmem)
2833+
return -ENOMEM;
28392834

28402835
cxlr_pmem->hpa_range.start = p->res->start;
28412836
cxlr_pmem->hpa_range.end = p->res->end;
@@ -2853,11 +2848,8 @@ static struct cxl_pmem_region *cxl_pmem_region_alloc(struct cxl_region *cxlr)
28532848
*/
28542849
if (i == 0) {
28552850
cxl_nvb = cxl_find_nvdimm_bridge(cxlmd);
2856-
if (!cxl_nvb) {
2857-
kfree(cxlr_pmem);
2858-
cxlr_pmem = ERR_PTR(-ENODEV);
2859-
goto out;
2860-
}
2851+
if (!cxl_nvb)
2852+
return -ENODEV;
28612853
cxlr->cxl_nvb = cxl_nvb;
28622854
}
28632855
m->cxlmd = cxlmd;
@@ -2868,18 +2860,16 @@ static struct cxl_pmem_region *cxl_pmem_region_alloc(struct cxl_region *cxlr)
28682860
}
28692861

28702862
dev = &cxlr_pmem->dev;
2871-
cxlr_pmem->cxlr = cxlr;
2872-
cxlr->cxlr_pmem = cxlr_pmem;
28732863
device_initialize(dev);
28742864
lockdep_set_class(&dev->mutex, &cxl_pmem_region_key);
28752865
device_set_pm_not_required(dev);
28762866
dev->parent = &cxlr->dev;
28772867
dev->bus = &cxl_bus_type;
28782868
dev->type = &cxl_pmem_region_type;
2879-
out:
2880-
up_read(&cxl_region_rwsem);
2869+
cxlr_pmem->cxlr = cxlr;
2870+
cxlr->cxlr_pmem = no_free_ptr(cxlr_pmem);
28812871

2882-
return cxlr_pmem;
2872+
return 0;
28832873
}
28842874

28852875
static void cxl_dax_region_release(struct device *dev)
@@ -2996,9 +2986,10 @@ static int devm_cxl_add_pmem_region(struct cxl_region *cxlr)
29962986
struct device *dev;
29972987
int rc;
29982988

2999-
cxlr_pmem = cxl_pmem_region_alloc(cxlr);
3000-
if (IS_ERR(cxlr_pmem))
3001-
return PTR_ERR(cxlr_pmem);
2989+
rc = cxl_pmem_region_alloc(cxlr);
2990+
if (rc)
2991+
return rc;
2992+
cxlr_pmem = cxlr->cxlr_pmem;
30022993
cxl_nvb = cxlr->cxl_nvb;
30032994

30042995
dev = &cxlr_pmem->dev;

0 commit comments

Comments
 (0)