Skip to content

Commit

Permalink
cxl/region: Add region driver boiler plate
Browse files Browse the repository at this point in the history
The CXL region driver is responsible for routing fully formed CXL
regions to one of libnvdimm, for persistent memory regions, device-dax
for volatile memory regions, or just act as an enumeration placeholder
if the region was setup and configuration locked by platform firmware.
In the platform-firmware-setup case the expectation is that region is
already accounted in the system memory map, i.e. already enabled as
"System RAM".

For now, just attach to CXL regions in the CXL_CONFIG_COMMIT state, and
take no further action.

Given this driver is just a small / simple router, include it in the
core rather than its own module.

Co-developed-by: Ben Widawsky <bwidawsk@kernel.org>
Signed-off-by: Ben Widawsky <bwidawsk@kernel.org>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Link: https://lore.kernel.org/r/20220624041950.559155-18-dan.j.williams@intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
  • Loading branch information
djbw committed Jul 26, 2022
1 parent 176baef commit 8d48817
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 1 deletion.
12 changes: 12 additions & 0 deletions drivers/cxl/core/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,26 @@ extern struct attribute_group cxl_base_attribute_group;
extern struct device_attribute dev_attr_create_pmem_region;
extern struct device_attribute dev_attr_delete_region;
extern struct device_attribute dev_attr_region;
extern const struct device_type cxl_region_type;
void cxl_decoder_kill_region(struct cxl_endpoint_decoder *cxled);
#define CXL_REGION_ATTR(x) (&dev_attr_##x.attr)
#define CXL_REGION_TYPE(x) (&cxl_region_type)
#define SET_CXL_REGION_ATTR(x) (&dev_attr_##x.attr),
int cxl_region_init(void);
void cxl_region_exit(void);
#else
static inline void cxl_decoder_kill_region(struct cxl_endpoint_decoder *cxled)
{
}
static inline int cxl_region_init(void)
{
return 0;
}
static inline void cxl_region_exit(void)
{
}
#define CXL_REGION_ATTR(x) NULL
#define CXL_REGION_TYPE(x) NULL
#define SET_CXL_REGION_ATTR(x)
#endif

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 @@ -51,6 +51,8 @@ static int cxl_device_id(struct device *dev)
}
if (is_cxl_memdev(dev))
return CXL_DEVICE_MEMORY_EXPANDER;
if (dev->type == CXL_REGION_TYPE())
return CXL_DEVICE_REGION;
return 0;
}

Expand Down Expand Up @@ -1864,8 +1866,14 @@ static __init int cxl_core_init(void)
if (rc)
goto err_bus;

rc = cxl_region_init();
if (rc)
goto err_region;

return 0;

err_region:
bus_unregister(&cxl_bus_type);
err_bus:
destroy_workqueue(cxl_bus_wq);
err_wq:
Expand All @@ -1875,6 +1883,7 @@ static __init int cxl_core_init(void)

static void cxl_core_exit(void)
{
cxl_region_exit();
bus_unregister(&cxl_bus_type);
destroy_workqueue(cxl_bus_wq);
cxl_memdev_exit();
Expand Down
45 changes: 44 additions & 1 deletion drivers/cxl/core/region.c
Original file line number Diff line number Diff line change
Expand Up @@ -1450,7 +1450,7 @@ static void cxl_region_release(struct device *dev)
kfree(cxlr);
}

static const struct device_type cxl_region_type = {
const struct device_type cxl_region_type = {
.name = "cxl_region",
.release = cxl_region_release,
.groups = region_groups
Expand Down Expand Up @@ -1650,4 +1650,47 @@ static ssize_t delete_region_store(struct device *dev,
}
DEVICE_ATTR_WO(delete_region);

static int cxl_region_probe(struct device *dev)
{
struct cxl_region *cxlr = to_cxl_region(dev);
struct cxl_region_params *p = &cxlr->params;
int rc;

rc = down_read_interruptible(&cxl_region_rwsem);
if (rc) {
dev_dbg(&cxlr->dev, "probe interrupted\n");
return rc;
}

if (p->state < CXL_CONFIG_COMMIT) {
dev_dbg(&cxlr->dev, "config state: %d\n", p->state);
rc = -ENXIO;
}

/*
* From this point on any path that changes the region's state away from
* CXL_CONFIG_COMMIT is also responsible for releasing the driver.
*/
up_read(&cxl_region_rwsem);

return rc;
}

static struct cxl_driver cxl_region_driver = {
.name = "cxl_region",
.probe = cxl_region_probe,
.id = CXL_DEVICE_REGION,
};

int cxl_region_init(void)
{
return cxl_driver_register(&cxl_region_driver);
}

void cxl_region_exit(void)
{
cxl_driver_unregister(&cxl_region_driver);
}

MODULE_IMPORT_NS(CXL);
MODULE_ALIAS_CXL(CXL_DEVICE_REGION);
1 change: 1 addition & 0 deletions drivers/cxl/cxl.h
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,7 @@ void cxl_driver_unregister(struct cxl_driver *cxl_drv);
#define CXL_DEVICE_PORT 3
#define CXL_DEVICE_ROOT 4
#define CXL_DEVICE_MEMORY_EXPANDER 5
#define CXL_DEVICE_REGION 6

#define MODULE_ALIAS_CXL(type) MODULE_ALIAS("cxl:t" __stringify(type) "*")
#define CXL_MODALIAS_FMT "cxl:t%d"
Expand Down

0 comments on commit 8d48817

Please sign in to comment.