Skip to content

Commit

Permalink
cxl/region: Refactor attach_target() for autodiscovery
Browse files Browse the repository at this point in the history
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 <vishal.l.verma@intel.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Reviewed-by: Ira Weiny <ira.weiny@intel.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Tested-by: Fan Ni <fan.ni@samsung.com>
Link: https://lore.kernel.org/r/167601996393.1924368.2202255054618600069.stgit@dwillia2-xfh.jf.intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
  • Loading branch information
Dan Williams committed Feb 11, 2023
1 parent 6e09926 commit 3528b1e
Showing 1 changed file with 28 additions and 19 deletions.
47 changes: 28 additions & 19 deletions drivers/cxl/core/region.c
Original file line number Diff line number Diff line change
Expand Up @@ -1422,31 +1422,25 @@ void cxl_decoder_kill_region(struct cxl_endpoint_decoder *cxled)
up_write(&cxl_region_rwsem);
}

static int attach_target(struct cxl_region *cxlr, const char *decoder, int pos)
static int attach_target(struct cxl_region *cxlr,
struct cxl_endpoint_decoder *cxled, int pos,
unsigned int state)
{
struct device *dev;
int rc;

dev = bus_find_device_by_name(&cxl_bus_type, NULL, decoder);
if (!dev)
return -ENODEV;

if (!is_endpoint_decoder(dev)) {
put_device(dev);
return -EINVAL;
}
int rc = 0;

rc = down_write_killable(&cxl_region_rwsem);
if (state == TASK_INTERRUPTIBLE)
rc = down_write_killable(&cxl_region_rwsem);
else
down_write(&cxl_region_rwsem);
if (rc)
goto out;
return rc;

down_read(&cxl_dpa_rwsem);
rc = cxl_region_attach(cxlr, to_cxl_endpoint_decoder(dev), pos);
rc = cxl_region_attach(cxlr, cxled, pos);
if (rc == 0)
set_bit(CXL_REGION_F_INCOHERENT, &cxlr->flags);
up_read(&cxl_dpa_rwsem);
up_write(&cxl_region_rwsem);
out:
put_device(dev);
return rc;
}

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

if (sysfs_streq(buf, "\n"))
rc = detach_target(cxlr, pos);
else
rc = attach_target(cxlr, buf, pos);
else {
struct device *dev;

dev = bus_find_device_by_name(&cxl_bus_type, NULL, buf);
if (!dev)
return -ENODEV;

if (!is_endpoint_decoder(dev)) {
rc = -EINVAL;
goto out;
}

rc = attach_target(cxlr, to_cxl_endpoint_decoder(dev), pos,
TASK_INTERRUPTIBLE);
out:
put_device(dev);
}

if (rc < 0)
return rc;
Expand Down

0 comments on commit 3528b1e

Please sign in to comment.