Inter-revision diff: patch 19

Comparing v13 (message) to v23 (message)

--- v13
+++ v23
@@ -1,90 +1,204 @@
 From: Alejandro Lucero <alucerop@amd.com>
 
-By definition a type2 cxl device will use the host managed memory for
-specific functionality, therefore it should not be available to other
-uses. However, a dax interface could be just good enough in some cases.
-
-Add a flag to a cxl region for specifically state to not create a dax
-device. Allow a Type2 driver to set that flag at region creation time.
+Creating a CXL region requires userspace intervention through the cxl
+sysfs files. Type2 support should allow accelerator drivers to create
+such cxl region from kernel code.
+
+Adding that functionality and integrating it with current support for
+memory expanders.
+
+Based on https://lore.kernel.org/linux-cxl/168592159835.1948938.1647215579839222774.stgit@dwillia2-xfh.jf.intel.com/
 
 Signed-off-by: Alejandro Lucero <alucerop@amd.com>
-Reviewed-by: Zhi Wang <zhiw@nvidia.com>
 Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
-Reviewed-by: Ben Cheatham <benjamin.cheatham@amd.com>
 Reviewed-by: Dave Jiang <dave.jiang@intel.com>
 ---
- drivers/cxl/core/region.c | 10 +++++++++-
- drivers/cxl/cxl.h         |  3 +++
- include/cxl/cxl.h         |  3 ++-
- 3 files changed, 14 insertions(+), 2 deletions(-)
+ drivers/cxl/core/region.c | 131 ++++++++++++++++++++++++++++++++++++--
+ include/cxl/cxl.h         |   3 +
+ 2 files changed, 127 insertions(+), 7 deletions(-)
 
 diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
-index f55fb253ecde..cec168a26efb 100644
+index 63c2aeb2ee1f..293e63dfef22 100644
 --- a/drivers/cxl/core/region.c
 +++ b/drivers/cxl/core/region.c
-@@ -3649,12 +3649,14 @@ __construct_new_region(struct cxl_root_decoder *cxlrd,
-  * @cxlrd: root decoder to allocate HPA
-  * @cxled: endpoint decoder with reserved DPA capacity
-  * @ways: interleave ways required
-+ * @no_dax: if true no DAX device should be created
-  *
-  * Returns a fully formed region in the commit state and attached to the
-  * cxl_region driver.
-  */
- struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
--				     struct cxl_endpoint_decoder *cxled, int ways)
-+				     struct cxl_endpoint_decoder *cxled, int ways,
-+				     bool no_dax)
+@@ -2944,6 +2944,14 @@ cxl_find_region_by_name(struct cxl_root_decoder *cxlrd, const char *name)
+ 	return to_cxl_region(region_dev);
+ }
+ 
++static void drop_region(struct cxl_region *cxlr)
++{
++	struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent);
++	struct cxl_port *port = cxlrd_to_port(cxlrd);
++
++	devm_release_action(port->uport_dev, __unregister_region, cxlr);
++}
++
+ static ssize_t delete_region_store(struct device *dev,
+ 				   struct device_attribute *attr,
+ 				   const char *buf, size_t len)
+@@ -4047,14 +4055,12 @@ static int __construct_region(struct cxl_region *cxlr,
+ 	return 0;
+ }
+ 
+-/* Establish an empty region covering the given HPA range */
+-static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
+-					   struct cxl_endpoint_decoder *cxled)
++static struct cxl_region *construct_region_begin(struct cxl_root_decoder *cxlrd,
++						 struct cxl_endpoint_decoder *cxled)
  {
+ 	struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
+-	struct cxl_port *port = cxlrd_to_port(cxlrd);
+ 	struct cxl_dev_state *cxlds = cxlmd->cxlds;
+-	int rc, part = READ_ONCE(cxled->part);
++	int part = READ_ONCE(cxled->part);
  	struct cxl_region *cxlr;
  
-@@ -3670,6 +3672,9 @@ struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
- 		return ERR_PTR(-ENODEV);
- 	}
- 
-+	if (no_dax)
-+		set_bit(CXL_REGION_F_NO_DAX, &cxlr->flags);
-+
+ 	do {
+@@ -4063,13 +4069,26 @@ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
+ 				       cxled->cxld.target_type);
+ 	} while (IS_ERR(cxlr) && PTR_ERR(cxlr) == -EBUSY);
+ 
+-	if (IS_ERR(cxlr)) {
++	if (IS_ERR(cxlr))
+ 		dev_err(cxlmd->dev.parent,
+ 			"%s:%s: %s failed assign region: %ld\n",
+ 			dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev),
+ 			__func__, PTR_ERR(cxlr));
++
++	return cxlr;
++}
++
++/* Establish an empty region covering the given HPA range */
++static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
++					   struct cxl_endpoint_decoder *cxled)
++{
++	struct cxl_port *port = cxlrd_to_port(cxlrd);
++	struct cxl_region *cxlr;
++	int rc;
++
++	cxlr = construct_region_begin(cxlrd, cxled);
++	if (IS_ERR(cxlr))
+ 		return cxlr;
+-	}
+ 
+ 	rc = __construct_region(cxlr, cxlrd, cxled);
+ 	if (rc) {
+@@ -4080,6 +4099,104 @@ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
  	return cxlr;
  }
- EXPORT_SYMBOL_NS_GPL(cxl_create_region, "CXL");
-@@ -3833,6 +3838,9 @@ static int cxl_region_probe(struct device *dev)
- 	if (rc)
- 		return rc;
- 
-+	if (test_bit(CXL_REGION_F_NO_DAX, &cxlr->flags))
-+		return 0;
-+
- 	switch (cxlr->mode) {
- 	case CXL_PARTMODE_PMEM:
- 		return devm_cxl_add_pmem_region(cxlr);
-diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
-index c35620c24c8f..2eb927c9229c 100644
---- a/drivers/cxl/cxl.h
-+++ b/drivers/cxl/cxl.h
-@@ -405,6 +405,9 @@ struct cxl_region_params {
-  */
- #define CXL_REGION_F_NEEDS_RESET 1
- 
-+/* Allow Type2 drivers to specify if a dax region should not be created. */
-+#define CXL_REGION_F_NO_DAX 2
-+
- /**
-  * struct cxl_region - CXL region
-  * @dev: This region's device
+ 
++DEFINE_FREE(cxl_region_drop, struct cxl_region *, if (_T) drop_region(_T))
++
++static struct cxl_region *
++__construct_new_region(struct cxl_root_decoder *cxlrd,
++		       struct cxl_endpoint_decoder **cxled, int ways)
++{
++	struct cxl_memdev *cxlmd = cxled_to_memdev(cxled[0]);
++	struct cxl_decoder *cxld = &cxlrd->cxlsd.cxld;
++	struct cxl_region_params *p;
++	resource_size_t size = 0;
++	int rc, i;
++
++	struct cxl_region *cxlr __free(cxl_region_drop) =
++		construct_region_begin(cxlrd, cxled[0]);
++	if (IS_ERR(cxlr))
++		return cxlr;
++
++	guard(rwsem_write)(&cxl_rwsem.region);
++
++	/*
++	 * Sanity check. This should not happen with an accel driver handling
++	 * the region creation.
++	 */
++	p = &cxlr->params;
++	if (p->state >= CXL_CONFIG_INTERLEAVE_ACTIVE) {
++		dev_err(cxlmd->dev.parent,
++			"%s:%s: %s  unexpected region state\n",
++			dev_name(&cxlmd->dev), dev_name(&cxled[0]->cxld.dev),
++			__func__);
++		return ERR_PTR(-EBUSY);
++	}
++
++	rc = set_interleave_ways(cxlr, ways);
++	if (rc)
++		return ERR_PTR(rc);
++
++	rc = set_interleave_granularity(cxlr, cxld->interleave_granularity);
++	if (rc)
++		return ERR_PTR(rc);
++
++	scoped_guard(rwsem_read, &cxl_rwsem.dpa) {
++		for (i = 0; i < ways; i++) {
++			if (!cxled[i]->dpa_res)
++				return ERR_PTR(-EINVAL);
++			size += resource_size(cxled[i]->dpa_res);
++		}
++
++		rc = alloc_hpa(cxlr, size);
++		if (rc)
++			return ERR_PTR(rc);
++
++		for (i = 0; i < ways; i++) {
++			rc = cxl_region_attach(cxlr, cxled[i], 0);
++			if (rc)
++				return ERR_PTR(rc);
++		}
++	}
++
++	rc = cxl_region_decode_commit(cxlr);
++	if (rc)
++		return ERR_PTR(rc);
++
++	p->state = CXL_CONFIG_COMMIT;
++
++	return no_free_ptr(cxlr);
++}
++
++/**
++ * cxl_create_region - Establish a region given an endpoint decoder
++ * @cxlrd: root decoder to allocate HPA
++ * @cxled: endpoint decoders with reserved DPA capacity
++ * @ways: interleave ways required
++ *
++ * Returns a fully formed region in the commit state and attached to the
++ * cxl_region driver.
++ */
++struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
++				     struct cxl_endpoint_decoder **cxled,
++				     int ways)
++{
++	struct cxl_region *cxlr;
++
++	mutex_lock(&cxlrd->range_lock);
++	cxlr = __construct_new_region(cxlrd, cxled, ways);
++	mutex_unlock(&cxlrd->range_lock);
++	if (IS_ERR(cxlr))
++		return cxlr;
++
++	if (device_attach(&cxlr->dev) <= 0) {
++		dev_err(&cxlr->dev, "failed to create region\n");
++		drop_region(cxlr);
++		return ERR_PTR(-ENODEV);
++	}
++
++	return cxlr;
++}
++EXPORT_SYMBOL_NS_GPL(cxl_create_region, "CXL");
++
+ static struct cxl_region *
+ cxl_find_region_by_range(struct cxl_root_decoder *cxlrd, struct range *hpa)
+ {
 diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
-index 21cb39dcee9e..0a5d97d5a6bb 100644
+index 4802371db00e..50acbd13bcf8 100644
 --- a/include/cxl/cxl.h
 +++ b/include/cxl/cxl.h
-@@ -267,7 +267,8 @@ struct cxl_endpoint_decoder *cxl_request_dpa(struct cxl_memdev *cxlmd,
+@@ -281,4 +281,7 @@ struct cxl_endpoint_decoder *cxl_request_dpa(struct cxl_memdev *cxlmd,
+ 					     enum cxl_partition_mode mode,
  					     resource_size_t alloc);
  int cxl_dpa_free(struct cxl_endpoint_decoder *cxled);
- struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
--				     struct cxl_endpoint_decoder *cxled, int ways);
-+				     struct cxl_endpoint_decoder *cxled, int ways,
-+				     bool no_dax);
- 
- int cxl_accel_region_detach(struct cxl_endpoint_decoder *cxled);
++struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
++				     struct cxl_endpoint_decoder **cxled,
++				     int ways);
  #endif /* __CXL_CXL_H__ */
 -- 
 2.34.1
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help