Skip to content

Commit

Permalink
cxl/region: Enable the assignment of endpoint decoders to regions
Browse files Browse the repository at this point in the history
The region provisioning process involves allocating DPA to a set of
endpoint decoders, and HPA plus the region geometry to a region device.
Then the decoder is assigned to the region. At this point several
validation steps can be performed to validate that the decoder is
suitable to participate in the region.

Co-developed-by: Ben Widawsky <bwidawsk@kernel.org>
Signed-off-by: Ben Widawsky <bwidawsk@kernel.org>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reported-by: kernel test robot <lkp@intel.com>
Link: https://lore.kernel.org/r/165784336184.1758207.16403282029203949622.stgit@dwillia2-xfh.jf.intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
  • Loading branch information
djbw committed Jul 25, 2022
1 parent 23a22cd commit b9686e8
Show file tree
Hide file tree
Showing 6 changed files with 340 additions and 2 deletions.
19 changes: 19 additions & 0 deletions Documentation/ABI/testing/sysfs-bus-cxl
Original file line number Diff line number Diff line change
Expand Up @@ -353,3 +353,22 @@ Description:
size attribute, the resulting physical address space determined
by the driver is reflected here. It is therefore not useful to
read this before writing a value to the size attribute.


What: /sys/bus/cxl/devices/regionZ/target[0..N]
Date: May, 2022
KernelVersion: v5.20
Contact: linux-cxl@vger.kernel.org
Description:
(RW) Write an endpoint decoder object name to 'targetX' where X
is the intended position of the endpoint device in the region
interleave and N is the 'interleave_ways' setting for the
region. ENXIO is returned if the write results in an impossible
to map decode scenario, like the endpoint is unreachable at that
position relative to the root decoder interleave. EBUSY is
returned if the position in the region is already occupied, or
if the region is not in a state to accept interleave
configuration changes. EINVAL is returned if the object name is
not an endpoint decoder. Once all positions have been
successfully written a final validation for decode conflicts is
performed before activating the region.
6 changes: 6 additions & 0 deletions drivers/cxl/core/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,14 @@ extern struct attribute_group cxl_base_attribute_group;
#ifdef CONFIG_CXL_REGION
extern struct device_attribute dev_attr_create_pmem_region;
extern struct device_attribute dev_attr_delete_region;
extern struct device_attribute dev_attr_region;
void cxl_decoder_kill_region(struct cxl_endpoint_decoder *cxled);
#define CXL_REGION_ATTR(x) (&dev_attr_##x.attr)
#define SET_CXL_REGION_ATTR(x) (&dev_attr_##x.attr),
#else
static inline void cxl_decoder_kill_region(struct cxl_endpoint_decoder *cxled)
{
}
#define CXL_REGION_ATTR(x) NULL
#define SET_CXL_REGION_ATTR(x)
#endif
Expand All @@ -34,6 +39,7 @@ int cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, unsigned long long size);
int cxl_dpa_free(struct cxl_endpoint_decoder *cxled);
resource_size_t cxl_dpa_size(struct cxl_endpoint_decoder *cxled);
resource_size_t cxl_dpa_resource_start(struct cxl_endpoint_decoder *cxled);
extern struct rw_semaphore cxl_dpa_rwsem;

int cxl_memdev_init(void);
void cxl_memdev_exit(void);
Expand Down
15 changes: 14 additions & 1 deletion drivers/cxl/core/hdm.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* for enumerating these registers and capabilities.
*/

static DECLARE_RWSEM(cxl_dpa_rwsem);
DECLARE_RWSEM(cxl_dpa_rwsem);

static int add_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
int *target_map)
Expand Down Expand Up @@ -321,6 +321,12 @@ int cxl_dpa_free(struct cxl_endpoint_decoder *cxled)
rc = 0;
goto out;
}
if (cxled->cxld.region) {
dev_dbg(dev, "decoder assigned to: %s\n",
dev_name(&cxled->cxld.region->dev));
rc = -EBUSY;
goto out;
}
if (cxled->cxld.flags & CXL_DECODER_F_ENABLE) {
dev_dbg(dev, "decoder enabled\n");
rc = -EBUSY;
Expand Down Expand Up @@ -397,6 +403,13 @@ int cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, unsigned long long size)
int rc;

down_write(&cxl_dpa_rwsem);
if (cxled->cxld.region) {
dev_dbg(dev, "decoder attached to %s\n",
dev_name(&cxled->cxld.region->dev));
rc = -EBUSY;
goto out;
}

if (cxled->cxld.flags & CXL_DECODER_F_ENABLE) {
dev_dbg(dev, "decoder enabled\n");
rc = -EBUSY;
Expand Down
9 changes: 9 additions & 0 deletions drivers/cxl/core/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ static struct attribute *cxl_decoder_base_attrs[] = {
&dev_attr_locked.attr,
&dev_attr_interleave_granularity.attr,
&dev_attr_interleave_ways.attr,
SET_CXL_REGION_ATTR(region)
NULL,
};

Expand Down Expand Up @@ -1583,6 +1584,7 @@ struct cxl_endpoint_decoder *cxl_endpoint_decoder_alloc(struct cxl_port *port)
if (!cxled)
return ERR_PTR(-ENOMEM);

cxled->pos = -1;
cxld = &cxled->cxld;
rc = cxl_decoder_init(port, cxld);
if (rc) {
Expand Down Expand Up @@ -1687,6 +1689,13 @@ EXPORT_SYMBOL_NS_GPL(cxl_decoder_add, CXL);

static void cxld_unregister(void *dev)
{
struct cxl_endpoint_decoder *cxled;

if (is_endpoint_decoder(dev)) {
cxled = to_cxl_endpoint_decoder(dev);
cxl_decoder_kill_region(cxled);
}

device_unregister(dev);
}

Expand Down

0 comments on commit b9686e8

Please sign in to comment.