Skip to content

Commit 6e09926

Browse files
committed
cxl/region: Add volatile region creation support
Expand the region creation infrastructure to enable 'ram' (volatile-memory) regions. The internals of create_pmem_region_store() and create_pmem_region_show() are factored out into helpers __create_region() and __create_region_show() for the 'ram' case to reuse. Reviewed-by: Vishal Verma <[email protected]> Reviewed-by: Gregory Price <[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/167601995775.1924368.352616146815830591.stgit@dwillia2-xfh.jf.intel.com Signed-off-by: Dan Williams <[email protected]>
1 parent 1b9b7a6 commit 6e09926

File tree

4 files changed

+83
-25
lines changed

4 files changed

+83
-25
lines changed

Documentation/ABI/testing/sysfs-bus-cxl

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -285,20 +285,20 @@ Description:
285285
interleave_granularity).
286286

287287

288-
What: /sys/bus/cxl/devices/decoderX.Y/create_pmem_region
289-
Date: May, 2022
290-
KernelVersion: v6.0
288+
What: /sys/bus/cxl/devices/decoderX.Y/create_{pmem,ram}_region
289+
Date: May, 2022, January, 2023
290+
KernelVersion: v6.0 (pmem), v6.3 (ram)
291291
292292
Description:
293293
(RW) Write a string in the form 'regionZ' to start the process
294-
of defining a new persistent memory region (interleave-set)
295-
within the decode range bounded by root decoder 'decoderX.Y'.
296-
The value written must match the current value returned from
297-
reading this attribute. An atomic compare exchange operation is
298-
done on write to assign the requested id to a region and
299-
allocate the region-id for the next creation attempt. EBUSY is
300-
returned if the region name written does not match the current
301-
cached value.
294+
of defining a new persistent, or volatile memory region
295+
(interleave-set) within the decode range bounded by root decoder
296+
'decoderX.Y'. The value written must match the current value
297+
returned from reading this attribute. An atomic compare exchange
298+
operation is done on write to assign the requested id to a
299+
region and allocate the region-id for the next creation attempt.
300+
EBUSY is returned if the region name written does not match the
301+
current cached value.
302302

303303

304304
What: /sys/bus/cxl/devices/decoderX.Y/delete_region

drivers/cxl/core/core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ extern struct attribute_group cxl_base_attribute_group;
1111

1212
#ifdef CONFIG_CXL_REGION
1313
extern struct device_attribute dev_attr_create_pmem_region;
14+
extern struct device_attribute dev_attr_create_ram_region;
1415
extern struct device_attribute dev_attr_delete_region;
1516
extern struct device_attribute dev_attr_region;
1617
extern const struct device_type cxl_pmem_region_type;

drivers/cxl/core/port.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@ static struct attribute *cxl_decoder_root_attrs[] = {
294294
&dev_attr_cap_type3.attr,
295295
&dev_attr_target_list.attr,
296296
SET_CXL_REGION_ATTR(create_pmem_region)
297+
SET_CXL_REGION_ATTR(create_ram_region)
297298
SET_CXL_REGION_ATTR(delete_region)
298299
NULL,
299300
};
@@ -305,6 +306,13 @@ static bool can_create_pmem(struct cxl_root_decoder *cxlrd)
305306
return (cxlrd->cxlsd.cxld.flags & flags) == flags;
306307
}
307308

