Skip to content

Commit 9e53046

Browse files
committed
cxl/region/extent: Expose region extent information in sysfs
Extent information can be helpful to the user to coordinate memory usage with the external orchestrator and FM. Expose the details of region extents by creating the following sysfs entries. /sys/bus/cxl/devices/dax_regionX/extentX.Y /sys/bus/cxl/devices/dax_regionX/extentX.Y/offset /sys/bus/cxl/devices/dax_regionX/extentX.Y/length /sys/bus/cxl/devices/dax_regionX/extentX.Y/tag Based on an original patch by Navneet Singh. Reviewed-by: Jonathan Cameron <[email protected]> Reviewed-by: Fan Ni <[email protected]> Tested-by: Fan Ni <[email protected]> Signed-off-by: Ira Weiny <[email protected]> --- Changes: [iweiny: rebase] [iweiny: s/tag/uuid/ throughout the code] [iweiny: update sysfs docs to 2025]
1 parent 1909e61 commit 9e53046

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed

Documentation/ABI/testing/sysfs-bus-cxl

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,3 +639,39 @@ Description:
639639
The count is persistent across power loss and wraps back to 0
640640
upon overflow. If this file is not present, the device does not
641641
have the necessary support for dirty tracking.
642+
643+
644+
What: /sys/bus/cxl/devices/dax_regionX/extentX.Y/offset
645+
Date: May, 2025
646+
KernelVersion: v6.16
647+
648+
Description:
649+
(RO) [For Dynamic Capacity regions only] Users can use the
650+
extent information to create DAX devices on specific extents.
651+
This is done by creating and destroying DAX devices in specific
652+
sequences and looking at the mappings created. Extent offset
653+
within the region.
654+
655+
656+
What: /sys/bus/cxl/devices/dax_regionX/extentX.Y/length
657+
Date: May, 2025
658+
KernelVersion: v6.16
659+
660+
Description:
661+
(RO) [For Dynamic Capacity regions only] Users can use the
662+
extent information to create DAX devices on specific extents.
663+
This is done by creating and destroying DAX devices in specific
664+
sequences and looking at the mappings created. Extent length
665+
within the region.
666+
667+
668+
What: /sys/bus/cxl/devices/dax_regionX/extentX.Y/uuid
669+
Date: May, 2025
670+
KernelVersion: v6.16
671+
672+
Description:
673+
(RO) [For Dynamic Capacity regions only] Users can use the
674+
extent information to create DAX devices on specific extents.
675+
This is done by creating and destroying DAX devices in specific
676+
sequences and looking at the mappings created. UUID of this
677+
extent.

drivers/cxl/core/extent.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,63 @@
66

77
#include "core.h"
88

9+
static ssize_t offset_show(struct device *dev, struct device_attribute *attr,
10+
char *buf)
11+
{
12+
struct region_extent *region_extent = to_region_extent(dev);
13+
14+
return sysfs_emit(buf, "%#llx\n", region_extent->hpa_range.start);
15+
}
16+
static DEVICE_ATTR_RO(offset);
17+
18+
static ssize_t length_show(struct device *dev, struct device_attribute *attr,
19+
char *buf)
20+
{
21+
struct region_extent *region_extent = to_region_extent(dev);
22+
u64 length = range_len(&region_extent->hpa_range);
23+
24+
return sysfs_emit(buf, "%#llx\n", length);
25+
}
26+
static DEVICE_ATTR_RO(length);
27+
28+
static ssize_t uuid_show(struct device *dev, struct device_attribute *attr,
29+
char *buf)
30+
{
31+
struct region_extent *region_extent = to_region_extent(dev);
32+
33+
return sysfs_emit(buf, "%pUb\n", &region_extent->uuid);
34+
}
35+
static DEVICE_ATTR_RO(uuid);
36+
37+
static struct attribute *region_extent_attrs[] = {
38+
&dev_attr_offset.attr,
39+
&dev_attr_length.attr,
40+
&dev_attr_uuid.attr,
41+
NULL
42+
};
43+
44+
static uuid_t empty_uuid = { 0 };
45+
46+
static umode_t region_extent_visible(struct kobject *kobj,
47+
struct attribute *a, int n)
48+
{
49+
struct device *dev = kobj_to_dev(kobj);
50+
struct region_extent *region_extent = to_region_extent(dev);
51+
52+
if (a == &dev_attr_uuid.attr &&
53+
uuid_equal(&region_extent->uuid, &empty_uuid))
54+
return 0;
55+
56+
return a->mode;
57+
}
58+
59+
static const struct attribute_group region_extent_attribute_group = {
60+
.attrs = region_extent_attrs,
61+
.is_visible = region_extent_visible,
62+
};
63+
64+
__ATTRIBUTE_GROUPS(region_extent_attribute);
65+
966
static void cxled_release_extent(struct cxl_endpoint_decoder *cxled,
1067
struct cxled_extent *ed_extent)
1168
{
@@ -44,6 +101,7 @@ static void region_extent_release(struct device *dev)
44101
static const struct device_type region_extent_type = {
45102
.name = "extent",
46103
.release = region_extent_release,
104+
.groups = region_extent_attribute_groups,
47105
};
48106

49107
bool is_region_extent(struct device *dev)

0 commit comments

Comments
 (0)