@@ -478,25 +478,18 @@ static int decoder_populate_targets(struct cxl_decoder *cxld,
if (!target_map)
return 0;
- device_lock(&port->dev);
- if (list_empty(&port->dports)) {
- rc = -EINVAL;
- goto out_unlock;
- }
+ device_lock_assert(&port->dev);
+ if (list_empty(&port->dports))
+ return -EINVAL;
for (i = 0; i < cxld->nr_targets; i++) {
struct cxl_dport *dport = find_dport(port, target_map[i]);
- if (!dport) {
- rc = -ENXIO;
- goto out_unlock;
- }
+ if (!dport)
+ return -ENXIO;
cxld->target[i] = dport;
}
-out_unlock:
- device_unlock(&port->dev);
-
return rc;
}
@@ -548,7 +541,7 @@ int cxl_decoder_add(struct cxl_decoder *cxld, int *target_map)
{
struct cxl_port *port;
struct device *dev;
- int rc;
+ int rc = 0;
if (WARN_ON_ONCE(!cxld))
return -EINVAL;
@@ -562,11 +555,13 @@ int cxl_decoder_add(struct cxl_decoder *cxld, int *target_map)
dev = &cxld->dev;
port = to_cxl_port(cxld->dev.parent);
- if (!is_endpoint_decoder(dev)) {
+
+ device_lock(&port->dev);
+ if (!is_endpoint_decoder(dev))
rc = decoder_populate_targets(cxld, port, target_map);
- if (rc)
- return rc;
- }
+ device_unlock(&port->dev);
+ if (rc)
+ return rc;
rc = dev_set_name(dev, "decoder%d.%d", port->id, cxld->id);
if (rc)
A CXL port driver which would be responsible for adding decoders will want to do so during probe. Unfortunately, the device lock is held during probe. Making this change allows for a new lock-free variant of cxl_decoder_add which will be used by the port driver. Signed-off-by: Ben Widawsky <ben.widawsky@intel.com> --- drivers/cxl/core/bus.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-)