cxl/mem: Convert devm_cxl_add_memdev() to scope-based-cleanup

In preparation for adding more setup steps, convert the current
implementation to scope-based cleanup.

The cxl_memdev_shutdown() is only required after cdev_device_add(). With
that moved to a helper function it precludes the need to add
scope-based-handler for that cleanup if devm_add_action_or_reset() fails.

Cc: Smita Koralahalli <Smita.KoralahalliChannabasappa@amd.com>
Reviewed-by: Alison Schofield <alison.schofield@intel.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Reviewed-by: Ben Cheatham <benjamin.cheatham@amd.com>
Tested-by: Alejandro Lucero <alucerop@amd.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Link: https://patch.msgid.link/20251216005616.3090129-5-dan.j.williams@intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
This commit is contained in:
Dan Williams 2025-12-15 16:56:14 -08:00 committed by Dave Jiang
parent ae201a0092
commit 6e1d21903f

View File

@ -1050,6 +1050,45 @@ static const struct file_operations cxl_memdev_fops = {
.llseek = noop_llseek,
};
/*
* Activate ioctl operations, no cxl_memdev_rwsem manipulation needed as this is
* ordered with cdev_add() publishing the device.
*/
static int cxlmd_add(struct cxl_memdev *cxlmd, struct cxl_dev_state *cxlds)
{
int rc;
cxlmd->cxlds = cxlds;
cxlds->cxlmd = cxlmd;
rc = cdev_device_add(&cxlmd->cdev, &cxlmd->dev);
if (rc) {
/*
* The cdev was briefly live, shutdown any ioctl operations that
* saw that state.
*/
cxl_memdev_shutdown(&cxlmd->dev);
return rc;
}
return 0;
}
DEFINE_FREE(put_cxlmd, struct cxl_memdev *,
if (!IS_ERR_OR_NULL(_T)) put_device(&_T->dev))
static struct cxl_memdev *cxl_memdev_autoremove(struct cxl_memdev *cxlmd)
{
int rc;
rc = devm_add_action_or_reset(cxlmd->cxlds->dev, cxl_memdev_unregister,
cxlmd);
if (rc)
return ERR_PTR(rc);
return cxlmd;
}
/*
* Core helper for devm_cxl_add_memdev() that wants to both create a device and
* assert to the caller that upon return cxl_mem::probe() has been invoked.
@ -1057,45 +1096,24 @@ static const struct file_operations cxl_memdev_fops = {
struct cxl_memdev *__devm_cxl_add_memdev(struct device *host,
struct cxl_dev_state *cxlds)
{
struct cxl_memdev *cxlmd;
struct device *dev;
struct cdev *cdev;
int rc;
cxlmd = cxl_memdev_alloc(cxlds, &cxl_memdev_fops);
struct cxl_memdev *cxlmd __free(put_cxlmd) =
cxl_memdev_alloc(cxlds, &cxl_memdev_fops);
if (IS_ERR(cxlmd))
return cxlmd;
dev = &cxlmd->dev;
rc = dev_set_name(dev, "mem%d", cxlmd->id);
if (rc)
goto err;
return ERR_PTR(rc);
/*
* Activate ioctl operations, no cxl_memdev_rwsem manipulation
* needed as this is ordered with cdev_add() publishing the device.
*/
cxlmd->cxlds = cxlds;
cxlds->cxlmd = cxlmd;
cdev = &cxlmd->cdev;
rc = cdev_device_add(cdev, dev);
if (rc)
goto err;
rc = devm_add_action_or_reset(host, cxl_memdev_unregister, cxlmd);
rc = cxlmd_add(cxlmd, cxlds);
if (rc)
return ERR_PTR(rc);
return cxlmd;
err:
/*
* The cdev was briefly live, shutdown any ioctl operations that
* saw that state.
*/
cxl_memdev_shutdown(dev);
put_device(dev);
return ERR_PTR(rc);
return cxl_memdev_autoremove(no_free_ptr(cxlmd));
}
EXPORT_SYMBOL_FOR_MODULES(__devm_cxl_add_memdev, "cxl_mem");