Skip to content

Commit 1001611

Browse files
djbwdavejiang
authored andcommitted
cxl/mem: Fix devm_cxl_memdev_edac_release() confusion
A device release method is only for undoing allocations on the path to preparing the device for device_add(). In contrast, devm allocations are post device_add(), are acquired during / after ->probe() and are released synchronous with ->remove(). So, a "devm" helper in a "release" method is a clear anti-pattern. Move this devm release action where it belongs, an action created at edac object creation time. Otherwise, this leaks resources until cxl_memdev_release() time which may be long after these xarray and error record caches have gone idle. Note, this also fixes up the type of @cxlmd->err_rec_array which needlessly dropped type-safety. Fixes: 0b5ccb0 ("cxl/edac: Support for finding memory operation attributes from the current boot") Cc: Dave Jiang <dave.jiang@intel.com> Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com> Cc: Shiju Jose <shiju.jose@huawei.com> Cc: Alison Schofield <alison.schofield@intel.com> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Reviewed-by: Ben Cheatham <benjamin.cheatham@amd.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com> Tested-by: Shiju Jose <shiju.jose@huawei.com> Reviewed-by: Shiju Jose <shiju.jose@huawei.com> Tested-by: Alejandro Lucero <alucerop@amd.com> Link: https://patch.msgid.link/20251216005616.3090129-2-dan.j.williams@intel.com Signed-off-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: Dave Jiang <dave.jiang@intel.com>
1 parent 9ace475 commit 1001611

3 files changed

Lines changed: 38 additions & 32 deletions

File tree

drivers/cxl/core/edac.c

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1988,6 +1988,40 @@ static int cxl_memdev_soft_ppr_init(struct cxl_memdev *cxlmd,
19881988
return 0;
19891989
}
19901990

1991+
static void err_rec_free(void *_cxlmd)
1992+
{
1993+
struct cxl_memdev *cxlmd = _cxlmd;
1994+
struct cxl_mem_err_rec *array_rec = cxlmd->err_rec_array;
1995+
struct cxl_event_gen_media *rec_gen_media;
1996+
struct cxl_event_dram *rec_dram;
1997+
unsigned long index;
1998+
1999+
cxlmd->err_rec_array = NULL;
2000+
xa_for_each(&array_rec->rec_dram, index, rec_dram)
2001+
kfree(rec_dram);
2002+
xa_destroy(&array_rec->rec_dram);
2003+
2004+
xa_for_each(&array_rec->rec_gen_media, index, rec_gen_media)
2005+
kfree(rec_gen_media);
2006+
xa_destroy(&array_rec->rec_gen_media);
2007+
kfree(array_rec);
2008+
}
2009+
2010+
static int devm_cxl_memdev_setup_err_rec(struct cxl_memdev *cxlmd)
2011+
{
2012+
struct cxl_mem_err_rec *array_rec =
2013+
kzalloc(sizeof(*array_rec), GFP_KERNEL);
2014+
2015+
if (!array_rec)
2016+
return -ENOMEM;
2017+
2018+
xa_init(&array_rec->rec_gen_media);
2019+
xa_init(&array_rec->rec_dram);
2020+
cxlmd->err_rec_array = array_rec;
2021+
2022+
return devm_add_action_or_reset(&cxlmd->dev, err_rec_free, cxlmd);
2023+
}
2024+
19912025
int devm_cxl_memdev_edac_register(struct cxl_memdev *cxlmd)
19922026
{
19932027
struct edac_dev_feature ras_features[CXL_NR_EDAC_DEV_FEATURES];
@@ -2038,15 +2072,9 @@ int devm_cxl_memdev_edac_register(struct cxl_memdev *cxlmd)
20382072
}
20392073

20402074
if (repair_inst) {
2041-
struct cxl_mem_err_rec *array_rec =
2042-
devm_kzalloc(&cxlmd->dev, sizeof(*array_rec),
2043-
GFP_KERNEL);
2044-
if (!array_rec)
2045-
return -ENOMEM;
2046-
2047-
xa_init(&array_rec->rec_gen_media);
2048-
xa_init(&array_rec->rec_dram);
2049-
cxlmd->err_rec_array = array_rec;
2075+
rc = devm_cxl_memdev_setup_err_rec(cxlmd);
2076+
if (rc)
2077+
return rc;
20502078
}
20512079
}
20522080

@@ -2088,22 +2116,4 @@ int devm_cxl_region_edac_register(struct cxl_region *cxlr)
20882116
}
20892117
EXPORT_SYMBOL_NS_GPL(devm_cxl_region_edac_register, "CXL");
20902118

2091-
void devm_cxl_memdev_edac_release(struct cxl_memdev *cxlmd)
2092-
{
2093-
struct cxl_mem_err_rec *array_rec = cxlmd->err_rec_array;
2094-
struct cxl_event_gen_media *rec_gen_media;
2095-
struct cxl_event_dram *rec_dram;
2096-
unsigned long index;
2097-
2098-
if (!IS_ENABLED(CONFIG_CXL_EDAC_MEM_REPAIR) || !array_rec)
2099-
return;
2100-
2101-
xa_for_each(&array_rec->rec_dram, index, rec_dram)
2102-
kfree(rec_dram);
2103-
xa_destroy(&array_rec->rec_dram);
21042119

2105-
xa_for_each(&array_rec->rec_gen_media, index, rec_gen_media)
2106-
kfree(rec_gen_media);
2107-
xa_destroy(&array_rec->rec_gen_media);
2108-
}
2109-
EXPORT_SYMBOL_NS_GPL(devm_cxl_memdev_edac_release, "CXL");

drivers/cxl/core/memdev.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ static void cxl_memdev_release(struct device *dev)
2727
struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
2828

2929
ida_free(&cxl_memdev_ida, cxlmd->id);
30-
devm_cxl_memdev_edac_release(cxlmd);
3130
kfree(cxlmd);
3231
}
3332

drivers/cxl/cxlmem.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ struct cxl_memdev {
6363
int depth;
6464
u8 scrub_cycle;
6565
int scrub_region_id;
66-
void *err_rec_array;
66+
struct cxl_mem_err_rec *err_rec_array;
6767
};
6868

6969
static inline struct cxl_memdev *to_cxl_memdev(struct device *dev)
@@ -877,7 +877,6 @@ int devm_cxl_memdev_edac_register(struct cxl_memdev *cxlmd);
877877
int devm_cxl_region_edac_register(struct cxl_region *cxlr);
878878
int cxl_store_rec_gen_media(struct cxl_memdev *cxlmd, union cxl_event *evt);
879879
int cxl_store_rec_dram(struct cxl_memdev *cxlmd, union cxl_event *evt);
880-
void devm_cxl_memdev_edac_release(struct cxl_memdev *cxlmd);
881880
#else
882881
static inline int devm_cxl_memdev_edac_register(struct cxl_memdev *cxlmd)
883882
{ return 0; }
@@ -889,8 +888,6 @@ static inline int cxl_store_rec_gen_media(struct cxl_memdev *cxlmd,
889888
static inline int cxl_store_rec_dram(struct cxl_memdev *cxlmd,
890889
union cxl_event *evt)
891890
{ return 0; }
892-
static inline void devm_cxl_memdev_edac_release(struct cxl_memdev *cxlmd)
893-
{ return; }
894891
#endif
895892

896893
#ifdef CONFIG_CXL_SUSPEND

0 commit comments

Comments
 (0)