Commit db9a3a35 authored by Jonathan Cameron's avatar Jonathan Cameron Committed by Dan Williams

cxl: Fix cleanup of port devices on failure to probe driver.

The device is created, and then there is a check if a driver succesfully
bound to it. In event of failing the bind (e.g. failure in cxl_port_probe())
the device is left registered. When a bus rescan later occurs, fresh
devices are created leading to a multiple device representing the same
underlying hardware. Bad things may follow and at very least we have far too many
devices.

Fix by ensuring autoremove is registered if the device create succeeds,
but doesn't depend on sucessful binding to a driver.

Bug was observed as side effect of incorrect ownership in
[PATCH v9 6/9] cxl/port: Read CDAT table
but will result from any failure to in cxl_port_probe().

Fixes: 8dd2bc0f ("cxl/mem: Add the cxl_mem driver")
Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: default avatarIra Weiny <ira.weiny@intel.com>
Link: https://lore.kernel.org/r/20220609134519.11668-1-Jonathan.Cameron@huawei.comSigned-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent f6f0dab5
...@@ -29,6 +29,7 @@ static int create_endpoint(struct cxl_memdev *cxlmd, ...@@ -29,6 +29,7 @@ static int create_endpoint(struct cxl_memdev *cxlmd,
{ {
struct cxl_dev_state *cxlds = cxlmd->cxlds; struct cxl_dev_state *cxlds = cxlmd->cxlds;
struct cxl_port *endpoint; struct cxl_port *endpoint;
int rc;
endpoint = devm_cxl_add_port(&parent_port->dev, &cxlmd->dev, endpoint = devm_cxl_add_port(&parent_port->dev, &cxlmd->dev,
cxlds->component_reg_phys, parent_port); cxlds->component_reg_phys, parent_port);
...@@ -37,13 +38,17 @@ static int create_endpoint(struct cxl_memdev *cxlmd, ...@@ -37,13 +38,17 @@ static int create_endpoint(struct cxl_memdev *cxlmd,
dev_dbg(&cxlmd->dev, "add: %s\n", dev_name(&endpoint->dev)); dev_dbg(&cxlmd->dev, "add: %s\n", dev_name(&endpoint->dev));
rc = cxl_endpoint_autoremove(cxlmd, endpoint);
if (rc)
return rc;
if (!endpoint->dev.driver) { if (!endpoint->dev.driver) {
dev_err(&cxlmd->dev, "%s failed probe\n", dev_err(&cxlmd->dev, "%s failed probe\n",
dev_name(&endpoint->dev)); dev_name(&endpoint->dev));
return -ENXIO; return -ENXIO;
} }
return cxl_endpoint_autoremove(cxlmd, endpoint); return 0;
} }
static void enable_suspend(void *data) static void enable_suspend(void *data)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment