Skip to content

Commit 3528b1e

Browse files
committed
cxl/region: Refactor attach_target() for autodiscovery
Region autodiscovery is the process of kernel creating 'struct cxl_region' object to represent active CXL memory ranges it finds already active in hardware when the driver loads. Typically this happens when platform firmware establishes CXL memory regions and then publishes them in the memory map. However, this can also happen in the case of kexec-reboot after the kernel has created regions. In the autodiscovery case the region creation process starts with a known endpoint decoder. Refactor attach_target() into a helper that is suitable to be called from either sysfs, for runtime region creation, or from cxl_port_probe() after it has enumerated all endpoint decoders. The cxl_port_probe() context is an async device-core probing context, so it is not appropriate to allow SIGTERM to interrupt the assembly process. Refactor attach_target() to take @cxled and @State as arguments where @State indicates whether waiting from the region rwsem is interruptible or not. No behavior change is intended. Reviewed-by: Vishal Verma <[email protected]> Reviewed-by: Dave Jiang <[email protected]> Reviewed-by: Ira Weiny <[email protected]> Reviewed-by: Jonathan Cameron <[email protected]> Tested-by: Fan Ni <[email protected]> Link: https://lore.kernel.org/r/167601996393.1924368.2202255054618600069.stgit@dwillia2-xfh.jf.intel.com Signed-off-by: Dan Williams <[email protected]>
1 parent 6e09926 commit 3528b1e

File tree

1 file changed

+28
-19
lines changed

1 file changed

+28
-19
lines changed

drivers/cxl/core/region.c

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1422,31 +1422,25 @@ void cxl_decoder_kill_region(struct cxl_endpoint_decoder *cxled)
14221422
up_write(&cxl_region_rwsem);
14231423
}
14241424

1425-
static int attach_target(struct cxl_region *cxlr, const char *decoder, int pos)
1425+
static int attach_target(struct cxl_region *cxlr,
1426+
struct cxl_endpoint_decoder *cxled, int pos,
1427+
unsigned int state)
14261428
{
1427-
struct device *dev;
1428-
int rc;
1429-
1430-
dev = bus_find_device_by_name(&cxl_bus_type, NULL, decoder);
1431-
if (!dev)
1432-
return -ENODEV;
1433-
1434-
if (!is_endpoint_decoder(dev)) {
1435-
put_device(dev);
1436-
return -EINVAL;
1437-
}
1429+
int rc = 0;
14381430

1439-
rc = down_write_killable(&cxl_region_rwsem);
1431+
if (state == TASK_INTERRUPTIBLE)
1432+
rc = down_write_killable(&cxl_region_rwsem);
1433+
else
1434+
down_write(&cxl_region_rwsem);
14401435
if (rc)
1441-
goto out;
1436+
return rc;
1437+
14421438
down_read(&cxl_dpa_rwsem);
1443-
rc = cxl_region_attach(cxlr, to_cxl_endpoint_decoder(dev), pos);
1439+
rc = cxl_region_attach(cxlr, cxled, pos);
14441440
if (rc == 0)
14451441
set_bit(CXL_REGION_F_INCOHERENT, &cxlr->flags);
14461442
up_read(&cxl_dpa_rwsem);
14471443
up_write(&cxl_region_rwsem);
1448-
out:
1449-
put_device(dev);
14501444
return rc;
14511445
}
14521446

@@ -1484,8 +1478,23 @@ static size_t store_targetN(struct cxl_region *cxlr, const char *buf, int pos,
14841478

14851479
if (sysfs_streq(buf, "\n"))
14861480
rc = detach_target(cxlr, pos);
1487-
else
1488-
rc = attach_target(cxlr, buf, pos);
1481+
else {
1482+
struct device *dev;
1483+
1484+
dev = bus_find_device_by_name(&cxl_bus_type, NULL, buf);
1485+
if (!dev)
1486+
return -ENODEV;
1487+
1488+
if (!is_endpoint_decoder(dev)) {
1489+
rc = -EINVAL;
1490+
goto out;
1491+
}
1492+
1493+
rc = attach_target(cxlr, to_cxl_endpoint_decoder(dev), pos,
1494+
TASK_INTERRUPTIBLE);
1495+
out:
1496+
put_device(dev);
1497+
}
14891498

14901499
if (rc < 0)
14911500
return rc;

0 commit comments

Comments
 (0)