Skip to content

Commit 318c588

Browse files
Gregory Pricedavejiang
authored andcommitted
cxl/memdev: fix deadlock in cxl_memdev_autoremove() on attach failure
cxl_memdev_autoremove() takes device_lock(&cxlmd->dev) via guard(device) and then calls cxl_memdev_unregister() when the attach callback was provided but cxl_mem_probe() failed to bind. cxl_memdev_unregister() calls cdev_device_del() device_del() bus_remove_device() device_release_driver() This path is reached when a driver uses the @Attach parameter to devm_cxl_add_memdev() and the CXL topology fails to enumerate (e.g. DVSEC range registers decode outside platform-defined CXL ranges, causing the endpoint port probe to fail). Add cxl_memdev_attach_failed() to set the scope of the check correctly. Reported-by: kreview-c94b85d6d2 Fixes: 29317f8 ("cxl/mem: Introduce cxl_memdev_attach for CXL-dependent operation") Signed-off-by: Gregory Price <gourry@gourry.net> Reviewed-by: Dan Williams <dan.j.williams@intel.com> Reviewed-by: Davidlohr Bueso <dave@stgolabs.net> Link: https://patch.msgid.link/20260211192228.2148713-1-gourry@gourry.net Signed-off-by: Dave Jiang <dave.jiang@intel.com>
1 parent 6de23f8 commit 318c588

1 file changed

Lines changed: 9 additions & 4 deletions

File tree

drivers/cxl/core/memdev.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,18 +1089,23 @@ static int cxlmd_add(struct cxl_memdev *cxlmd, struct cxl_dev_state *cxlds)
10891089
DEFINE_FREE(put_cxlmd, struct cxl_memdev *,
10901090
if (!IS_ERR_OR_NULL(_T)) put_device(&_T->dev))
10911091

1092-
static struct cxl_memdev *cxl_memdev_autoremove(struct cxl_memdev *cxlmd)
1092+
static bool cxl_memdev_attach_failed(struct cxl_memdev *cxlmd)
10931093
{
1094-
int rc;
1095-
10961094
/*
10971095
* If @attach is provided fail if the driver is not attached upon
10981096
* return. Note that failure here could be the result of a race to
10991097
* teardown the CXL port topology. I.e. cxl_mem_probe() could have
11001098
* succeeded and then cxl_mem unbound before the lock is acquired.
11011099
*/
11021100
guard(device)(&cxlmd->dev);
1103-
if (cxlmd->attach && !cxlmd->dev.driver) {
1101+
return (cxlmd->attach && !cxlmd->dev.driver);
1102+
}
1103+
1104+
static struct cxl_memdev *cxl_memdev_autoremove(struct cxl_memdev *cxlmd)
1105+
{
1106+
int rc;
1107+
1108+
if (cxl_memdev_attach_failed(cxlmd)) {
11041109
cxl_memdev_unregister(cxlmd);
11051110
return ERR_PTR(-ENXIO);
11061111
}

0 commit comments

Comments
 (0)