[PATCH V2 18/20] cxl/pmem: Add support of cxl lsa 2.1 support in cxl pmem

Neeraj Kumar posted 20 patches 2 months, 1 week ago
There is a newer version of this series
[PATCH V2 18/20] cxl/pmem: Add support of cxl lsa 2.1 support in cxl pmem
Posted by Neeraj Kumar 2 months, 1 week ago
Add support of cxl lsa 2.1 using NDD_CXL_LABEL flag. It also creates cxl
region based on region information parsed from LSA.

Signed-off-by: Neeraj Kumar <s.neeraj@samsung.com>
---
 drivers/cxl/core/region.c | 58 +++++++++++++++++++++++++++++++++++++++
 drivers/cxl/cxl.h         |  4 +++
 drivers/cxl/pmem.c        |  2 ++
 3 files changed, 64 insertions(+)

diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index 8578e046aa78..19ccdd136da0 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -2665,6 +2665,64 @@ static ssize_t create_ram_region_show(struct device *dev,
 	return __create_region_show(to_cxl_root_decoder(dev), buf);
 }
 
+static int match_free_ep_decoder(struct device *dev, const void *data)
+{
+	struct cxl_decoder *cxld = to_cxl_decoder(dev);
+
+	return !cxld->region;
+}
+
+static struct cxl_decoder *cxl_find_free_ep_decoder(struct cxl_port *port)
+{
+	struct device *dev;
+
+	dev = device_find_child(&port->dev, NULL, match_free_ep_decoder);
+	if (!dev)
+		return NULL;
+
+	/* Release device ref taken via device_find_child() */
+	put_device(dev);
+	return to_cxl_decoder(dev);
+}
+
+void create_pmem_region(struct nvdimm *nvdimm)
+{
+	struct cxl_nvdimm *cxl_nvd;
+	struct cxl_memdev *cxlmd;
+	struct cxl_nvdimm_bridge *cxl_nvb;
+	struct cxl_pmem_region_params *params;
+	struct cxl_root_decoder *cxlrd;
+	struct cxl_decoder *cxld;
+	struct cxl_region *cxlr;
+
+	if (!nvdimm_has_cxl_region(nvdimm))
+		return;
+
+	lockdep_assert_held(&cxl_rwsem.region);
+	cxl_nvd = nvdimm_provider_data(nvdimm);
+	params = nvdimm_get_cxl_region_param(nvdimm);
+	cxlmd = cxl_nvd->cxlmd;
+	cxl_nvb = cxlmd->cxl_nvb;
+	cxlrd = cxlmd->cxlrd;
+
+	/*
+	 * FIXME: Limitation: Region creation support only for
+	 * interleave way == 1
+	 */
+	if (!(params->nlabel == 1))
+		dev_info(&cxlmd->dev,
+			 "Region Creation is not supported with iw > 1\n");
+	else {
+		cxld = cxl_find_free_ep_decoder(cxlmd->endpoint);
+		cxlr = cxl_create_region(cxlrd, CXL_PARTMODE_PMEM,
+					 atomic_read(&cxlrd->region_id),
+					 params, cxld);
+		if (IS_ERR(cxlr))
+			dev_info(&cxlmd->dev, "Region Creation failed\n");
+	}
+}
+EXPORT_SYMBOL_NS_GPL(create_pmem_region, "CXL");
+
 struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
 				     enum cxl_partition_mode mode, int id,
 				     struct cxl_pmem_region_params *params,
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index e249372b642d..51c56069f451 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -870,6 +870,7 @@ struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
 				     enum cxl_partition_mode mode, int id,
 				     struct cxl_pmem_region_params *params,
 				     struct cxl_decoder *cxld);
