@@ -173,7 +173,8 @@ static int cxl_port_perf_data_calculate(struct cxl_port *port,
return rc;
}
- struct cxl_root *cxl_root __free(put_device) = find_cxl_root(port);
+ struct cxl_root *cxl_root __free(put_cxl_root) = find_cxl_root(port);
+
if (!cxl_root)
return -ENODEV;
@@ -354,7 +355,7 @@ static int cxl_qos_class_verify(struct cxl_memdev *cxlmd)
struct cxl_port *root_port;
int rc;
- struct cxl_root *cxl_root __free(put_device) =
+ struct cxl_root *cxl_root __free(put_cxl_root) =
find_cxl_root(cxlmd->endpoint);
if (!cxl_root)
@@ -64,7 +64,8 @@ static int match_nvdimm_bridge(struct device *dev, void *data)
struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(struct cxl_memdev *cxlmd)
{
- struct cxl_root *cxl_root = find_cxl_root(cxlmd->endpoint);
+ struct cxl_root *cxl_root __free(put_cxl_root) =
+ find_cxl_root(cxlmd->endpoint);
struct cxl_port *port;
struct device *dev;
@@ -73,7 +74,6 @@ struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(struct cxl_memdev *cxlmd)
port = &cxl_root->port;
dev = device_find_child(&port->dev, NULL, match_nvdimm_bridge);
- put_device(&port->dev);
if (!dev)
return NULL;
@@ -986,6 +986,15 @@ struct cxl_root *find_cxl_root(struct cxl_port *port)
}
EXPORT_SYMBOL_NS_GPL(find_cxl_root, CXL);
+void put_cxl_root(struct cxl_root *cxl_root)
+{
+ if (!cxl_root)
+ return;
+
+ put_device(&cxl_root->port.dev);
+}
+EXPORT_SYMBOL_NS_GPL(put_cxl_root, CXL);
+
static struct cxl_dport *find_dport(struct cxl_port *port, int id)
{
struct cxl_dport *dport;
@@ -735,6 +735,9 @@ struct cxl_port *devm_cxl_add_port(struct device *host,
struct cxl_root *devm_cxl_add_root(struct device *host,
const struct cxl_root_ops *ops);
struct cxl_root *find_cxl_root(struct cxl_port *port);
+void put_cxl_root(struct cxl_root *cxl_root);
+DEFINE_FREE(put_cxl_root, struct cxl_root *, if (_T) put_cxl_root(_T))
+
int devm_cxl_enumerate_ports(struct cxl_memdev *cxlmd);
void cxl_bus_rescan(void);
void cxl_bus_drain(void);
@@ -130,7 +130,7 @@ static int cxl_endpoint_port_probe(struct cxl_port *port)
* This can't fail in practice as CXL root exit unregisters all
* descendant ports and that in turn synchronizes with cxl_port_probe()
*/
- struct cxl_root *cxl_root __free(put_device) = find_cxl_root(port);
+ struct cxl_root *cxl_root __free(put_cxl_root) = find_cxl_root(port);
if (!cxl_root)
return -ENODEV;
Add a helper function put_cxl_root() to maintain symmetry for find_cxl_root() function instead of relying on open coding of the put_device() in order to dereference the 'struct device' that happens via get_device() in find_cxl_root(). Add cleanups for all code paths that calls put_device() after find_cxl_root(). Suggested-by: Robert Richter <rrichter@amd.com> Signed-off-by: Dave Jiang <dave.jiang@intel.com> --- v3: - Adjust for cxl_root as parameter for find_cxl_root() - Add NULL ptr check fore __free(). (Dan) - Fix DEFINE_FREE() macro to name it put_cxl_root (Dan) - Cleanup all functions calling put_cxl_root() and related calls. (Dan) v2: - Make put_cxl_root() an exported function to be symmetric to find_cxl_root(). (Robert) --- drivers/cxl/core/cdat.c | 5 +++-- drivers/cxl/core/pmem.c | 4 ++-- drivers/cxl/core/port.c | 9 +++++++++ drivers/cxl/cxl.h | 3 +++ drivers/cxl/port.c | 2 +- 5 files changed, 18 insertions(+), 5 deletions(-)