309+
static bool can_create_ram(struct cxl_root_decoder *cxlrd)
310+
{
311+
unsigned long flags = CXL_DECODER_F_TYPE3 | CXL_DECODER_F_RAM;
312+
313+
return (cxlrd->cxlsd.cxld.flags & flags) == flags;
314+
}
315+
308316
static umode_t cxl_root_decoder_visible(struct kobject *kobj, struct attribute *a, int n)
309317
{
310318
struct device *dev = kobj_to_dev(kobj);
@@ -313,7 +321,11 @@ static umode_t cxl_root_decoder_visible(struct kobject *kobj, struct attribute *
313321
if (a == CXL_REGION_ATTR(create_pmem_region) && !can_create_pmem(cxlrd))
314322
return 0;
315323

316-
if (a == CXL_REGION_ATTR(delete_region) && !can_create_pmem(cxlrd))
324+
if (a == CXL_REGION_ATTR(create_ram_region) && !can_create_ram(cxlrd))
325+
return 0;
326+
327+
if (a == CXL_REGION_ATTR(delete_region) &&
328+
!(can_create_pmem(cxlrd) || can_create_ram(cxlrd)))
317329
return 0;
318330

319331
return a->mode;

drivers/cxl/core/region.c

Lines changed: 58 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1689,6 +1689,15 @@ static struct cxl_region *devm_cxl_add_region(struct cxl_root_decoder *cxlrd,
16891689
struct device *dev;
16901690
int rc;
16911691

1692+
switch (mode) {
1693+
case CXL_DECODER_RAM:
1694+
case CXL_DECODER_PMEM:
1695+
break;
1696+
default:
1697+
dev_err(&cxlrd->cxlsd.cxld.dev, "unsupported mode %d\n", mode);
1698+
return ERR_PTR(-EINVAL);
1699+
}
1700+
16921701
cxlr = cxl_region_alloc(cxlrd, id);
16931702
if (IS_ERR(cxlr))
16941703
return cxlr;
@@ -1717,12 +1726,38 @@ static struct cxl_region *devm_cxl_add_region(struct cxl_root_decoder *cxlrd,
17171726
return ERR_PTR(rc);
17181727
}
17191728

1729+
static ssize_t __create_region_show(struct cxl_root_decoder *cxlrd, char *buf)
1730+
{
1731+
return sysfs_emit(buf, "region%u\n", atomic_read(&cxlrd->region_id));
1732+
}
1733+
17201734
static ssize_t create_pmem_region_show(struct device *dev,
17211735
struct device_attribute *attr, char *buf)
17221736
{
1723-
struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(dev);
1737+
return __create_region_show(to_cxl_root_decoder(dev), buf);
1738+
}
17241739

1725-
return sysfs_emit(buf, "region%u\n", atomic_read(&cxlrd->region_id));
1740+
static ssize_t create_ram_region_show(struct device *dev,
1741+
struct device_attribute *attr, char *buf)
1742+
{
1743+
return __create_region_show(to_cxl_root_decoder(dev), buf);
1744+
}
1745+
1746+
static struct cxl_region *__create_region(struct cxl_root_decoder *cxlrd,
1747+
enum cxl_decoder_mode mode, int id)
1748+
{
1749+
int rc;
1750+
1751+
rc = memregion_alloc(GFP_KERNEL);
1752+
if (rc < 0)
1753+
return ERR_PTR(rc);
1754+
1755+
if (atomic_cmpxchg(&cxlrd->region_id, id, rc) != id) {
1756+
memregion_free(rc);
1757+
return ERR_PTR(-EBUSY);
1758+
}
1759+
1760+
return devm_cxl_add_region(cxlrd, id, mode, CXL_DECODER_EXPANDER);
17261761
}
17271762

17281763
static ssize_t create_pmem_region_store(struct device *dev,
@@ -1731,29 +1766,39 @@ static ssize_t create_pmem_region_store(struct device *dev,
17311766
{
17321767
struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(dev);
17331768
struct cxl_region *cxlr;
1734-
int id, rc;
1769+
int rc, id;
17351770

17361771
rc = sscanf(buf, "region%d\n", &id);
17371772
if (rc != 1)
17381773
return -EINVAL;
17391774

1740-
rc = memregion_alloc(GFP_KERNEL);
1741-
if (rc < 0)
1742-
return rc;
1775+
cxlr = __create_region(cxlrd, CXL_DECODER_PMEM, id);
1776+
if (IS_ERR(cxlr))
1777+
return PTR_ERR(cxlr);
17431778

1744-
if (atomic_cmpxchg(&cxlrd->region_id, id, rc) != id) {
1745-
memregion_free(rc);
1746-
return -EBUSY;
1747-
}
1779+
return len;
1780+
}
1781+
DEVICE_ATTR_RW(create_pmem_region);
1782+
1783+
static ssize_t create_ram_region_store(struct device *dev,
1784+
struct device_attribute *attr,
1785+
const char *buf, size_t len)
1786+
{
1787+
struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(dev);
1788+
struct cxl_region *cxlr;
1789+
int rc, id;
17481790

1749-
cxlr = devm_cxl_add_region(cxlrd, id, CXL_DECODER_PMEM,
1750-
CXL_DECODER_EXPANDER);
1791+
rc = sscanf(buf, "region%d\n", &id);
1792+
if (rc != 1)
1793+
return -EINVAL;
1794+
1795+
cxlr = __create_region(cxlrd, CXL_DECODER_RAM, id);
17511796
if (IS_ERR(cxlr))
17521797
return PTR_ERR(cxlr);
17531798

17541799
return len;
17551800
}
1756-
DEVICE_ATTR_RW(create_pmem_region);
1801+
DEVICE_ATTR_RW(create_ram_region);
17571802

17581803
static ssize_t region_show(struct device *dev, struct device_attribute *attr,
17591804
char *buf)

0 commit comments

Comments
 (0)