+void create_pmem_region(struct nvdimm *nvdimm);
 #else
 static inline bool is_cxl_pmem_region(struct device *dev)
 {
@@ -903,6 +904,9 @@ cxl_create_region(struct cxl_root_decoder *cxlrd,
 {
 	return NULL;
 }
+static inline void create_pmem_region(struct nvdimm *nvdimm)
+{
+}
 #endif
 
 void cxl_endpoint_parse_cdat(struct cxl_port *port);
diff --git a/drivers/cxl/pmem.c b/drivers/cxl/pmem.c
index 38a5bcdc68ce..4a7428a5a82c 100644
--- a/drivers/cxl/pmem.c
+++ b/drivers/cxl/pmem.c
@@ -135,6 +135,7 @@ static int cxl_nvdimm_probe(struct device *dev)
 		return rc;
 
 	set_bit(NDD_LABELING, &flags);
+	set_bit(NDD_CXL_LABEL, &flags);
 	set_bit(NDD_REGISTER_SYNC, &flags);
 	set_bit(ND_CMD_GET_CONFIG_SIZE, &cmd_mask);
 	set_bit(ND_CMD_GET_CONFIG_DATA, &cmd_mask);
@@ -155,6 +156,7 @@ static int cxl_nvdimm_probe(struct device *dev)
 		return -ENOMEM;
 
 	dev_set_drvdata(dev, nvdimm);
+	create_pmem_region(nvdimm);
 	return devm_add_action_or_reset(dev, unregister_nvdimm, nvdimm);
 }
 
-- 
2.34.1
Re: [PATCH V2 18/20] cxl/pmem: Add support of cxl lsa 2.1 support in cxl pmem
Posted by kernel test robot 2 months ago
Hi Neeraj,

kernel test robot noticed the following build warnings:

[auto build test WARNING on f11a5f89910a7ae970fbce4fdc02d86a8ba8570f]

url:    https://github.com/intel-lab-lkp/linux/commits/Neeraj-Kumar/nvdimm-label-Introduce-NDD_CXL_LABEL-flag-to-set-cxl-label-format/20250730-202209
base:   f11a5f89910a7ae970fbce4fdc02d86a8ba8570f
patch link:    https://lore.kernel.org/r/20250730121209.303202-19-s.neeraj%40samsung.com
patch subject: [PATCH V2 18/20] cxl/pmem: Add support of cxl lsa 2.1 support in cxl pmem
config: i386-randconfig-011-20250731 (https://download.01.org/0day-ci/archive/20250731/202507310929.lJ3DlrYh-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14+deb12u1) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250731/202507310929.lJ3DlrYh-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202507310929.lJ3DlrYh-lkp@intel.com/

All warnings (new ones prefixed by >>):

   drivers/cxl/core/region.c: In function 'create_pmem_region':
>> drivers/cxl/core/region.c:2692:35: warning: variable 'cxl_nvb' set but not used [-Wunused-but-set-variable]
    2692 |         struct cxl_nvdimm_bridge *cxl_nvb;
         |                                   ^~~~~~~


vim +/cxl_nvb +2692 drivers/cxl/core/region.c

  2687	
  2688	void create_pmem_region(struct nvdimm *nvdimm)
  2689	{
  2690		struct cxl_nvdimm *cxl_nvd;
  2691		struct cxl_memdev *cxlmd;
> 2692		struct cxl_nvdimm_bridge *cxl_nvb;
  2693		struct cxl_pmem_region_params *params;
  2694		struct cxl_root_decoder *cxlrd;
  2695		struct cxl_decoder *cxld;
  2696		struct cxl_region *cxlr;
  2697	
  2698		if (!nvdimm_has_cxl_region(nvdimm))
  2699			return;
  2700	
  2701		lockdep_assert_held(&cxl_rwsem.region);
  2702		cxl_nvd = nvdimm_provider_data(nvdimm);
  2703		params = nvdimm_get_cxl_region_param(nvdimm);
  2704		cxlmd = cxl_nvd->cxlmd;
  2705		cxl_nvb = cxlmd->cxl_nvb;
  2706		cxlrd = cxlmd->cxlrd;
  2707	
  2708		/*
  2709		 * FIXME: Limitation: Region creation support only for
  2710		 * interleave way == 1
  2711		 */
  2712		if (!(params->nlabel == 1))
  2713			dev_info(&cxlmd->dev,
  2714				 "Region Creation is not supported with iw > 1\n");
  2715		else {
  2716			cxld = cxl_find_free_ep_decoder(cxlmd->endpoint);
  2717			cxlr = cxl_create_region(cxlrd, CXL_PARTMODE_PMEM,
  2718						 atomic_read(&cxlrd->region_id),
  2719						 params, cxld);
  2720			if (IS_ERR(cxlr))
  2721				dev_info(&cxlmd->dev, "Region Creation failed\n");
  2722		}
  2723	}
  2724	EXPORT_SYMBOL_NS_GPL(create_pmem_region, "CXL");
  2725	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki