From nobody Sun Feb 8 15:08:14 2026 Received: from mailout3.samsung.com (mailout3.samsung.com [203.254.224.33]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4BA0835B12B for ; Fri, 9 Jan 2026 12:44:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=203.254.224.33 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962701; cv=none; b=HYDtue10yKcJtT5u/UWi01J19Rm0A2G9Rs6a9r8MnRDeVrgMAN4+qZDu59+QkzPSGrzGw/6wqYpD2bhsmnbfaZZEq4A/LJdgu5C1vtGYR7aQOio1OwJhLNBYEIi7MTycBuAn7exbvKTGv+Kg2gl8IB7X/8+NcNYyz2azms2dc9Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962701; c=relaxed/simple; bh=Nrh3LJeASNPcmlmYLto8vp7K7VofCjI17u7FYsOih7U=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:MIME-Version: Content-Type:References; b=E6fwzFtcHmXBLLULZ/vlca77porHLncKSMxW5oCnX1ZpoG3OhUAYBh1EhNUI8fm59nAu/uASD/V135CRIy2M5GFbJL54REif1AXfsuIYR+1EmEvJsQq9Cf5kFZ8ib4DhvC3ZiJhSKQz9MOYvTo61+IqHhABRZR0h2Le4pBw2OE0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com; spf=pass smtp.mailfrom=samsung.com; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b=NtLGBGr3; arc=none smtp.client-ip=203.254.224.33 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=samsung.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="NtLGBGr3" Received: from epcas5p3.samsung.com (unknown [182.195.41.41]) by mailout3.samsung.com (KnoxPortal) with ESMTP id 20260109124457epoutp0372050a6134718fd30ab6f26e9eb9f51c~JELTV5aGV0648506485epoutp03l for ; Fri, 9 Jan 2026 12:44:57 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout3.samsung.com 20260109124457epoutp0372050a6134718fd30ab6f26e9eb9f51c~JELTV5aGV0648506485epoutp03l DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1767962697; bh=5xmz/B9yMfpkRTzrVcJYqxwlY+cbVHk6E47L8xjO2O4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NtLGBGr3Gsz7v24jFSWPCXlJ4dzInKLTEwms4OmE95r45dQbECE/XgwqVzhwoR/co rwViobJjJRKlbuz1rRuh4Ge8i8xQMMJQ8iZy2hHoDU73bzfzG7EnntHVhSGc3AqafA /+GKTEWoM4DO59FMXUWLCCs7zvMfbIQZNITFkrGc= Received: from epsnrtp03.localdomain (unknown [182.195.42.155]) by epcas5p4.samsung.com (KnoxPortal) with ESMTPS id 20260109124457epcas5p4d976a8104e4883828c7a62a98c3d350c~JELS_x4o90290002900epcas5p4O; Fri, 9 Jan 2026 12:44:57 +0000 (GMT) Received: from epcas5p2.samsung.com (unknown [182.195.38.88]) by epsnrtp03.localdomain (Postfix) with ESMTP id 4dnhLc3k8Zz3hhT3; Fri, 9 Jan 2026 12:44:56 +0000 (GMT) Received: from epsmtip1.samsung.com (unknown [182.195.34.30]) by epcas5p4.samsung.com (KnoxPortal) with ESMTPA id 20260109124455epcas5p469d54be9ab7a1801b80922404647d371~JELRkUh651264312643epcas5p4b; Fri, 9 Jan 2026 12:44:55 +0000 (GMT) Received: from test-PowerEdge-R740xd.samsungds.net (unknown [107.99.41.79]) by epsmtip1.samsung.com (KnoxPortal) with ESMTPA id 20260109124454epsmtip150d3dcc109c4412b283a2aa79f5a466d~JELQZHSAW0972809728epsmtip1H; Fri, 9 Jan 2026 12:44:54 +0000 (GMT) From: Neeraj Kumar To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev, linux-kernel@vger.kernel.org, gost.dev@samsung.com Cc: a.manzanares@samsung.com, vishak.g@samsung.com, neeraj.kernel@gmail.com, Neeraj Kumar Subject: [PATCH V5 01/17] nvdimm/label: Introduce NDD_REGION_LABELING flag to set region label Date: Fri, 9 Jan 2026 18:14:21 +0530 Message-Id: <20260109124437.4025893-2-s.neeraj@samsung.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260109124437.4025893-1-s.neeraj@samsung.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CMS-MailID: 20260109124455epcas5p469d54be9ab7a1801b80922404647d371 X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" CMS-TYPE: 105P cpgsPolicy: CPGSC10-542,Y X-CFilter-Loop: Reflected X-CMS-RootMailID: 20260109124455epcas5p469d54be9ab7a1801b80922404647d371 References: <20260109124437.4025893-1-s.neeraj@samsung.com> Prior to LSA 2.1 version, LSA contain only namespace labels. LSA 2.1 introduced in CXL 2.0 Spec, which contain region label along with namespace label. NDD_LABELING flag is used for namespace. Introduced NDD_REGION_LABELING flag for region label. Based on these flags nvdimm driver performs operation on namespace label or region label. NDD_REGION_LABELING will be utilized by cxl driver to enable LSA 2.1 region label support Accordingly updated label index version Reviewed-by: Jonathan Cameron Reviewed-by: Dave Jiang Signed-off-by: Neeraj Kumar Reviewed-by: Ira Weiny --- drivers/nvdimm/dimm.c | 1 + drivers/nvdimm/dimm_devs.c | 7 +++++++ drivers/nvdimm/label.c | 21 +++++++++++++++++---- drivers/nvdimm/nd.h | 1 + include/linux/libnvdimm.h | 3 +++ 5 files changed, 29 insertions(+), 4 deletions(-) diff --git a/drivers/nvdimm/dimm.c b/drivers/nvdimm/dimm.c index 2f6c26cc6a3e..07f5c5d5e537 100644 --- a/drivers/nvdimm/dimm.c +++ b/drivers/nvdimm/dimm.c @@ -62,6 +62,7 @@ static int nvdimm_probe(struct device *dev) if (rc < 0) dev_dbg(dev, "failed to unlock dimm: %d\n", rc); =20 + ndd->cxl =3D nvdimm_region_label_supported(ndd->dev); =20 /* * EACCES failures reading the namespace label-area-properties diff --git a/drivers/nvdimm/dimm_devs.c b/drivers/nvdimm/dimm_devs.c index e1349ef5f8fd..3363a97cc5b5 100644 --- a/drivers/nvdimm/dimm_devs.c +++ b/drivers/nvdimm/dimm_devs.c @@ -18,6 +18,13 @@ =20 static DEFINE_IDA(dimm_ida); =20 +bool nvdimm_region_label_supported(struct device *dev) +{ + struct nvdimm *nvdimm =3D to_nvdimm(dev); + + return test_bit(NDD_REGION_LABELING, &nvdimm->flags); +} + /* * Retrieve bus and dimm handle and return if this bus supports * get_config_data commands diff --git a/drivers/nvdimm/label.c b/drivers/nvdimm/label.c index 04f4a049599a..0a9b6c5cb2c3 100644 --- a/drivers/nvdimm/label.c +++ b/drivers/nvdimm/label.c @@ -688,11 +688,24 @@ static int nd_label_write_index(struct nvdimm_drvdata= *ndd, int index, u32 seq, - (unsigned long) to_namespace_index(ndd, 0); nsindex->labeloff =3D __cpu_to_le64(offset); nsindex->nslot =3D __cpu_to_le32(nslot); - nsindex->major =3D __cpu_to_le16(1); - if (sizeof_namespace_label(ndd) < 256) + + /* Set LSA Label Index Version */ + if (ndd->cxl) { + /* CXL r3.2: Table 9-9 Label Index Block Layout */ + nsindex->major =3D __cpu_to_le16(2); nsindex->minor =3D __cpu_to_le16(1); - else - nsindex->minor =3D __cpu_to_le16(2); + } else { + nsindex->major =3D __cpu_to_le16(1); + /* + * NVDIMM Namespace Specification + * Table 2: Namespace Label Index Block Fields + */ + if (sizeof_namespace_label(ndd) < 256) + nsindex->minor =3D __cpu_to_le16(1); + else /* UEFI 2.7: Label Index Block Definitions */ + nsindex->minor =3D __cpu_to_le16(2); + } + nsindex->checksum =3D __cpu_to_le64(0); if (flags & ND_NSINDEX_INIT) { unsigned long *free =3D (unsigned long *) nsindex->free; diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h index b199eea3260e..f631bd84d6f0 100644 --- a/drivers/nvdimm/nd.h +++ b/drivers/nvdimm/nd.h @@ -522,6 +522,7 @@ void nvdimm_set_labeling(struct device *dev); void nvdimm_set_locked(struct device *dev); void nvdimm_clear_locked(struct device *dev); int nvdimm_security_setup_events(struct device *dev); +bool nvdimm_region_label_supported(struct device *dev); #if IS_ENABLED(CONFIG_NVDIMM_KEYS) int nvdimm_security_unlock(struct device *dev); #else diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h index 28f086c4a187..5696715c33bb 100644 --- a/include/linux/libnvdimm.h +++ b/include/linux/libnvdimm.h @@ -44,6 +44,9 @@ enum { /* dimm provider wants synchronous registration by __nvdimm_create() */ NDD_REGISTER_SYNC =3D 8, =20 + /* dimm supports region labels (LSA Format 2.1) */ + NDD_REGION_LABELING =3D 9, + /* need to set a limit somewhere, but yes, this is likely overkill */ ND_IOCTL_MAX_BUFLEN =3D SZ_4M, ND_CMD_MAX_ELEM =3D 5, --=20 2.34.1 From nobody Sun Feb 8 15:08:14 2026 Received: from mailout2.samsung.com (mailout2.samsung.com [203.254.224.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4CFAF35B142 for ; Fri, 9 Jan 2026 12:45:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=203.254.224.25 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962703; cv=none; b=timjyOshigoe7kDlb1SVWR6EEIqa/g1wexmO0jwMii1RfFj7vclshTe2tl1gXoRoWKf0v2oM7dgmVevgzjqQEzlzD/hvcV3o6jxuPe9/Ela0HAOaqwMkfhkMSwMKmTKZ7ZJmZnsL/CTO7V8ku41Ljts2yxqRYyMF4vGmBGuyJfY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962703; c=relaxed/simple; bh=KM24CjqoMDDe8npGaVVcWzJfF1oRGcGBwVm4lwATVU0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:MIME-Version: Content-Type:References; b=cJ8N2QXUcquqdQE/MtK+MUYIxt12XhHpERH3w3yFcIv440a1E8+daPpGZOS39envA6sQzUvu+0y1lsmbpk3r6IbSs69yi3h6CtdDMn6XEUH/NqXp9ID6bMp5PCGh0zYJB57kVSwtYBbuq66oGcp9Zrib0Md93pA0LtqCdEnFHos= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com; spf=pass smtp.mailfrom=samsung.com; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b=rwzLuElc; arc=none smtp.client-ip=203.254.224.25 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=samsung.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="rwzLuElc" Received: from epcas5p1.samsung.com (unknown [182.195.41.39]) by mailout2.samsung.com (KnoxPortal) with ESMTP id 20260109124459epoutp025de2dae2cb1b42714fc7d8517fd753f3~JELVIRmT72083220832epoutp02S for ; Fri, 9 Jan 2026 12:44:59 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.samsung.com 20260109124459epoutp025de2dae2cb1b42714fc7d8517fd753f3~JELVIRmT72083220832epoutp02S DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1767962699; bh=XCGgkoYzmHDoS6RA8zyIHNIs3/xy9sGJph2JjO1aG/Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rwzLuElchf4um3gbjXw2T0e7xhFzenW10+bmvcXK70aIZxCMyqkqQVa8PuwMIfQkc rqLqVrqM4kFBZr9EGbwxjzN9SU+0+XtxHT/GdEE8yASSybgqWYPiXp7ppLQ+Mv6mxn HYzgR0lm2ryC5pnPuDkaFX2xi5GUu+bq3R+NogEw= Received: from epsnrtp02.localdomain (unknown [182.195.42.154]) by epcas5p4.samsung.com (KnoxPortal) with ESMTPS id 20260109124458epcas5p461ba1190da42dc4a5516dc925a4226da~JELUeBJdi1264312643epcas5p4e; Fri, 9 Jan 2026 12:44:58 +0000 (GMT) Received: from epcas5p4.samsung.com (unknown [182.195.38.88]) by epsnrtp02.localdomain (Postfix) with ESMTP id 4dnhLf0l8jz2SSKX; Fri, 9 Jan 2026 12:44:58 +0000 (GMT) Received: from epsmtip1.samsung.com (unknown [182.195.34.30]) by epcas5p2.samsung.com (KnoxPortal) with ESMTPA id 20260109124457epcas5p2c2e8b5dfb9bfc0bc2aa0fcbe9e3122f3~JELTONU5c0900009000epcas5p2r; Fri, 9 Jan 2026 12:44:57 +0000 (GMT) Received: from test-PowerEdge-R740xd.samsungds.net (unknown [107.99.41.79]) by epsmtip1.samsung.com (KnoxPortal) with ESMTPA id 20260109124455epsmtip150b6494316438851410b875002b7c69a~JELRt94d50972509725epsmtip1P; Fri, 9 Jan 2026 12:44:55 +0000 (GMT) From: Neeraj Kumar To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev, linux-kernel@vger.kernel.org, gost.dev@samsung.com Cc: a.manzanares@samsung.com, vishak.g@samsung.com, neeraj.kernel@gmail.com, Neeraj Kumar Subject: [PATCH V5 02/17] nvdimm/label: CXL labels skip the need for 'interleave-set cookie' Date: Fri, 9 Jan 2026 18:14:22 +0530 Message-Id: <20260109124437.4025893-3-s.neeraj@samsung.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260109124437.4025893-1-s.neeraj@samsung.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CMS-MailID: 20260109124457epcas5p2c2e8b5dfb9bfc0bc2aa0fcbe9e3122f3 X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" CMS-TYPE: 105P cpgsPolicy: CPGSC10-542,Y X-CFilter-Loop: Reflected X-CMS-RootMailID: 20260109124457epcas5p2c2e8b5dfb9bfc0bc2aa0fcbe9e3122f3 References: <20260109124437.4025893-1-s.neeraj@samsung.com> CXL LSA v2.1 utilizes the region labels stored in the LSA for interleave set configuration instead of interleave-set cookie used in previous LSA versions. As interleave-set cookie is not required for CXL LSA v2.1 format so skip its usage for CXL LSA 2.1 format Reviewed-by: Jonathan Cameron Acked-by: Ira Weiny Reviewed-by: Dave Jiang Signed-off-by: Neeraj Kumar --- drivers/nvdimm/namespace_devs.c | 8 +++++++- drivers/nvdimm/region_devs.c | 10 ++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_dev= s.c index a5edcacfe46d..43fdb806532e 100644 --- a/drivers/nvdimm/namespace_devs.c +++ b/drivers/nvdimm/namespace_devs.c @@ -1678,7 +1678,13 @@ static struct device *create_namespace_pmem(struct n= d_region *nd_region, int rc =3D 0; u16 i; =20 - if (cookie =3D=3D 0) { + /* + * CXL LSA v2.1 utilizes the region label stored in the LSA for + * interleave set configuration. Whereas EFI LSA v1.1 & v1.2 + * utilizes interleave-set cookie. i.e, CXL labels skip the + * need for 'interleave-set cookie' + */ + if (!ndd->cxl && cookie =3D=3D 0) { dev_dbg(&nd_region->dev, "invalid interleave-set-cookie\n"); return ERR_PTR(-ENXIO); } diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c index 1220530a23b6..77f36a585f13 100644 --- a/drivers/nvdimm/region_devs.c +++ b/drivers/nvdimm/region_devs.c @@ -841,6 +841,16 @@ u64 nd_region_interleave_set_cookie(struct nd_region *= nd_region, if (!nd_set) return 0; =20 + /* + * CXL LSA v2.1 utilizes the region label stored in the LSA for + * interleave set configuration. Whereas EFI LSA v1.1 & v1.2 + * utilizes interleave-set cookie. i.e, CXL labels skip the + * need for 'interleave-set cookie' + */ + if (nsindex && __le16_to_cpu(nsindex->major) =3D=3D 2 + && __le16_to_cpu(nsindex->minor) =3D=3D 1) + return 0; + if (nsindex && __le16_to_cpu(nsindex->major) =3D=3D 1 && __le16_to_cpu(nsindex->minor) =3D=3D 1) return nd_set->cookie1; --=20 2.34.1 From nobody Sun Feb 8 15:08:14 2026 Received: from mailout4.samsung.com (mailout4.samsung.com [203.254.224.34]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1338C35C1AC for ; Fri, 9 Jan 2026 12:45:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=203.254.224.34 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962709; cv=none; b=ccgqCMt/t/pxUpLpLHehmFYzzEx1IxnFbKktHL6Dwwj/vmqJQTIGys+D3Fxt3gFwJpZN/xO/Xizc77yg3ai4N7o4Oc0Ka87K+HY4u3Xl7WBhSSrdfJwRiYtiVIohe6bftSBvpBcatUUvtT9O2JBUt6K6MrU9bLI675pHKjinomM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962709; c=relaxed/simple; bh=2w4QHGOCw++q1kvhal2TldeR8J4oIxIGDuYaRPud1Nw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:MIME-Version: Content-Type:References; b=WGHoclDD9pfPeeDCJwx0o7SJVo1w4XMI5h0z6ptuJk2XQaIKTWTCG2bwQXR++2PSS98pedHDsIh9S5KH9AlfQZJsDIiM3HVPeorxAeqn2lCGv8JBL1l5b3Iqp31cTZORiZbLN4xtG/bUQqmFsMsfJycUhZf5ZGOEWYLDbX5Fvc8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com; spf=pass smtp.mailfrom=samsung.com; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b=i3i2U3mj; arc=none smtp.client-ip=203.254.224.34 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=samsung.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="i3i2U3mj" Received: from epcas5p4.samsung.com (unknown [182.195.41.42]) by mailout4.samsung.com (KnoxPortal) with ESMTP id 20260109124505epoutp04cbe934ed1939f8dc80d4749a0cc9534e~JELafnsJG0412004120epoutp04- for ; Fri, 9 Jan 2026 12:45:05 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout4.samsung.com 20260109124505epoutp04cbe934ed1939f8dc80d4749a0cc9534e~JELafnsJG0412004120epoutp04- DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1767962705; bh=6Ls7B2htQErg67j/Et/0NeQpLttPeWzT3//fPeN7TuY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=i3i2U3mjbV8qmvXWRYo4ebCaXhqrzLtQC1YI51TxBvPrnWqHuF6gEB+16WupzPaMU a8swdxtYOCZBIOLATCX8emsNmUZhCk2k6ixjWjx1+/AwkNxXZb6f4rU1I0ncPGikrg Jn6oGsEGhD/gYdbrFZryYZ4yQ+lPlEeqwLDS0uVM= Received: from epsnrtp04.localdomain (unknown [182.195.42.156]) by epcas5p2.samsung.com (KnoxPortal) with ESMTPS id 20260109124504epcas5p2527ba909dbc68df57a3829797f6755ff~JELaDQdvK0900109001epcas5p2z; Fri, 9 Jan 2026 12:45:04 +0000 (GMT) Received: from epcas5p1.samsung.com (unknown [182.195.38.89]) by epsnrtp04.localdomain (Postfix) with ESMTP id 4dnhLm0g3Zz6B9m5; Fri, 9 Jan 2026 12:45:04 +0000 (GMT) Received: from epsmtip1.samsung.com (unknown [182.195.34.30]) by epcas5p2.samsung.com (KnoxPortal) with ESMTPA id 20260109124503epcas5p27010aaf98c7c3735852cbb18bd68458e~JELY9rDMK2073820738epcas5p2L; Fri, 9 Jan 2026 12:45:03 +0000 (GMT) Received: from test-PowerEdge-R740xd.samsungds.net (unknown [107.99.41.79]) by epsmtip1.samsung.com (KnoxPortal) with ESMTPA id 20260109124457epsmtip17bdcc41e92c2e42498b48bdb89cccfdf~JELTdsLR00972509725epsmtip1Q; Fri, 9 Jan 2026 12:44:57 +0000 (GMT) From: Neeraj Kumar To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev, linux-kernel@vger.kernel.org, gost.dev@samsung.com Cc: a.manzanares@samsung.com, vishak.g@samsung.com, neeraj.kernel@gmail.com, Neeraj Kumar Subject: [PATCH V5 03/17] nvdimm/label: Add namespace/region label support as per LSA 2.1 Date: Fri, 9 Jan 2026 18:14:23 +0530 Message-Id: <20260109124437.4025893-4-s.neeraj@samsung.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260109124437.4025893-1-s.neeraj@samsung.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CMS-MailID: 20260109124503epcas5p27010aaf98c7c3735852cbb18bd68458e X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" CMS-TYPE: 105P cpgsPolicy: CPGSC10-542,Y X-CFilter-Loop: Reflected X-CMS-RootMailID: 20260109124503epcas5p27010aaf98c7c3735852cbb18bd68458e References: <20260109124437.4025893-1-s.neeraj@samsung.com> Modify __pmem_label_update() to update region labels into LSA CXL 3.2 Spec mentions CXL LSA 2.1 Namespace Labels at section 9.13.2.5 Modified __pmem_label_update() using setter functions to update namespace label as per CXL LSA 2.1 Create export routine nd_region_label_update() used for creating region label into LSA. It will be used later from CXL subsystem Reviewed-by: Dave Jiang Signed-off-by: Neeraj Kumar Reviewed-by: Ira Weiny Reviewed-by: Jonathan Cameron --- drivers/nvdimm/label.c | 360 ++++++++++++++++++++++++++------ drivers/nvdimm/label.h | 17 +- drivers/nvdimm/namespace_devs.c | 20 +- drivers/nvdimm/nd.h | 51 +++++ include/linux/libnvdimm.h | 8 + 5 files changed, 386 insertions(+), 70 deletions(-) diff --git a/drivers/nvdimm/label.c b/drivers/nvdimm/label.c index 0a9b6c5cb2c3..17e2a1f5a6da 100644 --- a/drivers/nvdimm/label.c +++ b/drivers/nvdimm/label.c @@ -22,8 +22,8 @@ static uuid_t nvdimm_btt2_uuid; static uuid_t nvdimm_pfn_uuid; static uuid_t nvdimm_dax_uuid; =20 -static uuid_t cxl_region_uuid; -static uuid_t cxl_namespace_uuid; +uuid_t cxl_region_uuid; +uuid_t cxl_namespace_uuid; =20 static const char NSINDEX_SIGNATURE[] =3D "NAMESPACE_INDEX\0"; =20 @@ -278,15 +278,38 @@ static struct nd_namespace_label *nd_label_base(struc= t nvdimm_drvdata *ndd) return base + 2 * sizeof_namespace_index(ndd); } =20 +static unsigned long find_slot(struct nvdimm_drvdata *ndd, + unsigned long label) +{ + unsigned long base; + + base =3D (unsigned long)nd_label_base(ndd); + return (label - base) / sizeof_namespace_label(ndd); +} + +static int to_lsa_slot(struct nvdimm_drvdata *ndd, + union nd_lsa_label *lsa_label) +{ + return find_slot(ndd, (unsigned long) lsa_label); +} + static int to_slot(struct nvdimm_drvdata *ndd, - struct nd_namespace_label *nd_label) + struct nd_label_ent *label_ent) +{ + if (uuid_equal(&cxl_region_uuid, &label_ent->label_uuid)) + return find_slot(ndd, (unsigned long) label_ent->region_label); + else + return find_slot(ndd, (unsigned long) label_ent->label); +} + +static union nd_lsa_label *to_lsa_label(struct nvdimm_drvdata *ndd, int sl= ot) { unsigned long label, base; =20 - label =3D (unsigned long) nd_label; base =3D (unsigned long) nd_label_base(ndd); + label =3D base + sizeof_namespace_label(ndd) * slot; =20 - return (label - base) / sizeof_namespace_label(ndd); + return (union nd_lsa_label *) label; } =20 static struct nd_namespace_label *to_label(struct nvdimm_drvdata *ndd, int= slot) @@ -381,6 +404,16 @@ static void nsl_calculate_checksum(struct nvdimm_drvda= ta *ndd, nsl_set_checksum(ndd, nd_label, sum); } =20 +static void region_label_calculate_checksum(struct nvdimm_drvdata *ndd, + struct cxl_region_label *region_label) +{ + u64 sum; + + region_label->checksum =3D __cpu_to_le64(0); + sum =3D nd_fletcher64(region_label, sizeof_namespace_label(ndd), 1); + region_label->checksum =3D __cpu_to_le64(sum); +} + static bool slot_valid(struct nvdimm_drvdata *ndd, struct nd_namespace_label *nd_label, u32 slot) { @@ -584,7 +617,7 @@ int nd_label_active_count(struct nvdimm_drvdata *ndd) return count; } =20 -struct nd_namespace_label *nd_label_active(struct nvdimm_drvdata *ndd, int= n) +union nd_lsa_label *nd_label_active(struct nvdimm_drvdata *ndd, int n) { struct nd_namespace_index *nsindex; unsigned long *free; @@ -601,7 +634,7 @@ struct nd_namespace_label *nd_label_active(struct nvdim= m_drvdata *ndd, int n) continue; =20 if (n-- =3D=3D 0) - return to_label(ndd, slot); + return to_lsa_label(ndd, slot); } =20 return NULL; @@ -737,9 +770,9 @@ static int nd_label_write_index(struct nvdimm_drvdata *= ndd, int index, u32 seq, } =20 static unsigned long nd_label_offset(struct nvdimm_drvdata *ndd, - struct nd_namespace_label *nd_label) + union nd_lsa_label *lsa_label) { - return (unsigned long) nd_label + return (unsigned long) lsa_label - (unsigned long) to_namespace_index(ndd, 0); } =20 @@ -823,11 +856,15 @@ static void reap_victim(struct nd_mapping *nd_mapping, struct nd_label_ent *victim) { struct nvdimm_drvdata *ndd =3D to_ndd(nd_mapping); - u32 slot =3D to_slot(ndd, victim->label); + u32 slot =3D to_slot(ndd, victim); =20 dev_dbg(ndd->dev, "free: %d\n", slot); nd_label_free_slot(ndd, slot); - victim->label =3D NULL; + + if (uuid_equal(&cxl_region_uuid, &victim->label_uuid)) + victim->region_label =3D NULL; + else + victim->label =3D NULL; } =20 static void nsl_set_type_guid(struct nvdimm_drvdata *ndd, @@ -884,26 +921,20 @@ enum nvdimm_claim_class nsl_get_claim_class(struct nv= dimm_drvdata *ndd, return guid_to_nvdimm_cclass(&nd_label->efi.abstraction_guid); } =20 -static int __pmem_label_update(struct nd_region *nd_region, - struct nd_mapping *nd_mapping, struct nd_namespace_pmem *nspm, - int pos, unsigned long flags) +static int namespace_label_update(struct nd_region *nd_region, + struct nd_mapping *nd_mapping, + struct nd_namespace_pmem *nspm, + int pos, u64 flags, + struct nd_namespace_label *ns_label, + struct nd_namespace_index *nsindex, + u32 slot) { struct nd_namespace_common *ndns =3D &nspm->nsio.common; struct nd_interleave_set *nd_set =3D nd_region->nd_set; struct nvdimm_drvdata *ndd =3D to_ndd(nd_mapping); - struct nd_namespace_label *nd_label; - struct nd_namespace_index *nsindex; - struct nd_label_ent *label_ent; struct nd_label_id label_id; struct resource *res; - unsigned long *free; - u32 nslot, slot; - size_t offset; u64 cookie; - int rc; - - if (!preamble_next(ndd, &nsindex, &free, &nslot)) - return -ENXIO; =20 cookie =3D nd_region_interleave_set_cookie(nd_region, nsindex); nd_label_gen_id(&label_id, nspm->uuid, 0); @@ -916,33 +947,150 @@ static int __pmem_label_update(struct nd_region *nd_= region, return -ENXIO; } =20 + nsl_set_type(ndd, ns_label); + nsl_set_uuid(ndd, ns_label, nspm->uuid); + nsl_set_name(ndd, ns_label, nspm->alt_name); + nsl_set_flags(ndd, ns_label, flags); + nsl_set_nlabel(ndd, ns_label, nd_region->ndr_mappings); + nsl_set_nrange(ndd, ns_label, 1); + nsl_set_position(ndd, ns_label, pos); + nsl_set_isetcookie(ndd, ns_label, cookie); + nsl_set_rawsize(ndd, ns_label, resource_size(res)); + nsl_set_lbasize(ndd, ns_label, nspm->lbasize); + nsl_set_dpa(ndd, ns_label, res->start); + nsl_set_slot(ndd, ns_label, slot); + nsl_set_alignment(ndd, ns_label, 0); + nsl_set_type_guid(ndd, ns_label, &nd_set->type_guid); + nsl_set_region_uuid(ndd, ns_label, &nd_set->uuid); + nsl_set_claim_class(ndd, ns_label, ndns->claim_class); + nsl_calculate_checksum(ndd, ns_label); + nd_dbg_dpa(nd_region, ndd, res, "\n"); + + return 0; +} + +static void region_label_update(struct nd_region *nd_region, + struct cxl_region_label *region_label, + struct nd_mapping *nd_mapping, + int pos, u64 flags, u32 slot) +{ + struct nd_interleave_set *nd_set =3D nd_region->nd_set; + struct nvdimm_drvdata *ndd =3D to_ndd(nd_mapping); + + /* Set Region Label Format identification UUID */ + uuid_copy((uuid_t *)region_label->type, &cxl_region_uuid); + + /* Set Current Region Label UUID */ + export_uuid(region_label->uuid, &nd_set->uuid); + + region_label->flags =3D __cpu_to_le32(flags); + region_label->nlabel =3D __cpu_to_le16(nd_region->ndr_mappings); + region_label->position =3D __cpu_to_le16(pos); + region_label->dpa =3D __cpu_to_le64(nd_mapping->start); + region_label->rawsize =3D __cpu_to_le64(nd_mapping->size); + region_label->hpa =3D __cpu_to_le64(nd_set->res->start); + region_label->slot =3D __cpu_to_le32(slot); + region_label->ig =3D __cpu_to_le32(nd_set->interleave_granularity); + region_label->align =3D __cpu_to_le32(0); + + /* Update fletcher64 Checksum */ + region_label_calculate_checksum(ndd, region_label); +} + +static bool is_label_reapable(struct nd_interleave_set *nd_set, + struct nd_namespace_pmem *nspm, + struct nvdimm_drvdata *ndd, + struct nd_label_ent *label_ent, + enum label_type ltype, + unsigned long *flags) +{ + switch (ltype) { + case NS_LABEL_TYPE: + if (test_and_clear_bit(ND_LABEL_REAP, flags) || + nsl_uuid_equal(ndd, label_ent->label, nspm->uuid)) + return true; + + break; + case RG_LABEL_TYPE: + if (region_label_uuid_equal(label_ent->region_label, + &nd_set->uuid)) + return true; + + break; + } + + return false; +} + +static bool is_label_present(struct nd_label_ent *label_ent, + enum label_type ltype) +{ + switch (ltype) { + case NS_LABEL_TYPE: + if (label_ent->label) + return true; + + break; + case RG_LABEL_TYPE: + if (label_ent->region_label) + return true; + + break; + } + + return false; +} + +static int __pmem_label_update(struct nd_region *nd_region, + struct nd_mapping *nd_mapping, + struct nd_namespace_pmem *nspm, + int pos, unsigned long flags, + enum label_type ltype) +{ + struct nd_interleave_set *nd_set =3D nd_region->nd_set; + struct nvdimm_drvdata *ndd =3D to_ndd(nd_mapping); + struct nd_namespace_index *nsindex; + struct nd_label_ent *label_ent; + union nd_lsa_label *lsa_label; + unsigned long *free; + struct device *dev; + u32 nslot, slot; + size_t offset; + int rc; + + if (!preamble_next(ndd, &nsindex, &free, &nslot)) + return -ENXIO; + /* allocate and write the label to the staging (next) index */ slot =3D nd_label_alloc_slot(ndd); if (slot =3D=3D UINT_MAX) return -ENXIO; dev_dbg(ndd->dev, "allocated: %d\n", slot); =20 - nd_label =3D to_label(ndd, slot); - memset(nd_label, 0, sizeof_namespace_label(ndd)); - nsl_set_uuid(ndd, nd_label, nspm->uuid); - nsl_set_name(ndd, nd_label, nspm->alt_name); - nsl_set_flags(ndd, nd_label, flags); - nsl_set_nlabel(ndd, nd_label, nd_region->ndr_mappings); - nsl_set_nrange(ndd, nd_label, 1); - nsl_set_position(ndd, nd_label, pos); - nsl_set_isetcookie(ndd, nd_label, cookie); - nsl_set_rawsize(ndd, nd_label, resource_size(res)); - nsl_set_lbasize(ndd, nd_label, nspm->lbasize); - nsl_set_dpa(ndd, nd_label, res->start); - nsl_set_slot(ndd, nd_label, slot); - nsl_set_type_guid(ndd, nd_label, &nd_set->type_guid); - nsl_set_claim_class(ndd, nd_label, ndns->claim_class); - nsl_calculate_checksum(ndd, nd_label); - nd_dbg_dpa(nd_region, ndd, res, "\n"); + lsa_label =3D to_lsa_label(ndd, slot); + memset(lsa_label, 0, sizeof_namespace_label(ndd)); + + switch (ltype) { + case NS_LABEL_TYPE: + dev =3D &nspm->nsio.common.dev; + rc =3D namespace_label_update(nd_region, nd_mapping, + nspm, pos, flags, &lsa_label->ns_label, + nsindex, slot); + if (rc) + return rc; + + break; + case RG_LABEL_TYPE: + dev =3D &nd_region->dev; + region_label_update(nd_region, &lsa_label->region_label, + nd_mapping, pos, flags, slot); + + break; + } =20 /* update label */ - offset =3D nd_label_offset(ndd, nd_label); - rc =3D nvdimm_set_config_data(ndd, offset, nd_label, + offset =3D nd_label_offset(ndd, lsa_label); + rc =3D nvdimm_set_config_data(ndd, offset, lsa_label, sizeof_namespace_label(ndd)); if (rc < 0) return rc; @@ -950,10 +1098,11 @@ static int __pmem_label_update(struct nd_region *nd_= region, /* Garbage collect the previous label */ mutex_lock(&nd_mapping->lock); list_for_each_entry(label_ent, &nd_mapping->labels, list) { - if (!label_ent->label) + if (!is_label_present(label_ent, ltype)) continue; - if (test_and_clear_bit(ND_LABEL_REAP, &label_ent->flags) || - nsl_uuid_equal(ndd, label_ent->label, nspm->uuid)) + + if (is_label_reapable(nd_set, nspm, ndd, label_ent, ltype, + &label_ent->flags)) reap_victim(nd_mapping, label_ent); } =20 @@ -961,16 +1110,21 @@ static int __pmem_label_update(struct nd_region *nd_= region, rc =3D nd_label_write_index(ndd, ndd->ns_next, nd_inc_seq(__le32_to_cpu(nsindex->seq)), 0); if (rc =3D=3D 0) { - list_for_each_entry(label_ent, &nd_mapping->labels, list) - if (!label_ent->label) { - label_ent->label =3D nd_label; - nd_label =3D NULL; - break; - } - dev_WARN_ONCE(&nspm->nsio.common.dev, nd_label, - "failed to track label: %d\n", - to_slot(ndd, nd_label)); - if (nd_label) + list_for_each_entry(label_ent, &nd_mapping->labels, list) { + if (is_label_present(label_ent, ltype)) + continue; + + if (ltype =3D=3D NS_LABEL_TYPE) + label_ent->label =3D &lsa_label->ns_label; + else + label_ent->region_label =3D &lsa_label->region_label; + + lsa_label =3D NULL; + break; + } + dev_WARN_ONCE(dev, lsa_label, "failed to track label: %d\n", + to_lsa_slot(ndd, lsa_label)); + if (lsa_label) rc =3D -ENXIO; } mutex_unlock(&nd_mapping->lock); @@ -978,7 +1132,8 @@ static int __pmem_label_update(struct nd_region *nd_re= gion, return rc; } =20 -static int init_labels(struct nd_mapping *nd_mapping, int num_labels) +static int init_labels(struct nd_mapping *nd_mapping, int num_labels, + enum label_type ltype) { int i, old_num_labels =3D 0; struct nd_label_ent *label_ent; @@ -998,6 +1153,16 @@ static int init_labels(struct nd_mapping *nd_mapping,= int num_labels) label_ent =3D kzalloc(sizeof(*label_ent), GFP_KERNEL); if (!label_ent) return -ENOMEM; + + switch (ltype) { + case NS_LABEL_TYPE: + uuid_copy(&label_ent->label_uuid, &cxl_namespace_uuid); + break; + case RG_LABEL_TYPE: + uuid_copy(&label_ent->label_uuid, &cxl_region_uuid); + break; + } + mutex_lock(&nd_mapping->lock); list_add_tail(&label_ent->list, &nd_mapping->labels); mutex_unlock(&nd_mapping->lock); @@ -1041,19 +1206,19 @@ static int del_labels(struct nd_mapping *nd_mapping= , uuid_t *uuid) =20 mutex_lock(&nd_mapping->lock); list_for_each_entry_safe(label_ent, e, &nd_mapping->labels, list) { - struct nd_namespace_label *nd_label =3D label_ent->label; - - if (!nd_label) + if (label_ent->label) continue; active++; - if (!nsl_uuid_equal(ndd, nd_label, uuid)) + if (!nsl_uuid_equal(ndd, label_ent->label, uuid)) continue; active--; - slot =3D to_slot(ndd, nd_label); + slot =3D to_slot(ndd, label_ent); nd_label_free_slot(ndd, slot); dev_dbg(ndd->dev, "free: %d\n", slot); list_move_tail(&label_ent->list, &list); - label_ent->label =3D NULL; + + if (uuid_equal(&cxl_namespace_uuid, &label_ent->label_uuid)) + label_ent->label =3D NULL; } list_splice_tail_init(&list, &nd_mapping->labels); =20 @@ -1067,6 +1232,19 @@ static int del_labels(struct nd_mapping *nd_mapping,= uuid_t *uuid) nd_inc_seq(__le32_to_cpu(nsindex->seq)), 0); } =20 +static int find_region_label_count(struct nd_mapping *nd_mapping) +{ + struct nd_label_ent *label_ent; + int region_label_cnt =3D 0; + + guard(mutex)(&nd_mapping->lock); + list_for_each_entry(label_ent, &nd_mapping->labels, list) + if (uuid_equal(&cxl_region_uuid, &label_ent->label_uuid)) + region_label_cnt++; + + return region_label_cnt; +} + int nd_pmem_namespace_label_update(struct nd_region *nd_region, struct nd_namespace_pmem *nspm, resource_size_t size) { @@ -1075,6 +1253,7 @@ int nd_pmem_namespace_label_update(struct nd_region *= nd_region, for (i =3D 0; i < nd_region->ndr_mappings; i++) { struct nd_mapping *nd_mapping =3D &nd_region->mapping[i]; struct nvdimm_drvdata *ndd =3D to_ndd(nd_mapping); + int region_label_cnt; struct resource *res; int count =3D 0; =20 @@ -1090,12 +1269,20 @@ int nd_pmem_namespace_label_update(struct nd_region= *nd_region, count++; WARN_ON_ONCE(!count); =20 - rc =3D init_labels(nd_mapping, count); + region_label_cnt =3D find_region_label_count(nd_mapping); + /* + * init_labels() scan labels and allocate new label based + * on its second parameter (num_labels). Therefore to + * allocate new namespace label also include previously + * added region label + */ + rc =3D init_labels(nd_mapping, count + region_label_cnt, + NS_LABEL_TYPE); if (rc < 0) return rc; =20 rc =3D __pmem_label_update(nd_region, nd_mapping, nspm, i, - NSLABEL_FLAG_UPDATING); + NSLABEL_FLAG_UPDATING, NS_LABEL_TYPE); if (rc) return rc; } @@ -1107,7 +1294,48 @@ int nd_pmem_namespace_label_update(struct nd_region = *nd_region, for (i =3D 0; i < nd_region->ndr_mappings; i++) { struct nd_mapping *nd_mapping =3D &nd_region->mapping[i]; =20 - rc =3D __pmem_label_update(nd_region, nd_mapping, nspm, i, 0); + rc =3D __pmem_label_update(nd_region, nd_mapping, nspm, i, 0, + NS_LABEL_TYPE); + if (rc) + return rc; + } + + return 0; +} + +int nd_pmem_region_label_update(struct nd_region *nd_region) +{ + int i, rc; + + for (i =3D 0; i < nd_region->ndr_mappings; i++) { + struct nd_mapping *nd_mapping =3D &nd_region->mapping[i]; + struct nvdimm_drvdata *ndd =3D to_ndd(nd_mapping); + int region_label_cnt; + + /* No need to update region label for non cxl format */ + if (!ndd->cxl) + return 0; + + region_label_cnt =3D find_region_label_count(nd_mapping); + rc =3D init_labels(nd_mapping, region_label_cnt + 1, + RG_LABEL_TYPE); + if (rc < 0) + return rc; + + rc =3D __pmem_label_update(nd_region, nd_mapping, NULL, i, + NSLABEL_FLAG_UPDATING, RG_LABEL_TYPE); + if (rc) + return rc; + } + + /* Clear the UPDATING flag per UEFI 2.7 expectations */ + for (i =3D 0; i < nd_region->ndr_mappings; i++) { + struct nd_mapping *nd_mapping =3D &nd_region->mapping[i]; + struct nvdimm_drvdata *ndd =3D to_ndd(nd_mapping); + + WARN_ON_ONCE(!ndd->cxl); + rc =3D __pmem_label_update(nd_region, nd_mapping, NULL, i, 0, + RG_LABEL_TYPE); if (rc) return rc; } diff --git a/drivers/nvdimm/label.h b/drivers/nvdimm/label.h index 0650fb4b9821..f11f54056353 100644 --- a/drivers/nvdimm/label.h +++ b/drivers/nvdimm/label.h @@ -30,6 +30,11 @@ enum { ND_NSINDEX_INIT =3D 0x1, }; =20 +enum label_type { + RG_LABEL_TYPE, + NS_LABEL_TYPE, +}; + /** * struct nd_namespace_index - label set superblock * @sig: NAMESPACE_INDEX\0 @@ -183,6 +188,15 @@ struct nd_namespace_label { }; }; =20 +/* + * LSA 2.1 format introduces region label, which can also reside + * into LSA along with only namespace label as per v1.1 and v1.2 + */ +union nd_lsa_label { + struct nd_namespace_label ns_label; + struct cxl_region_label region_label; +}; + #define NVDIMM_BTT_GUID "8aed63a2-29a2-4c66-8b12-f05d15d3922a" #define NVDIMM_BTT2_GUID "18633bfc-1735-4217-8ac9-17239282d3f8" #define NVDIMM_PFN_GUID "266400ba-fb9f-4677-bcb0-968f11d0d225" @@ -215,7 +229,7 @@ struct nvdimm_drvdata; int nd_label_data_init(struct nvdimm_drvdata *ndd); size_t sizeof_namespace_index(struct nvdimm_drvdata *ndd); int nd_label_active_count(struct nvdimm_drvdata *ndd); -struct nd_namespace_label *nd_label_active(struct nvdimm_drvdata *ndd, int= n); +union nd_lsa_label *nd_label_active(struct nvdimm_drvdata *ndd, int n); u32 nd_label_alloc_slot(struct nvdimm_drvdata *ndd); bool nd_label_free_slot(struct nvdimm_drvdata *ndd, u32 slot); u32 nd_label_nfree(struct nvdimm_drvdata *ndd); @@ -223,4 +237,5 @@ struct nd_region; struct nd_namespace_pmem; int nd_pmem_namespace_label_update(struct nd_region *nd_region, struct nd_namespace_pmem *nspm, resource_size_t size); +int nd_pmem_region_label_update(struct nd_region *nd_region); #endif /* __LABEL_H__ */ diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_dev= s.c index 43fdb806532e..657004021c95 100644 --- a/drivers/nvdimm/namespace_devs.c +++ b/drivers/nvdimm/namespace_devs.c @@ -232,6 +232,13 @@ static ssize_t __alt_name_store(struct device *dev, co= nst char *buf, return rc; } =20 +int nd_region_label_update(struct nd_region *nd_region) +{ + guard(nvdimm_bus)(&nd_region->dev); + return nd_pmem_region_label_update(nd_region); +} +EXPORT_SYMBOL_GPL(nd_region_label_update); + static int nd_namespace_label_update(struct nd_region *nd_region, struct device *dev) { @@ -2122,13 +2129,20 @@ static int init_active_labels(struct nd_region *nd_= region) if (!count) continue; for (j =3D 0; j < count; j++) { - struct nd_namespace_label *label; + union nd_lsa_label *lsa_label; =20 label_ent =3D kzalloc(sizeof(*label_ent), GFP_KERNEL); if (!label_ent) break; - label =3D nd_label_active(ndd, j); - label_ent->label =3D label; + + lsa_label =3D nd_label_active(ndd, j); + if (is_region_label(ndd, lsa_label)) { + label_ent->region_label =3D &lsa_label->region_label; + uuid_copy(&label_ent->label_uuid, &cxl_region_uuid); + } else { + label_ent->label =3D &lsa_label->ns_label; + uuid_copy(&label_ent->label_uuid, &cxl_namespace_uuid); + } =20 mutex_lock(&nd_mapping->lock); list_add_tail(&label_ent->list, &nd_mapping->labels); diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h index f631bd84d6f0..1b31eee3028e 100644 --- a/drivers/nvdimm/nd.h +++ b/drivers/nvdimm/nd.h @@ -14,6 +14,9 @@ #include #include "label.h" =20 +extern uuid_t cxl_namespace_uuid; +extern uuid_t cxl_region_uuid; + enum { /* * Limits the maximum number of block apertures a dimm can @@ -295,6 +298,52 @@ static inline const u8 *nsl_uuid_raw(struct nvdimm_drv= data *ndd, return nd_label->efi.uuid; } =20 +static inline void nsl_set_type(struct nvdimm_drvdata *ndd, + struct nd_namespace_label *ns_label) +{ + if (!(ndd->cxl && ns_label)) + return; + + export_uuid(ns_label->cxl.type, &cxl_namespace_uuid); +} + +static inline void nsl_set_alignment(struct nvdimm_drvdata *ndd, + struct nd_namespace_label *ns_label, + u32 align) +{ + if (!ndd->cxl) + return; + + ns_label->cxl.align =3D __cpu_to_le32(align); +} + +static inline void nsl_set_region_uuid(struct nvdimm_drvdata *ndd, + struct nd_namespace_label *ns_label, + const uuid_t *uuid) +{ + if (!(ndd->cxl && uuid)) + return; + + export_uuid(ns_label->cxl.region_uuid, uuid); +} + +static inline bool is_region_label(struct nvdimm_drvdata *ndd, + union nd_lsa_label *lsa_label) +{ + if (!ndd->cxl) + return false; + + return uuid_equal(&cxl_region_uuid, + (uuid_t *)lsa_label->region_label.type); +} + +static inline bool +region_label_uuid_equal(struct cxl_region_label *region_label, + const uuid_t *uuid) +{ + return uuid_equal((uuid_t *)region_label->uuid, uuid); +} + bool nsl_validate_type_guid(struct nvdimm_drvdata *ndd, struct nd_namespace_label *nd_label, guid_t *guid); enum nvdimm_claim_class nsl_get_claim_class(struct nvdimm_drvdata *ndd, @@ -376,7 +425,9 @@ enum nd_label_flags { struct nd_label_ent { struct list_head list; unsigned long flags; + uuid_t label_uuid; struct nd_namespace_label *label; + struct cxl_region_label *region_label; }; =20 enum nd_mapping_lock_class { diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h index 5696715c33bb..2c213b9dac66 100644 --- a/include/linux/libnvdimm.h +++ b/include/linux/libnvdimm.h @@ -117,6 +117,13 @@ struct nd_interleave_set { u64 altcookie; =20 guid_t type_guid; + + /* v2.1 region label info */ + uuid_t uuid; + int interleave_ways; + int interleave_granularity; + struct resource *res; + int nr_targets; }; =20 struct nd_mapping_desc { @@ -307,6 +314,7 @@ int nvdimm_has_flush(struct nd_region *nd_region); int nvdimm_has_cache(struct nd_region *nd_region); int nvdimm_in_overwrite(struct nvdimm *nvdimm); bool is_nvdimm_sync(struct nd_region *nd_region); +int nd_region_label_update(struct nd_region *nd_region); =20 static inline int nvdimm_ctl(struct nvdimm *nvdimm, unsigned int cmd, void= *buf, unsigned int buf_len, int *cmd_rc) --=20 2.34.1 From nobody Sun Feb 8 15:08:14 2026 Received: from mailout2.samsung.com (mailout2.samsung.com [203.254.224.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6E17A35BDC6 for ; Fri, 9 Jan 2026 12:45:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=203.254.224.25 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962717; cv=none; b=qNml39SbPpNW74RVvIdK2FgUfkhLOO8OhPMfIMPtLFEnncoM8/YEIN8bAoeMmw0JGE5SWjd7fbFyHQ7MJLoliwj/8siSILxYHAhW5PBm6F8oSOGva6oiEqLGOdTvhktWjH7I346Vgl3eG0BdJ6Ks+TsIBVnm3OCo2/chWSQ2brU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962717; c=relaxed/simple; bh=eJ84zPDSdkNcOPjEXDOFVSn7BD2jw9zWo/Q+6BRmSXg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:MIME-Version: Content-Type:References; b=Ir0cHW9ofGdKg6ziPXXm8SPGNfjZIw2xjD3cx6s/G/vhfPPjue67ncEMhSUb3M82MQErSuwu7j4GHKdmfr8+mJB1oZ2nzPkGjHABwO/u1vf79nzVboYLwy4IqCk0EmOTz85Ue5sk51NN2T2qzqUonHEFXxH0kAlyVrMV33FMwEE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com; spf=pass smtp.mailfrom=samsung.com; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b=I0jgdHcM; arc=none smtp.client-ip=203.254.224.25 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=samsung.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="I0jgdHcM" Received: from epcas5p2.samsung.com (unknown [182.195.41.40]) by mailout2.samsung.com (KnoxPortal) with ESMTP id 20260109124513epoutp026491f5ec5e684ad83a4e815c7ec1e4d9~JELiki1eu1955219552epoutp02Z for ; Fri, 9 Jan 2026 12:45:13 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.samsung.com 20260109124513epoutp026491f5ec5e684ad83a4e815c7ec1e4d9~JELiki1eu1955219552epoutp02Z DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1767962713; bh=p94qzV25B2KBKjmHgA84WrlOtxJ8Ue2QOEDO24cUz2c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=I0jgdHcMUdCSQv9Oeuz9jO3Jn+5+LqZH7s2JnlBSVfH0J7mFh5sxuKEmSdfwp9tMa oWmf/F22QIYW3ySGSGTZQpzXwCKoGG2BYoMicHPsnY8t0dniXo3o61cP62gBMnr9Iz JOGBIz+vDEIuCt0ZxzvhVE44U7rcOz3K3Tb/fX3c= Received: from epsnrtp02.localdomain (unknown [182.195.42.154]) by epcas5p1.samsung.com (KnoxPortal) with ESMTPS id 20260109124513epcas5p1950c48a778b42bc6a9136c8e0113ea82~JELiJbAhk2895828958epcas5p1a; Fri, 9 Jan 2026 12:45:13 +0000 (GMT) Received: from epcas5p2.samsung.com (unknown [182.195.38.86]) by epsnrtp02.localdomain (Postfix) with ESMTP id 4dnhLw58Hdz2SSKX; Fri, 9 Jan 2026 12:45:12 +0000 (GMT) Received: from epsmtip1.samsung.com (unknown [182.195.34.30]) by epcas5p4.samsung.com (KnoxPortal) with ESMTPA id 20260109124512epcas5p4a6d8c2b9c6cf7cf794d1a477eaee7865~JELhEoIFR1015010150epcas5p46; Fri, 9 Jan 2026 12:45:12 +0000 (GMT) Received: from test-PowerEdge-R740xd.samsungds.net (unknown [107.99.41.79]) by epsmtip1.samsung.com (KnoxPortal) with ESMTPA id 20260109124505epsmtip19eb0b7448f062ca1f42cc18fd95e9813~JELaZEb8o0972509725epsmtip1V; Fri, 9 Jan 2026 12:45:04 +0000 (GMT) From: Neeraj Kumar To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev, linux-kernel@vger.kernel.org, gost.dev@samsung.com Cc: a.manzanares@samsung.com, vishak.g@samsung.com, neeraj.kernel@gmail.com, Neeraj Kumar Subject: [PATCH V5 04/17] nvdimm/label: Include region label in slot validation Date: Fri, 9 Jan 2026 18:14:24 +0530 Message-Id: <20260109124437.4025893-5-s.neeraj@samsung.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260109124437.4025893-1-s.neeraj@samsung.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CMS-MailID: 20260109124512epcas5p4a6d8c2b9c6cf7cf794d1a477eaee7865 X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" CMS-TYPE: 105P cpgsPolicy: CPGSC10-542,Y X-CFilter-Loop: Reflected X-CMS-RootMailID: 20260109124512epcas5p4a6d8c2b9c6cf7cf794d1a477eaee7865 References: <20260109124437.4025893-1-s.neeraj@samsung.com> Prior to LSA 2.1 Support, label in slot means only namespace label. But with LSA 2.1 a label can be either namespace or region label. Slot validation routine validates label slot by calculating label checksum. It was only validating namespace label. This changeset also validates region label if present. In previous patch to_lsa_label() was introduced along with to_label(). to_label() returns only namespace label whereas to_lsa_label() returns union nd_lsa_label* In this patch We have converted all usage of to_label() to to_lsa_label() Reviewed-by: Jonathan Cameron Reviewed-by: Dave Jiang Signed-off-by: Neeraj Kumar Reviewed-by: Ira Weiny --- drivers/nvdimm/label.c | 94 ++++++++++++++++++++++++++++-------------- 1 file changed, 64 insertions(+), 30 deletions(-) diff --git a/drivers/nvdimm/label.c b/drivers/nvdimm/label.c index 17e2a1f5a6da..9854cb45fb62 100644 --- a/drivers/nvdimm/label.c +++ b/drivers/nvdimm/label.c @@ -312,16 +312,6 @@ static union nd_lsa_label *to_lsa_label(struct nvdimm_= drvdata *ndd, int slot) return (union nd_lsa_label *) label; } =20 -static struct nd_namespace_label *to_label(struct nvdimm_drvdata *ndd, int= slot) -{ - unsigned long label, base; - - base =3D (unsigned long) nd_label_base(ndd); - label =3D base + sizeof_namespace_label(ndd) * slot; - - return (struct nd_namespace_label *) label; -} - #define for_each_clear_bit_le(bit, addr, size) \ for ((bit) =3D find_next_zero_bit_le((addr), (size), 0); \ (bit) < (size); \ @@ -382,7 +372,7 @@ static bool nsl_validate_checksum(struct nvdimm_drvdata= *ndd, { u64 sum, sum_save; =20 - if (!ndd->cxl && !efi_namespace_label_has(ndd, checksum)) + if (!efi_namespace_label_has(ndd, checksum)) return true; =20 sum_save =3D nsl_get_checksum(ndd, nd_label); @@ -397,13 +387,25 @@ static void nsl_calculate_checksum(struct nvdimm_drvd= ata *ndd, { u64 sum; =20 - if (!ndd->cxl && !efi_namespace_label_has(ndd, checksum)) + if (!efi_namespace_label_has(ndd, checksum)) return; nsl_set_checksum(ndd, nd_label, 0); sum =3D nd_fletcher64(nd_label, sizeof_namespace_label(ndd), 1); nsl_set_checksum(ndd, nd_label, sum); } =20 +static bool region_label_validate_checksum(struct nvdimm_drvdata *ndd, + struct cxl_region_label *region_label) +{ + u64 sum, sum_save; + + sum_save =3D __le64_to_cpu(region_label->checksum); + region_label->checksum =3D __cpu_to_le64(0); + sum =3D nd_fletcher64(region_label, sizeof_namespace_label(ndd), 1); + region_label->checksum =3D __cpu_to_le64(sum_save); + return sum =3D=3D sum_save; +} + static void region_label_calculate_checksum(struct nvdimm_drvdata *ndd, struct cxl_region_label *region_label) { @@ -415,16 +417,34 @@ static void region_label_calculate_checksum(struct nv= dimm_drvdata *ndd, } =20 static bool slot_valid(struct nvdimm_drvdata *ndd, - struct nd_namespace_label *nd_label, u32 slot) + union nd_lsa_label *lsa_label, u32 slot) { + struct cxl_region_label *region_label =3D &lsa_label->region_label; + struct nd_namespace_label *nd_label =3D &lsa_label->ns_label; + enum label_type type; bool valid; + static const char * const label_name[] =3D { + [RG_LABEL_TYPE] =3D "region", + [NS_LABEL_TYPE] =3D "namespace", + }; =20 /* check that we are written where we expect to be written */ - if (slot !=3D nsl_get_slot(ndd, nd_label)) - return false; - valid =3D nsl_validate_checksum(ndd, nd_label); + if (is_region_label(ndd, lsa_label)) { + type =3D RG_LABEL_TYPE; + if (slot !=3D __le32_to_cpu(region_label->slot)) + return false; + valid =3D region_label_validate_checksum(ndd, region_label); + } else { + type =3D NS_LABEL_TYPE; + if (slot !=3D nsl_get_slot(ndd, nd_label)) + return false; + valid =3D nsl_validate_checksum(ndd, nd_label); + } + if (!valid) - dev_dbg(ndd->dev, "fail checksum. slot: %d\n", slot); + dev_dbg(ndd->dev, "%s label checksum fail. slot: %d\n", + label_name[type], slot); + return valid; } =20 @@ -440,14 +460,16 @@ int nd_label_reserve_dpa(struct nvdimm_drvdata *ndd) for_each_clear_bit_le(slot, free, nslot) { struct nd_namespace_label *nd_label; struct nd_region *nd_region =3D NULL; + union nd_lsa_label *lsa_label; struct nd_label_id label_id; struct resource *res; uuid_t label_uuid; u32 flags; =20 - nd_label =3D to_label(ndd, slot); + lsa_label =3D to_lsa_label(ndd, slot); + nd_label =3D &lsa_label->ns_label; =20 - if (!slot_valid(ndd, nd_label, slot)) + if (!slot_valid(ndd, lsa_label, slot)) continue; =20 nsl_get_uuid(ndd, nd_label, &label_uuid); @@ -598,18 +620,30 @@ int nd_label_active_count(struct nvdimm_drvdata *ndd) return 0; =20 for_each_clear_bit_le(slot, free, nslot) { + struct cxl_region_label *region_label; struct nd_namespace_label *nd_label; - - nd_label =3D to_label(ndd, slot); - - if (!slot_valid(ndd, nd_label, slot)) { - u32 label_slot =3D nsl_get_slot(ndd, nd_label); - u64 size =3D nsl_get_rawsize(ndd, nd_label); - u64 dpa =3D nsl_get_dpa(ndd, nd_label); + union nd_lsa_label *lsa_label; + u32 lslot; + u64 size, dpa; + + lsa_label =3D to_lsa_label(ndd, slot); + nd_label =3D &lsa_label->ns_label; + region_label =3D &lsa_label->region_label; + + if (!slot_valid(ndd, lsa_label, slot)) { + if (is_region_label(ndd, lsa_label)) { + lslot =3D __le32_to_cpu(region_label->slot); + size =3D __le64_to_cpu(region_label->rawsize); + dpa =3D __le64_to_cpu(region_label->dpa); + } else { + lslot =3D nsl_get_slot(ndd, nd_label); + size =3D nsl_get_rawsize(ndd, nd_label); + dpa =3D nsl_get_dpa(ndd, nd_label); + } =20 dev_dbg(ndd->dev, "slot%d invalid slot: %d dpa: %llx size: %llx\n", - slot, label_slot, dpa, size); + slot, lslot, dpa, size); continue; } count++; @@ -627,10 +661,10 @@ union nd_lsa_label *nd_label_active(struct nvdimm_drv= data *ndd, int n) return NULL; =20 for_each_clear_bit_le(slot, free, nslot) { - struct nd_namespace_label *nd_label; + union nd_lsa_label *lsa_label; =20 - nd_label =3D to_label(ndd, slot); - if (!slot_valid(ndd, nd_label, slot)) + lsa_label =3D to_lsa_label(ndd, slot); + if (!slot_valid(ndd, lsa_label, slot)) continue; =20 if (n-- =3D=3D 0) --=20 2.34.1 From nobody Sun Feb 8 15:08:14 2026 Received: from mailout4.samsung.com (mailout4.samsung.com [203.254.224.34]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2C00535CB66 for ; Fri, 9 Jan 2026 12:45:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=203.254.224.34 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962721; cv=none; b=i4QNKqTHptp7eY14xFlBcacyTSsOlTWExzXwVUiAHE3XfoQVRLSac1/fbKwFLSdCQfPcPSpL6ICPjGiPX2dvh2+/BaRoJzzZe1S6+wWeM1NDgADqNftvpfqK4GXd5HMaj5calc+hlyWAWjoadhYT+AYSjJhrxpila9Jkop7dlsU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962721; c=relaxed/simple; bh=7wS8SF5L1SMjyiUjc9IW0gH8hSECl7p9MepOxkO2ydE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:MIME-Version: Content-Type:References; b=bqqyW0xt32TjL+Lqzy4jPDbDv/GxbmBJkZXAKaZHh36LwT8YuQFmFL4CbpeNeMdwergx2HQ0HWhFWXA4GyuYBw2fCHudN1iHB2U45cr/aBeFAXDTDCH3qS/mANrIkprq8rMOIslPKpmpkW0kb9emtA5ze4vGHXNgkI7c7vTBlUQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com; spf=pass smtp.mailfrom=samsung.com; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b=Rq6cst+r; arc=none smtp.client-ip=203.254.224.34 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=samsung.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="Rq6cst+r" Received: from epcas5p1.samsung.com (unknown [182.195.41.39]) by mailout4.samsung.com (KnoxPortal) with ESMTP id 20260109124518epoutp04ed9843afd7c0c51a24e975b027533595~JELm1Kx780571205712epoutp04G for ; Fri, 9 Jan 2026 12:45:18 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout4.samsung.com 20260109124518epoutp04ed9843afd7c0c51a24e975b027533595~JELm1Kx780571205712epoutp04G DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1767962718; bh=NbPWNi0pzEvD5YwskenIcUOkOu9snU3PvuKwTqmm89o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Rq6cst+rKFHMwiGDdL27HIWw60e2sOi1khkcMICpgUOFbiTKzE0d9jLco8U4B/icl gj6PsaHrO/c1vEf2UpLwBkLyNNtOdCzvOhN0uU45vDRftVQH3y9bxq+coyyVHEKXKO o7vHjFnhtSUmiz8OBhDE8kkH3EVQb4CsADcvLAts= Received: from epsnrtp01.localdomain (unknown [182.195.42.153]) by epcas5p2.samsung.com (KnoxPortal) with ESMTPS id 20260109124518epcas5p2ddd891883a94dd91d0232011f23ce8c5~JELmlkLCX2134121341epcas5p2T; Fri, 9 Jan 2026 12:45:18 +0000 (GMT) Received: from epcas5p4.samsung.com (unknown [182.195.38.92]) by epsnrtp01.localdomain (Postfix) with ESMTP id 4dnhM149vFz6B9m4; Fri, 9 Jan 2026 12:45:17 +0000 (GMT) Received: from epsmtip1.samsung.com (unknown [182.195.34.30]) by epcas5p3.samsung.com (KnoxPortal) with ESMTPA id 20260109124517epcas5p3d11e7d0941bcf34c74a789917c8aa0d0~JELlgdbO52082420824epcas5p3W; Fri, 9 Jan 2026 12:45:17 +0000 (GMT) Received: from test-PowerEdge-R740xd.samsungds.net (unknown [107.99.41.79]) by epsmtip1.samsung.com (KnoxPortal) with ESMTPA id 20260109124513epsmtip187a144b008f6dc82eb6ca676db476585~JELilYP910977109771epsmtip1l; Fri, 9 Jan 2026 12:45:13 +0000 (GMT) From: Neeraj Kumar To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev, linux-kernel@vger.kernel.org, gost.dev@samsung.com Cc: a.manzanares@samsung.com, vishak.g@samsung.com, neeraj.kernel@gmail.com, Neeraj Kumar Subject: [PATCH V5 05/17] nvdimm/label: Skip region label during ns label DPA reservation Date: Fri, 9 Jan 2026 18:14:25 +0530 Message-Id: <20260109124437.4025893-6-s.neeraj@samsung.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260109124437.4025893-1-s.neeraj@samsung.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CMS-MailID: 20260109124517epcas5p3d11e7d0941bcf34c74a789917c8aa0d0 X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" CMS-TYPE: 105P cpgsPolicy: CPGSC10-542,Y X-CFilter-Loop: Reflected X-CMS-RootMailID: 20260109124517epcas5p3d11e7d0941bcf34c74a789917c8aa0d0 References: <20260109124437.4025893-1-s.neeraj@samsung.com> CXL 3.2 Spec mentions CXL LSA 2.1 Namespace Labels at section 9.13.2.5. If Namespace label is present in LSA during nvdimm_probe() then dimm-physical-address(DPA) reservation is required. But this reservation is not required by cxl region label. Therefore if LSA scanning finds any region label, skip it. Reviewed-by: Dave Jiang Signed-off-by: Neeraj Kumar Reviewed-by: Ira Weiny Reviewed-by: Jonathan Cameron --- drivers/nvdimm/label.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/nvdimm/label.c b/drivers/nvdimm/label.c index 9854cb45fb62..169692dfa12c 100644 --- a/drivers/nvdimm/label.c +++ b/drivers/nvdimm/label.c @@ -469,6 +469,14 @@ int nd_label_reserve_dpa(struct nvdimm_drvdata *ndd) lsa_label =3D to_lsa_label(ndd, slot); nd_label =3D &lsa_label->ns_label; =20 + /* + * Skip region label. If LSA label is region label + * then it don't require dimm-physical-address(DPA) + * reservation. Whereas its required for namespace label + */ + if (is_region_label(ndd, lsa_label)) + continue; + if (!slot_valid(ndd, lsa_label, slot)) continue; =20 --=20 2.34.1 From nobody Sun Feb 8 15:08:14 2026 Received: from mailout2.samsung.com (mailout2.samsung.com [203.254.224.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E556035BDBC for ; Fri, 9 Jan 2026 12:45:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=203.254.224.25 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962723; cv=none; b=UeHPP+moArDsdSynW7m+K8cZcJm+RB+cQz16zbv8EVqqEwwTsjzLGnsZyzsv6hmWL8XfZVCNd2WY54zypK3smJf7n0sUEPld/J2g1MQ64zWZVs4LaMaaclQHSb9X4j3SnfKhhdJnXJYPzWk6MccS+WcYOoslzpB8LIJrXMbFLFo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962723; c=relaxed/simple; bh=Vl6QRqBDVWeDPdvPoeu6lPZ41lV+RQ4xt5L2bqTpzrs=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:MIME-Version: Content-Type:References; b=GIJigtV6dE6l0xJ4RoFW+FfPU0l4FElb0vm/t1Ov25+WXqPxyu8ZX8UWxqWrxPTmlOnpDFE7gOVLWUb8J1mH1QMGnYWvYx4MCabyKral/B9If8BUjts2Q5G6oGljirj5gjVkWiuQg9pplIgv+B/4ethUNf0jZiDm04btYFB4lpc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com; spf=pass smtp.mailfrom=samsung.com; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b=OPlbjTXk; arc=none smtp.client-ip=203.254.224.25 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=samsung.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="OPlbjTXk" Received: from epcas5p1.samsung.com (unknown [182.195.41.39]) by mailout2.samsung.com (KnoxPortal) with ESMTP id 20260109124520epoutp0278ae1a0af38be063b17934d9a7ed6234~JELodczUx2083220832epoutp02j for ; Fri, 9 Jan 2026 12:45:20 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.samsung.com 20260109124520epoutp0278ae1a0af38be063b17934d9a7ed6234~JELodczUx2083220832epoutp02j DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1767962720; bh=c7T6ZJ4KXocop9UUK8AuZEyn63B7t7oAxoInpDQTVkc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OPlbjTXktLc/wSdAnMvrJcYcPFwUsunYhy9N5+7H81c/S1o19b8KaRce7iY0zAQy6 zCFsEJaoU3z24Jpau0kAj9wy4HW4v0/UIq9xTdOmfe5gVtawFG4E2pGadGK989xGyv tISvhY1EyUmlRF4/Cf7Kk2Cj6cY5L+NXFOZ3Y+cU= Received: from epsnrtp03.localdomain (unknown [182.195.42.155]) by epcas5p3.samsung.com (KnoxPortal) with ESMTPS id 20260109124519epcas5p309bfdb17e5d9533261b40c7991c631c8~JELn09XOe2029020290epcas5p3q; Fri, 9 Jan 2026 12:45:19 +0000 (GMT) Received: from epcas5p4.samsung.com (unknown [182.195.38.93]) by epsnrtp03.localdomain (Postfix) with ESMTP id 4dnhM26510z3hhT4; Fri, 9 Jan 2026 12:45:18 +0000 (GMT) Received: from epsmtip1.samsung.com (unknown [182.195.34.30]) by epcas5p2.samsung.com (KnoxPortal) with ESMTPA id 20260109124518epcas5p26832d0b4ae4017cb3afbd613bf58eabd~JELmzoVZa2073820738epcas5p2W; Fri, 9 Jan 2026 12:45:18 +0000 (GMT) Received: from test-PowerEdge-R740xd.samsungds.net (unknown [107.99.41.79]) by epsmtip1.samsung.com (KnoxPortal) with ESMTPA id 20260109124517epsmtip14cf401a10c2622402698c0de1eb6b24d~JELlvXoOr0972509725epsmtip1Y; Fri, 9 Jan 2026 12:45:17 +0000 (GMT) From: Neeraj Kumar To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev, linux-kernel@vger.kernel.org, gost.dev@samsung.com Cc: a.manzanares@samsung.com, vishak.g@samsung.com, neeraj.kernel@gmail.com, Neeraj Kumar Subject: [PATCH V5 06/17] nvdimm/label: Preserve region label during namespace creation Date: Fri, 9 Jan 2026 18:14:26 +0530 Message-Id: <20260109124437.4025893-7-s.neeraj@samsung.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260109124437.4025893-1-s.neeraj@samsung.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CMS-MailID: 20260109124518epcas5p26832d0b4ae4017cb3afbd613bf58eabd X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" CMS-TYPE: 105P cpgsPolicy: CPGSC10-542,Y X-CFilter-Loop: Reflected X-CMS-RootMailID: 20260109124518epcas5p26832d0b4ae4017cb3afbd613bf58eabd References: <20260109124437.4025893-1-s.neeraj@samsung.com> During namespace creation we scan labels present in LSA using scan_labels(). Currently scan_labels() is only preserving namespace labels into label_ent list. In this patch we also preserve region label into label_ent list Reviewed-by: Dave Jiang Signed-off-by: Neeraj Kumar Reviewed-by: Ira Weiny Reviewed-by: Jonathan Cameron --- drivers/nvdimm/namespace_devs.c | 47 +++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_dev= s.c index 657004021c95..8411f4152319 100644 --- a/drivers/nvdimm/namespace_devs.c +++ b/drivers/nvdimm/namespace_devs.c @@ -1994,9 +1994,32 @@ static struct device **scan_labels(struct nd_region = *nd_region) =20 if (count =3D=3D 0) { struct nd_namespace_pmem *nspm; + for (i =3D 0; i < nd_region->ndr_mappings; i++) { + struct cxl_region_label *region_label; + struct nd_label_ent *le, *e; + LIST_HEAD(list); =20 - /* Publish a zero-sized namespace for userspace to configure. */ - nd_mapping_free_labels(nd_mapping); + nd_mapping =3D &nd_region->mapping[i]; + if (list_empty(&nd_mapping->labels)) + continue; + + list_for_each_entry_safe(le, e, &nd_mapping->labels, + list) { + region_label =3D le->region_label; + if (!region_label) + continue; + + /* Preserve region labels if present */ + list_move_tail(&le->list, &list); + } + + /* + * Publish a zero-sized namespace for userspace + * to configure. + */ + nd_mapping_free_labels(nd_mapping); + list_splice_init(&list, &nd_mapping->labels); + } nspm =3D kzalloc(sizeof(*nspm), GFP_KERNEL); if (!nspm) goto err; @@ -2008,7 +2031,7 @@ static struct device **scan_labels(struct nd_region *= nd_region) } else if (is_memory(&nd_region->dev)) { /* clean unselected labels */ for (i =3D 0; i < nd_region->ndr_mappings; i++) { - struct list_head *l, *e; + struct nd_label_ent *le, *e; LIST_HEAD(list); int j; =20 @@ -2019,10 +2042,24 @@ static struct device **scan_labels(struct nd_region= *nd_region) } =20 j =3D count; - list_for_each_safe(l, e, &nd_mapping->labels) { + list_for_each_entry_safe(le, e, &nd_mapping->labels, + list) { + /* Preserve region labels */ + if (uuid_equal(&le->label_uuid, + &cxl_region_uuid)) { + list_move_tail(&le->list, &list); + continue; + } + + /* + * Once preserving selected ns label done + * break out of loop + */ if (!j--) break; - list_move_tail(l, &list); + + /* Preserve selected ns label */ + list_move_tail(&le->list, &list); } nd_mapping_free_labels(nd_mapping); list_splice_init(&list, &nd_mapping->labels); --=20 2.34.1 From nobody Sun Feb 8 15:08:14 2026 Received: from mailout4.samsung.com (mailout4.samsung.com [203.254.224.34]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 21EB135CB8C for ; Fri, 9 Jan 2026 12:45:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=203.254.224.34 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962727; cv=none; b=NdZcxgNbSLpCA5Mrh3i3B9m80NIU87uROoSHAov6/iM0TqxZcJQrDrVddAcxCMsf8Y0vJw9LRl3WIOacGwgspSTABddURWUhewJry8KYX5sud6cBdAwxpM5V1UlZOfpbgM0VyCMIrWg1Oa5YE3ZS0agmF3gDmr/5+wCA70rbLaQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962727; c=relaxed/simple; bh=Uw4WDfXuunKhJeP6S7dLXFRJgAapipZFPKLdVI0wU7Y=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:MIME-Version: Content-Type:References; b=rp016WwLbjF0ayjl96uIvjpozyxiBkoETeC0+GhfUsQ/btLFJWBvKPEzJdTEiC/0LZFrFq61I0cAjuOS9L6bvYGc63W2r4n1QQWEp/QrNvTsDGIvu2OlHoGERZ8qVGlCSKRLt+VY366LJrz4I0VM+HlUHDj3W3nKrAkMLBAIduk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com; spf=pass smtp.mailfrom=samsung.com; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b=BgfgAKXO; arc=none smtp.client-ip=203.254.224.34 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=samsung.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="BgfgAKXO" Received: from epcas5p2.samsung.com (unknown [182.195.41.40]) by mailout4.samsung.com (KnoxPortal) with ESMTP id 20260109124522epoutp045f3b417aadc5f0fb33aa2bba8f8b9be4~JELqhiJVm0410704107epoutp04E for ; Fri, 9 Jan 2026 12:45:22 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout4.samsung.com 20260109124522epoutp045f3b417aadc5f0fb33aa2bba8f8b9be4~JELqhiJVm0410704107epoutp04E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1767962722; bh=OlEn5fbnpL7fm6LPBp1hOH6sSNbq7MHBsml7Ep/to+s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BgfgAKXO0Bu1Abz3+GcQomHmQN4/XzmQQwfjcwDsGNaqs5HFRfZ7VYsfoiLMtuqaW Yl2u87T2LN9P6hmeISghDQzq1JqU0s3WYwvLbxQu3XM2kvWC7xCtJY/QRNXXSSsybY De+hX7LGewSi7mPqJHRCon5pMran2MS3slgwZfw0= Received: from epsnrtp03.localdomain (unknown [182.195.42.155]) by epcas5p3.samsung.com (KnoxPortal) with ESMTPS id 20260109124522epcas5p3c9f8177c358abe44f64a9412f2f1678b~JELqKJTlQ2082420824epcas5p3h; Fri, 9 Jan 2026 12:45:22 +0000 (GMT) Received: from epcas5p1.samsung.com (unknown [182.195.38.92]) by epsnrtp03.localdomain (Postfix) with ESMTP id 4dnhM52w8lz3hhT3; Fri, 9 Jan 2026 12:45:21 +0000 (GMT) Received: from epsmtip1.samsung.com (unknown [182.195.34.30]) by epcas5p4.samsung.com (KnoxPortal) with ESMTPA id 20260109124519epcas5p44c534dd371d670f569277bd2eaa825a7~JELoJZBn51264312643epcas5p4C; Fri, 9 Jan 2026 12:45:19 +0000 (GMT) Received: from test-PowerEdge-R740xd.samsungds.net (unknown [107.99.41.79]) by epsmtip1.samsung.com (KnoxPortal) with ESMTPA id 20260109124518epsmtip1d2aeb5c6dfa3d0e28762b45a064896e1~JELnCvYyK0977009770epsmtip1c; Fri, 9 Jan 2026 12:45:18 +0000 (GMT) From: Neeraj Kumar To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev, linux-kernel@vger.kernel.org, gost.dev@samsung.com Cc: a.manzanares@samsung.com, vishak.g@samsung.com, neeraj.kernel@gmail.com, Neeraj Kumar Subject: [PATCH V5 07/17] nvdimm/label: Add region label delete support Date: Fri, 9 Jan 2026 18:14:27 +0530 Message-Id: <20260109124437.4025893-8-s.neeraj@samsung.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260109124437.4025893-1-s.neeraj@samsung.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CMS-MailID: 20260109124519epcas5p44c534dd371d670f569277bd2eaa825a7 X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" CMS-TYPE: 105P cpgsPolicy: CPGSC10-542,Y X-CFilter-Loop: Reflected X-CMS-RootMailID: 20260109124519epcas5p44c534dd371d670f569277bd2eaa825a7 References: <20260109124437.4025893-1-s.neeraj@samsung.com> Create export routine nd_region_label_delete() used for deleting region label from LSA. It will be used later from CXL subsystem Reviewed-by: Dave Jiang Reviewed-by: Jonathan Cameron Signed-off-by: Neeraj Kumar Reviewed-by: Ira Weiny --- drivers/nvdimm/label.c | 74 ++++++++++++++++++++++++++++++--- drivers/nvdimm/label.h | 1 + drivers/nvdimm/namespace_devs.c | 7 ++++ drivers/nvdimm/nd.h | 6 +++ include/linux/libnvdimm.h | 1 + 5 files changed, 83 insertions(+), 6 deletions(-) diff --git a/drivers/nvdimm/label.c b/drivers/nvdimm/label.c index 169692dfa12c..2ad148bfe40b 100644 --- a/drivers/nvdimm/label.c +++ b/drivers/nvdimm/label.c @@ -1229,7 +1229,8 @@ static int init_labels(struct nd_mapping *nd_mapping,= int num_labels, return max(num_labels, old_num_labels); } =20 -static int del_labels(struct nd_mapping *nd_mapping, uuid_t *uuid) +static int del_labels(struct nd_mapping *nd_mapping, uuid_t *uuid, + enum label_type ltype) { struct nvdimm_drvdata *ndd =3D to_ndd(nd_mapping); struct nd_label_ent *label_ent, *e; @@ -1248,11 +1249,24 @@ static int del_labels(struct nd_mapping *nd_mapping= , uuid_t *uuid) =20 mutex_lock(&nd_mapping->lock); list_for_each_entry_safe(label_ent, e, &nd_mapping->labels, list) { - if (label_ent->label) + if ((ltype =3D=3D NS_LABEL_TYPE && !label_ent->label) || + (ltype =3D=3D RG_LABEL_TYPE && !label_ent->region_label)) continue; active++; - if (!nsl_uuid_equal(ndd, label_ent->label, uuid)) - continue; + + switch (ltype) { + case NS_LABEL_TYPE: + if (!nsl_uuid_equal(ndd, label_ent->label, uuid)) + continue; + + break; + case RG_LABEL_TYPE: + if (!region_label_uuid_equal(label_ent->region_label, uuid)) + continue; + + break; + } + active--; slot =3D to_slot(ndd, label_ent); nd_label_free_slot(ndd, slot); @@ -1261,10 +1275,12 @@ static int del_labels(struct nd_mapping *nd_mapping= , uuid_t *uuid) =20 if (uuid_equal(&cxl_namespace_uuid, &label_ent->label_uuid)) label_ent->label =3D NULL; + else + label_ent->region_label =3D NULL; } list_splice_tail_init(&list, &nd_mapping->labels); =20 - if (active =3D=3D 0) { + if ((ltype =3D=3D NS_LABEL_TYPE) && (active =3D=3D 0)) { nd_mapping_free_labels(nd_mapping); dev_dbg(ndd->dev, "no more active labels\n"); } @@ -1300,7 +1316,8 @@ int nd_pmem_namespace_label_update(struct nd_region *= nd_region, int count =3D 0; =20 if (size =3D=3D 0) { - rc =3D del_labels(nd_mapping, nspm->uuid); + rc =3D del_labels(nd_mapping, nspm->uuid, + NS_LABEL_TYPE); if (rc) return rc; continue; @@ -1385,6 +1402,51 @@ int nd_pmem_region_label_update(struct nd_region *nd= _region) return 0; } =20 +int nd_pmem_region_label_delete(struct nd_region *nd_region) +{ + struct nd_interleave_set *nd_set =3D nd_region->nd_set; + struct nd_label_ent *label_ent; + int i, rc; + + for (i =3D 0; i < nd_region->ndr_mappings; i++) { + struct nd_mapping *nd_mapping =3D &nd_region->mapping[i]; + struct nvdimm_drvdata *ndd =3D to_ndd(nd_mapping); + + /* Find non cxl format supported ndr_mappings */ + if (!ndd->cxl) { + dev_info(&nd_region->dev, "Unsupported region label\n"); + return -EINVAL; + } + + /* Find if any NS label using this region */ + guard(mutex)(&nd_mapping->lock); + list_for_each_entry(label_ent, &nd_mapping->labels, list) { + if (!label_ent->label) + continue; + + /* + * Check if any available NS labels has same + * region_uuid in LSA + */ + if (nsl_region_uuid_equal(label_ent->label, + &nd_set->uuid)) { + dev_dbg(&nd_region->dev, + "Region/Namespace label in use\n"); + return -EBUSY; + } + } + } + + for (i =3D 0; i < nd_region->ndr_mappings; i++) { + rc =3D del_labels(&nd_region->mapping[i], &nd_set->uuid, + RG_LABEL_TYPE); + if (rc) + return rc; + } + + return 0; +} + int __init nd_label_init(void) { WARN_ON(guid_parse(NVDIMM_BTT_GUID, &nvdimm_btt_guid)); diff --git a/drivers/nvdimm/label.h b/drivers/nvdimm/label.h index f11f54056353..80a7f7dd8ba7 100644 --- a/drivers/nvdimm/label.h +++ b/drivers/nvdimm/label.h @@ -238,4 +238,5 @@ struct nd_namespace_pmem; int nd_pmem_namespace_label_update(struct nd_region *nd_region, struct nd_namespace_pmem *nspm, resource_size_t size); int nd_pmem_region_label_update(struct nd_region *nd_region); +int nd_pmem_region_label_delete(struct nd_region *nd_region); #endif /* __LABEL_H__ */ diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_dev= s.c index 8411f4152319..9047826138be 100644 --- a/drivers/nvdimm/namespace_devs.c +++ b/drivers/nvdimm/namespace_devs.c @@ -239,6 +239,13 @@ int nd_region_label_update(struct nd_region *nd_region) } EXPORT_SYMBOL_GPL(nd_region_label_update); =20 +int nd_region_label_delete(struct nd_region *nd_region) +{ + guard(nvdimm_bus)(&nd_region->dev); + return nd_pmem_region_label_delete(nd_region); +} +EXPORT_SYMBOL_GPL(nd_region_label_delete); + static int nd_namespace_label_update(struct nd_region *nd_region, struct device *dev) { diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h index 1b31eee3028e..92a8eabe0792 100644 --- a/drivers/nvdimm/nd.h +++ b/drivers/nvdimm/nd.h @@ -337,6 +337,12 @@ static inline bool is_region_label(struct nvdimm_drvda= ta *ndd, (uuid_t *)lsa_label->region_label.type); } =20 +static inline bool nsl_region_uuid_equal(struct nd_namespace_label *ns_lab= el, + const uuid_t *uuid) +{ + return uuid_equal((uuid_t *)ns_label->cxl.region_uuid, uuid); +} + static inline bool region_label_uuid_equal(struct cxl_region_label *region_label, const uuid_t *uuid) diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h index 2c213b9dac66..bbf14a260c93 100644 --- a/include/linux/libnvdimm.h +++ b/include/linux/libnvdimm.h @@ -315,6 +315,7 @@ int nvdimm_has_cache(struct nd_region *nd_region); int nvdimm_in_overwrite(struct nvdimm *nvdimm); bool is_nvdimm_sync(struct nd_region *nd_region); int nd_region_label_update(struct nd_region *nd_region); +int nd_region_label_delete(struct nd_region *nd_region); =20 static inline int nvdimm_ctl(struct nvdimm *nvdimm, unsigned int cmd, void= *buf, unsigned int buf_len, int *cmd_rc) --=20 2.34.1 From nobody Sun Feb 8 15:08:14 2026 Received: from mailout1.samsung.com (mailout1.samsung.com [203.254.224.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5293D35CBA9 for ; Fri, 9 Jan 2026 12:45:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=203.254.224.24 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962727; cv=none; b=FOj2i7lhTsk1lVYsp7AVIIsXOgMM2eZd627Hc/iqAKP3tNAZeP4PuwV8hM9zNdheJaWvUbSWamYPCVZ7I2Hm2ev+3DafcvoMI0Mo/2XP9ikhaVvBCBKFUB0dxaGkP3fSbun4RfcEqDZM2H+UmMegeCIED7hFLp1a7HzdzfFYX4M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962727; c=relaxed/simple; bh=AoRGNftAmC02ctoU04552onWjzNbxK1TWIBQGzW2rDE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:MIME-Version: Content-Type:References; b=H+qdam6dF9Xom3PR3gjk4uk/1YSaHepIuPH0/VchFw6Lbre4WSRtwIAPDo7Jy6JWsFGSJMs7da3R2Ag4564pCwl+cXzS8vNAIh87hI4S+dNyIar29gwZzB+MlF8IADtj710F3ukkQiQO+u8EdJ2q73HGZ2PBu+SM5u77AWlpxgY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com; spf=pass smtp.mailfrom=samsung.com; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b=tWlQ03Gw; arc=none smtp.client-ip=203.254.224.24 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=samsung.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="tWlQ03Gw" Received: from epcas5p4.samsung.com (unknown [182.195.41.42]) by mailout1.samsung.com (KnoxPortal) with ESMTP id 20260109124522epoutp01e155528c6715a86c806a7583cb58d3fb~JELq3K5SO0753707537epoutp01G for ; Fri, 9 Jan 2026 12:45:22 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.samsung.com 20260109124522epoutp01e155528c6715a86c806a7583cb58d3fb~JELq3K5SO0753707537epoutp01G DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1767962722; bh=fcU13rdpIdlC2DLF99ubTX7jfe8rJBe3xxejaA55RRI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tWlQ03GwgKuzNTd4+iLJjRTKkycFxuLjBYd/QI6l7g5jxQTtfSbTKFOtSVAk6B3id U/CAO3yfqzret+03CTAA85cgQpl8DkXE0YUuCBfBlnOr9sjrvtuTP21gaRw91fENPk p4Wp21gKIlMfxi22cX+zl5Ei/x4KPQhiO2MEudI0= Received: from epsnrtp02.localdomain (unknown [182.195.42.154]) by epcas5p1.samsung.com (KnoxPortal) with ESMTPS id 20260109124522epcas5p1b3f49faa514c9ea4fdcff0d77e69fe8c~JELqpVNkI1268212682epcas5p17; Fri, 9 Jan 2026 12:45:22 +0000 (GMT) Received: from epcas5p3.samsung.com (unknown [182.195.38.91]) by epsnrtp02.localdomain (Postfix) with ESMTP id 4dnhM56Sp8z2SSKY; Fri, 9 Jan 2026 12:45:21 +0000 (GMT) Received: from epsmtip1.samsung.com (unknown [182.195.34.30]) by epcas5p2.samsung.com (KnoxPortal) with ESMTPA id 20260109124521epcas5p299cea0eaef023816e18f5fd32d053224~JELpioP_v3225732257epcas5p20; Fri, 9 Jan 2026 12:45:21 +0000 (GMT) Received: from test-PowerEdge-R740xd.samsungds.net (unknown [107.99.41.79]) by epsmtip1.samsung.com (KnoxPortal) with ESMTPA id 20260109124520epsmtip1f2c89d44e5102b9892bc8e7882bcadf8~JELoYYipz0977809778epsmtip1m; Fri, 9 Jan 2026 12:45:20 +0000 (GMT) From: Neeraj Kumar To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev, linux-kernel@vger.kernel.org, gost.dev@samsung.com Cc: a.manzanares@samsung.com, vishak.g@samsung.com, neeraj.kernel@gmail.com, Neeraj Kumar Subject: [PATCH V5 08/17] nvdimm/label: Preserve cxl region information from region label Date: Fri, 9 Jan 2026 18:14:28 +0530 Message-Id: <20260109124437.4025893-9-s.neeraj@samsung.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260109124437.4025893-1-s.neeraj@samsung.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CMS-MailID: 20260109124521epcas5p299cea0eaef023816e18f5fd32d053224 X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" CMS-TYPE: 105P cpgsPolicy: CPGSC10-542,Y X-CFilter-Loop: Reflected X-CMS-RootMailID: 20260109124521epcas5p299cea0eaef023816e18f5fd32d053224 References: <20260109124437.4025893-1-s.neeraj@samsung.com> Preserve region information from region label during nvdimm_probe. This preserved region information is used for creating cxl region to achieve region persistency across reboot. This patch supports interleave way =3D=3D 1, it is therefore it preserves only one region into LSA Reviewed-by: Dave Jiang Signed-off-by: Neeraj Kumar Reviewed-by: Ira Weiny Reviewed-by: Jonathan Cameron --- drivers/nvdimm/dimm.c | 4 ++++ drivers/nvdimm/label.c | 36 ++++++++++++++++++++++++++++++++++++ drivers/nvdimm/nd-core.h | 2 ++ drivers/nvdimm/nd.h | 1 + include/linux/libnvdimm.h | 14 ++++++++++++++ 5 files changed, 57 insertions(+) diff --git a/drivers/nvdimm/dimm.c b/drivers/nvdimm/dimm.c index 07f5c5d5e537..590ec883903d 100644 --- a/drivers/nvdimm/dimm.c +++ b/drivers/nvdimm/dimm.c @@ -107,6 +107,10 @@ static int nvdimm_probe(struct device *dev) if (rc) goto err; =20 + /* Preserve cxl region info if available */ + if (ndd->cxl) + nvdimm_cxl_region_preserve(ndd); + return 0; =20 err: diff --git a/drivers/nvdimm/label.c b/drivers/nvdimm/label.c index 2ad148bfe40b..7adb415f0926 100644 --- a/drivers/nvdimm/label.c +++ b/drivers/nvdimm/label.c @@ -494,6 +494,42 @@ int nd_label_reserve_dpa(struct nvdimm_drvdata *ndd) return 0; } =20 +int nvdimm_cxl_region_preserve(struct nvdimm_drvdata *ndd) +{ + struct nvdimm *nvdimm =3D to_nvdimm(ndd->dev); + struct cxl_pmem_region_params *p =3D &nvdimm->cxl_region_params; + struct nd_namespace_index *nsindex; + unsigned long *free; + u32 nslot, slot; + + if (!preamble_current(ndd, &nsindex, &free, &nslot)) + return 0; /* no label, nothing to preserve */ + + for_each_clear_bit_le(slot, free, nslot) { + union nd_lsa_label *lsa_label =3D to_lsa_label(ndd, slot); + struct cxl_region_label *region_label =3D &lsa_label->region_label; + uuid_t *region_uuid =3D (uuid_t *)®ion_label->type; + + /* TODO: Currently preserving only one region */ + if (uuid_equal(&cxl_region_uuid, region_uuid)) { + nvdimm->is_region_label =3D true; + import_uuid(&p->uuid, region_label->uuid); + p->flags =3D __le32_to_cpu(region_label->flags); + p->nlabel =3D __le16_to_cpu(region_label->nlabel); + p->position =3D __le16_to_cpu(region_label->position); + p->dpa =3D __le64_to_cpu(region_label->dpa); + p->rawsize =3D __le64_to_cpu(region_label->rawsize); + p->hpa =3D __le64_to_cpu(region_label->hpa); + p->slot =3D __le32_to_cpu(region_label->slot); + p->ig =3D __le32_to_cpu(region_label->ig); + p->align =3D __le32_to_cpu(region_label->align); + break; + } + } + + return 0; +} + int nd_label_data_init(struct nvdimm_drvdata *ndd) { size_t config_size, read_size, max_xfer, offset; diff --git a/drivers/nvdimm/nd-core.h b/drivers/nvdimm/nd-core.h index bfc6bfeb6e24..a73fac81531e 100644 --- a/drivers/nvdimm/nd-core.h +++ b/drivers/nvdimm/nd-core.h @@ -46,6 +46,8 @@ struct nvdimm { } sec; struct delayed_work dwork; const struct nvdimm_fw_ops *fw_ops; + bool is_region_label; + struct cxl_pmem_region_params cxl_region_params; }; =20 static inline unsigned long nvdimm_security_flags( diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h index 92a8eabe0792..86837de7f183 100644 --- a/drivers/nvdimm/nd.h +++ b/drivers/nvdimm/nd.h @@ -580,6 +580,7 @@ void nvdimm_set_locked(struct device *dev); void nvdimm_clear_locked(struct device *dev); int nvdimm_security_setup_events(struct device *dev); bool nvdimm_region_label_supported(struct device *dev); +int nvdimm_cxl_region_preserve(struct nvdimm_drvdata *ndd); #if IS_ENABLED(CONFIG_NVDIMM_KEYS) int nvdimm_security_unlock(struct device *dev); #else diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h index bbf14a260c93..07ea2e3f821a 100644 --- a/include/linux/libnvdimm.h +++ b/include/linux/libnvdimm.h @@ -108,6 +108,20 @@ struct nd_cmd_desc { int out_sizes[ND_CMD_MAX_ELEM]; }; =20 +struct cxl_pmem_region_params { + uuid_t uuid; + u32 flags; + u16 nlabel; + u16 position; + u64 dpa; + u64 rawsize; + u64 hpa; + u32 slot; + u32 ig; + u32 align; + int nr_targets; +}; + struct nd_interleave_set { /* v1.1 definition of the interleave-set-cookie algorithm */ u64 cookie1; --=20 2.34.1 From nobody Sun Feb 8 15:08:14 2026 Received: from mailout1.samsung.com (mailout1.samsung.com [203.254.224.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 24B2535CBBB for ; Fri, 9 Jan 2026 12:45:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=203.254.224.24 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962728; cv=none; b=Tu9OKWCGkS7V5Zz0pK/RzNiz9WrOFPyLTCROoa2XssGzu7SnJ7mDiSootcZ/lsyZldqj2K78ZT8w/R7m49ILgkZygo6jqD9MOJK2fZYEYxFaDWFk/YGIDGMSTll4prj42vQ2mWGQmSrz/8XTRHpVU6jXxwU4ELHVH4LehwXt3VI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962728; c=relaxed/simple; bh=2Oi5A2UjUY179mivkwDPYpVWvRqXcm+rbcVcLWgLV+4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:MIME-Version: Content-Type:References; b=NrqDyPbS8aMLMP+KvSMNRS5ulQ/nkIibkrIbhhNKWiLCLjKvoDRLrDG9lj979ZGUGBxitrYvYtQzu8McpKa7or2Wj/ByowmkRphRHocV2Yx/Np3LP/1nOnDY3cnDZgKi9uGxiYs++OD0wOmyYLNjE3+Ti8iLtUVoGdumc79i0LA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com; spf=pass smtp.mailfrom=samsung.com; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b=MgG4RnQX; arc=none smtp.client-ip=203.254.224.24 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=samsung.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="MgG4RnQX" Received: from epcas5p3.samsung.com (unknown [182.195.41.41]) by mailout1.samsung.com (KnoxPortal) with ESMTP id 20260109124524epoutp010fa07c3682ce7bd69ae7323f354ef75d~JELscZHtA0753707537epoutp01H for ; Fri, 9 Jan 2026 12:45:24 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.samsung.com 20260109124524epoutp010fa07c3682ce7bd69ae7323f354ef75d~JELscZHtA0753707537epoutp01H DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1767962724; bh=AegceBCi2PG2uzv8C4DQpTppHKH8pfEM1iy7MZDMHz0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MgG4RnQXrrYb82v2MzHRuwNrCjvIzu4Qzup0C+Mdgri9QwA0JMJPCi1EVQRS7l5xc j6K8eleQ+BaguhV5fVvSAG1k4Gfqh5B54fsqD0JxDVssbr2yiv3uDAT+IW9007IdEh Dgrfz2O3T/tjmyWyRnyeeSZxbYVVLtXQWl0DbDK4= Received: from epsnrtp04.localdomain (unknown [182.195.42.156]) by epcas5p1.samsung.com (KnoxPortal) with ESMTPS id 20260109124523epcas5p1f32ee165a9243b45d34e89d9bc36335a~JELr6HTPc3012130121epcas5p1X; Fri, 9 Jan 2026 12:45:23 +0000 (GMT) Received: from epcas5p1.samsung.com (unknown [182.195.38.90]) by epsnrtp04.localdomain (Postfix) with ESMTP id 4dnhM722mWz6B9m6; Fri, 9 Jan 2026 12:45:23 +0000 (GMT) Received: from epsmtip1.samsung.com (unknown [182.195.34.30]) by epcas5p2.samsung.com (KnoxPortal) with ESMTPA id 20260109124522epcas5p2ecae638cbd3211d7bdbecacba4ff89f3~JELqy5yfx2073820738epcas5p2c; Fri, 9 Jan 2026 12:45:22 +0000 (GMT) Received: from test-PowerEdge-R740xd.samsungds.net (unknown [107.99.41.79]) by epsmtip1.samsung.com (KnoxPortal) with ESMTPA id 20260109124521epsmtip1f23cf7209b7991dd8715da3d06b63191~JELpsgEtO0977809778epsmtip1n; Fri, 9 Jan 2026 12:45:21 +0000 (GMT) From: Neeraj Kumar To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev, linux-kernel@vger.kernel.org, gost.dev@samsung.com Cc: a.manzanares@samsung.com, vishak.g@samsung.com, neeraj.kernel@gmail.com, Neeraj Kumar Subject: [PATCH V5 09/17] nvdimm/label: Export routine to fetch region information Date: Fri, 9 Jan 2026 18:14:29 +0530 Message-Id: <20260109124437.4025893-10-s.neeraj@samsung.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260109124437.4025893-1-s.neeraj@samsung.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CMS-MailID: 20260109124522epcas5p2ecae638cbd3211d7bdbecacba4ff89f3 X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" CMS-TYPE: 105P cpgsPolicy: CPGSC10-542,Y X-CFilter-Loop: Reflected X-CMS-RootMailID: 20260109124522epcas5p2ecae638cbd3211d7bdbecacba4ff89f3 References: <20260109124437.4025893-1-s.neeraj@samsung.com> CXL region information preserved from the LSA needs to be exported for use by the CXL driver for CXL region re-creation. Reviewed-by: Dave Jiang Signed-off-by: Neeraj Kumar Reviewed-by: Ira Weiny Reviewed-by: Jonathan Cameron --- drivers/nvdimm/dimm_devs.c | 12 ++++++++++++ include/linux/libnvdimm.h | 2 ++ 2 files changed, 14 insertions(+) diff --git a/drivers/nvdimm/dimm_devs.c b/drivers/nvdimm/dimm_devs.c index 3363a97cc5b5..e1c95da92fbf 100644 --- a/drivers/nvdimm/dimm_devs.c +++ b/drivers/nvdimm/dimm_devs.c @@ -280,6 +280,18 @@ void *nvdimm_provider_data(struct nvdimm *nvdimm) } EXPORT_SYMBOL_GPL(nvdimm_provider_data); =20 +bool nvdimm_has_cxl_region(struct nvdimm *nvdimm) +{ + return nvdimm->is_region_label; +} +EXPORT_SYMBOL_GPL(nvdimm_has_cxl_region); + +void *nvdimm_get_cxl_region_param(struct nvdimm *nvdimm) +{ + return &nvdimm->cxl_region_params; +} +EXPORT_SYMBOL_GPL(nvdimm_get_cxl_region_param); + static ssize_t commands_show(struct device *dev, struct device_attribute *attr, char *buf) { diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h index 07ea2e3f821a..3ffd50ab6ac4 100644 --- a/include/linux/libnvdimm.h +++ b/include/linux/libnvdimm.h @@ -330,6 +330,8 @@ int nvdimm_in_overwrite(struct nvdimm *nvdimm); bool is_nvdimm_sync(struct nd_region *nd_region); int nd_region_label_update(struct nd_region *nd_region); int nd_region_label_delete(struct nd_region *nd_region); +bool nvdimm_has_cxl_region(struct nvdimm *nvdimm); +void *nvdimm_get_cxl_region_param(struct nvdimm *nvdimm); =20 static inline int nvdimm_ctl(struct nvdimm *nvdimm, unsigned int cmd, void= *buf, unsigned int buf_len, int *cmd_rc) --=20 2.34.1 From nobody Sun Feb 8 15:08:14 2026 Received: from mailout1.samsung.com (mailout1.samsung.com [203.254.224.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 394E235CBB8 for ; Fri, 9 Jan 2026 12:45:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=203.254.224.24 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962730; cv=none; b=We5QNm7dBMubDOvaRZd3qNwPxivSFWRk9JwnxxZ0qreCLtBUkC1kxOryD5UBo6upDDGaK9L+Kh9IwC+Nc3pmGafVK4fyQcjoNr3l/1QnwKtmyFjyBxFjvhNA6mUEof6OnTXd0HAzBu317B8Wrsqxy1/pfD5NGvRI/nJ2ceXoLpg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962730; c=relaxed/simple; bh=lnbR5frj3QX51jHP5Y4w+RMsDL7kbkgM18LkO1sRaYc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:MIME-Version: Content-Type:References; b=StC/N2MOM1jpki4wHI2JQR+J7hVLxFBS8aRHoqGzQs5uk/kiHOuGrNV7/61bOMcbEb7A/tt9ZSZH/Kw/6nycwUlm8edJrEcvrgzhhF/O4I1wdNmaeR/bxSXpx256o+zURcK3yafJXt9cFpAvvPGLxwk167oUG0+mshg6yKvE9l4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com; spf=pass smtp.mailfrom=samsung.com; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b=UvNrVUlT; arc=none smtp.client-ip=203.254.224.24 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=samsung.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="UvNrVUlT" Received: from epcas5p3.samsung.com (unknown [182.195.41.41]) by mailout1.samsung.com (KnoxPortal) with ESMTP id 20260109124525epoutp01126b8fccafa27c27113288a1418c2f14~JELthairq0794707947epoutp01l for ; Fri, 9 Jan 2026 12:45:25 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.samsung.com 20260109124525epoutp01126b8fccafa27c27113288a1418c2f14~JELthairq0794707947epoutp01l DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1767962725; bh=0iGs6thQ/y+3imRikVjE/q9bQLKbyJDoGhpVJf7OUps=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UvNrVUlTfAl5lGrX1wSKbWB8Hw4ByvLx0TfKW+DMAVloyDWxDdAzFR8d0OT8WY6O0 N8zdiuQXHLbxF3LC36JrOlIBKip153VjTy3Ml8gKziW0RJOEsOUXZYghXHZILI1baL xCjfiHhjuxrsK35/PfY5ilVR8hr256Qu2tOYhAlE= Received: from epsnrtp03.localdomain (unknown [182.195.42.155]) by epcas5p4.samsung.com (KnoxPortal) with ESMTPS id 20260109124525epcas5p4cfa691e5841e4e36cb89db322f95da31~JELtN3Nww0100001000epcas5p4M; Fri, 9 Jan 2026 12:45:25 +0000 (GMT) Received: from epcas5p3.samsung.com (unknown [182.195.38.89]) by epsnrtp03.localdomain (Postfix) with ESMTP id 4dnhM84t1cz3hhT3; Fri, 9 Jan 2026 12:45:24 +0000 (GMT) Received: from epsmtip1.samsung.com (unknown [182.195.34.30]) by epcas5p1.samsung.com (KnoxPortal) with ESMTPA id 20260109124524epcas5p11435563cce6dc392c06951bb07c8bfc3~JELsJIH4Q2911929119epcas5p1k; Fri, 9 Jan 2026 12:45:24 +0000 (GMT) Received: from test-PowerEdge-R740xd.samsungds.net (unknown [107.99.41.79]) by epsmtip1.samsung.com (KnoxPortal) with ESMTPA id 20260109124523epsmtip14d1288b96e5c192068ca86e74446325a~JELrCKc-k0977809778epsmtip1o; Fri, 9 Jan 2026 12:45:22 +0000 (GMT) From: Neeraj Kumar To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev, linux-kernel@vger.kernel.org, gost.dev@samsung.com Cc: a.manzanares@samsung.com, vishak.g@samsung.com, neeraj.kernel@gmail.com, Neeraj Kumar Subject: [PATCH V5 10/17] cxl/mem: Refactor cxl pmem region auto-assembling Date: Fri, 9 Jan 2026 18:14:30 +0530 Message-Id: <20260109124437.4025893-11-s.neeraj@samsung.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260109124437.4025893-1-s.neeraj@samsung.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CMS-MailID: 20260109124524epcas5p11435563cce6dc392c06951bb07c8bfc3 X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" CMS-TYPE: 105P cpgsPolicy: CPGSC10-542,Y X-CFilter-Loop: Reflected X-CMS-RootMailID: 20260109124524epcas5p11435563cce6dc392c06951bb07c8bfc3 References: <20260109124437.4025893-1-s.neeraj@samsung.com> In 84ec985944ef3, devm_cxl_add_nvdimm() sequence was changed and called before devm_cxl_add_endpoint(). It's because cxl pmem region auto-assembly used to get called at last in cxl_endpoint_port_probe(), which requires cxl_nvd presence. For cxl region persistency, region creation happens during nvdimm_probe which need the completion of endpoint probe. In order to accommodate both cxl pmem region auto-assembly and cxl region persistency, refactored following 1. Re-Sequence devm_cxl_add_nvdimm() after devm_cxl_add_endpoint(). This will be called only after successful completion of endpoint probe. 2. Create cxl_region_discovery() which performs pmem region auto-assembly and remove cxl pmem region auto-assembly from cxl_endpoint_port_probe() 3. Register cxl_region_discovery() with devm_cxl_add_memdev() which gets called during cxl_pci_probe() in context of cxl_mem_probe() 4. As cxlmd->ops->probe() calls registered cxl_region_discovery(), so move devm_cxl_add_nvdimm() before cxlmd->ops->probe(). It guarantees both the completion of endpoint probe and cxl_nvd presence before calling cxlmd->ops->probe(). Reviewed-by: Dave Jiang Signed-off-by: Neeraj Kumar Reviewed-by: Jonathan Cameron --- drivers/cxl/core/region.c | 37 +++++++++++++++++++++++++++++++++++++ drivers/cxl/cxl.h | 5 +++++ drivers/cxl/mem.c | 18 +++++++++--------- drivers/cxl/pci.c | 4 +++- drivers/cxl/port.c | 39 +-------------------------------------- 5 files changed, 55 insertions(+), 48 deletions(-) diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c index ae899f68551f..26238fb5e8cf 100644 --- a/drivers/cxl/core/region.c +++ b/drivers/cxl/core/region.c @@ -3727,6 +3727,43 @@ int cxl_add_to_region(struct cxl_endpoint_decoder *c= xled) } EXPORT_SYMBOL_NS_GPL(cxl_add_to_region, "CXL"); =20 +static int discover_region(struct device *dev, void *unused) +{ + struct cxl_endpoint_decoder *cxled; + int rc; + + if (!is_endpoint_decoder(dev)) + return 0; + + cxled =3D to_cxl_endpoint_decoder(dev); + if ((cxled->cxld.flags & CXL_DECODER_F_ENABLE) =3D=3D 0) + return 0; + + if (cxled->state !=3D CXL_DECODER_STATE_AUTO) + return 0; + + /* + * Region enumeration is opportunistic, if this add-event fails, + * continue to the next endpoint decoder. + */ + rc =3D cxl_add_to_region(cxled); + if (rc) + dev_dbg(dev, "failed to add to region: %#llx-%#llx\n", + cxled->cxld.hpa_range.start, cxled->cxld.hpa_range.end); + + return 0; +} + +int cxl_region_discovery(struct cxl_memdev *cxlmd) +{ + struct cxl_port *port =3D cxlmd->endpoint; + + device_for_each_child(&port->dev, NULL, discover_region); + + return 0; +} +EXPORT_SYMBOL_NS_GPL(cxl_region_discovery, "CXL"); + u64 cxl_port_get_spa_cache_alias(struct cxl_port *endpoint, u64 spa) { struct cxl_region_ref *iter; diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h index ba17fa86d249..684a0d1b441a 100644 --- a/drivers/cxl/cxl.h +++ b/drivers/cxl/cxl.h @@ -904,6 +904,7 @@ struct cxl_pmem_region *to_cxl_pmem_region(struct devic= e *dev); int cxl_add_to_region(struct cxl_endpoint_decoder *cxled); struct cxl_dax_region *to_cxl_dax_region(struct device *dev); u64 cxl_port_get_spa_cache_alias(struct cxl_port *endpoint, u64 spa); +int cxl_region_discovery(struct cxl_memdev *cxlmd); #else static inline bool is_cxl_pmem_region(struct device *dev) { @@ -926,6 +927,10 @@ static inline u64 cxl_port_get_spa_cache_alias(struct = cxl_port *endpoint, { return 0; } +static inline int cxl_region_discovery(struct cxl_memdev *cxlmd) +{ + return 0; +} #endif =20 void cxl_endpoint_parse_cdat(struct cxl_port *port); diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c index 13d9e089ecaf..f5e3e2fca86c 100644 --- a/drivers/cxl/mem.c +++ b/drivers/cxl/mem.c @@ -115,15 +115,6 @@ static int cxl_mem_probe(struct device *dev) return -ENXIO; } =20 - if (cxl_pmem_size(cxlds) && IS_ENABLED(CONFIG_CXL_PMEM)) { - rc =3D devm_cxl_add_nvdimm(parent_port, cxlmd); - if (rc) { - if (rc =3D=3D -ENODEV) - dev_info(dev, "PMEM disabled by platform\n"); - return rc; - } - } - if (dport->rch) endpoint_parent =3D parent_port->uport_dev; else @@ -143,6 +134,15 @@ static int cxl_mem_probe(struct device *dev) return rc; } =20 + if (cxl_pmem_size(cxlds) && IS_ENABLED(CONFIG_CXL_PMEM)) { + rc =3D devm_cxl_add_nvdimm(parent_port, cxlmd); + if (rc) { + if (rc =3D=3D -ENODEV) + dev_info(dev, "PMEM disabled by platform\n"); + return rc; + } + } + if (cxlmd->ops) { rc =3D cxlmd->ops->probe(cxlmd); if (rc) diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c index e21051d79b25..d56fdfe4b43b 100644 --- a/drivers/cxl/pci.c +++ b/drivers/cxl/pci.c @@ -907,6 +907,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const st= ruct pci_device_id *id) struct cxl_memdev_state *mds; struct cxl_dev_state *cxlds; struct cxl_register_map map; + struct cxl_memdev_ops ops; struct cxl_memdev *cxlmd; int rc, pmu_count; unsigned int i; @@ -1006,7 +1007,8 @@ static int cxl_pci_probe(struct pci_dev *pdev, const = struct pci_device_id *id) if (rc) dev_dbg(&pdev->dev, "No CXL Features discovered\n"); =20 - cxlmd =3D devm_cxl_add_memdev(&pdev->dev, cxlds, NULL); + ops.probe =3D cxl_region_discovery; + cxlmd =3D devm_cxl_add_memdev(&pdev->dev, cxlds, &ops); if (IS_ERR(cxlmd)) return PTR_ERR(cxlmd); =20 diff --git a/drivers/cxl/port.c b/drivers/cxl/port.c index d5fd0c5ae49b..ad98b2881fed 100644 --- a/drivers/cxl/port.c +++ b/drivers/cxl/port.c @@ -31,33 +31,6 @@ static void schedule_detach(void *cxlmd) schedule_cxl_memdev_detach(cxlmd); } =20 -static int discover_region(struct device *dev, void *unused) -{ - struct cxl_endpoint_decoder *cxled; - int rc; - - if (!is_endpoint_decoder(dev)) - return 0; - - cxled =3D to_cxl_endpoint_decoder(dev); - if ((cxled->cxld.flags & CXL_DECODER_F_ENABLE) =3D=3D 0) - return 0; - - if (cxled->state !=3D CXL_DECODER_STATE_AUTO) - return 0; - - /* - * Region enumeration is opportunistic, if this add-event fails, - * continue to the next endpoint decoder. - */ - rc =3D cxl_add_to_region(cxled); - if (rc) - dev_dbg(dev, "failed to add to region: %#llx-%#llx\n", - cxled->cxld.hpa_range.start, cxled->cxld.hpa_range.end); - - return 0; -} - static int cxl_switch_port_probe(struct cxl_port *port) { /* Reset nr_dports for rebind of driver */ @@ -83,17 +56,7 @@ static int cxl_endpoint_port_probe(struct cxl_port *port) if (rc) return rc; =20 - rc =3D devm_cxl_endpoint_decoders_setup(port); - if (rc) - return rc; - - /* - * Now that all endpoint decoders are successfully enumerated, try to - * assemble regions from committed decoders - */ - device_for_each_child(&port->dev, NULL, discover_region); - - return 0; + return devm_cxl_endpoint_decoders_setup(port); } =20 static int cxl_port_probe(struct device *dev) --=20 2.34.1 From nobody Sun Feb 8 15:08:14 2026 Received: from mailout2.samsung.com (mailout2.samsung.com [203.254.224.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9CB6F35CBA6 for ; Fri, 9 Jan 2026 12:45:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=203.254.224.25 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962732; cv=none; b=Vjb46TayHaybrBzSvbG7dmr6Ja1L9dGl3w106jon9IBdd3zMrLlnGsazwsjsRbFUvAnu+uq9NJ6c+l733x5D9gWrTc7Vu+9xAiDNo1V75qqZ05FuQJugLRdV882A3t2wclYjhg89f/TsLKBjvDv6tQE7kTGhGM5BEfgdNL+sRiU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962732; c=relaxed/simple; bh=HD/gTB5kgM6SiK/HmvIIhivfkdDDsrZm2IXLN8y2248=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:MIME-Version: Content-Type:References; b=vEeLzJsIdqCB1HuD3MWU8WH6i5ik4sH813R0mWBLj1ixKWJzPI8yf37TqMSUYz41qaSRI8T/pgey+5hPGK2rJKcN0aP8RAve5h+Du2sdtbaoDWFXRGNK+pubpXmXeXsPGQRvQ8u6YhRs4AvHoinOY4Ge0zrRqHRkgRlR86u2gew= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com; spf=pass smtp.mailfrom=samsung.com; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b=tYDWq3DB; arc=none smtp.client-ip=203.254.224.25 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=samsung.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="tYDWq3DB" Received: from epcas5p2.samsung.com (unknown [182.195.41.40]) by mailout2.samsung.com (KnoxPortal) with ESMTP id 20260109124527epoutp023f24a9433191f2fa7809b11b4bdec376~JELuw2PWY1948119481epoutp02k for ; Fri, 9 Jan 2026 12:45:27 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.samsung.com 20260109124527epoutp023f24a9433191f2fa7809b11b4bdec376~JELuw2PWY1948119481epoutp02k DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1767962727; bh=aO+ljYqEEsUGo4X69OdR2NXyQbVGtMyJXmVdd54fJ+U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tYDWq3DBqSisC5H3Cxhuc9NASU58YUM32jTf4FhTBB/0/LEUwC7gcLIR6TNU33Klk y7fa2MI6Qu7gcbzX1rT+GfkbyyJHm6rVRXM+4PHO9Yghb18EiRFKWcV6Mmjt/2/ivy Hb7DAVqYBj1UYHxf4NvA6st8yxGmNS7juMx7sfnw= Received: from epsnrtp02.localdomain (unknown [182.195.42.154]) by epcas5p1.samsung.com (KnoxPortal) with ESMTPS id 20260109124526epcas5p1a11f5188ac806435d97f9e9f82ffe92d~JELuixkgr2943229432epcas5p1e; Fri, 9 Jan 2026 12:45:26 +0000 (GMT) Received: from epcas5p1.samsung.com (unknown [182.195.38.87]) by epsnrtp02.localdomain (Postfix) with ESMTP id 4dnhMB0b2cz2SSKX; Fri, 9 Jan 2026 12:45:26 +0000 (GMT) Received: from epsmtip1.samsung.com (unknown [182.195.34.30]) by epcas5p1.samsung.com (KnoxPortal) with ESMTPA id 20260109124525epcas5p103e2d6f32643e6cb07b7037155ef16e9~JELtdxcz82911929119epcas5p1n; Fri, 9 Jan 2026 12:45:25 +0000 (GMT) Received: from test-PowerEdge-R740xd.samsungds.net (unknown [107.99.41.79]) by epsmtip1.samsung.com (KnoxPortal) with ESMTPA id 20260109124524epsmtip157be96a874752c009205ec3be9e26c2a~JELsY3uy90977009770epsmtip1j; Fri, 9 Jan 2026 12:45:24 +0000 (GMT) From: Neeraj Kumar To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev, linux-kernel@vger.kernel.org, gost.dev@samsung.com Cc: a.manzanares@samsung.com, vishak.g@samsung.com, neeraj.kernel@gmail.com, Neeraj Kumar Subject: [PATCH V5 11/17] cxl/region: Add devm_cxl_pmem_add_region() for pmem region creation Date: Fri, 9 Jan 2026 18:14:31 +0530 Message-Id: <20260109124437.4025893-12-s.neeraj@samsung.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260109124437.4025893-1-s.neeraj@samsung.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CMS-MailID: 20260109124525epcas5p103e2d6f32643e6cb07b7037155ef16e9 X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" CMS-TYPE: 105P cpgsPolicy: CPGSC10-542,Y X-CFilter-Loop: Reflected X-CMS-RootMailID: 20260109124525epcas5p103e2d6f32643e6cb07b7037155ef16e9 References: <20260109124437.4025893-1-s.neeraj@samsung.com> devm_cxl_pmem_add_region() is used to create cxl region based on region information scanned from LSA. devm_cxl_add_region() is used to just allocate cxlr and its fields are filled later by userspace tool using device attributes (*_store()). Inspiration for devm_cxl_pmem_add_region() is taken from these device attributes (_store*) calls. It allocates cxlr and fills information parsed from LSA and calls device_add(&cxlr->dev) to initiate further region creation porbes Rename __create_region() to cxl_create_region(), which will be used in later patch to create cxl region after fetching region information from LSA. Reviewed-by: Dave Jiang Signed-off-by: Neeraj Kumar --- drivers/cxl/core/core.h | 12 ++++ drivers/cxl/core/region.c | 137 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 144 insertions(+), 5 deletions(-) diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h index 1fb66132b777..268f6d19ab9d 100644 --- a/drivers/cxl/core/core.h +++ b/drivers/cxl/core/core.h @@ -42,6 +42,10 @@ int cxl_get_poison_by_endpoint(struct cxl_port *port); struct cxl_region *cxl_dpa_to_region(const struct cxl_memdev *cxlmd, u64 d= pa); u64 cxl_dpa_to_hpa(struct cxl_region *cxlr, const struct cxl_memdev *cxlmd, u64 dpa); +struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd, + enum cxl_partition_mode mode, int id, + struct cxl_pmem_region_params *pmem_params, + struct cxl_endpoint_decoder *cxled); =20 #else static inline u64 cxl_dpa_to_hpa(struct cxl_region *cxlr, @@ -71,6 +75,14 @@ static inline int cxl_region_init(void) static inline void cxl_region_exit(void) { } +static inline 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_endpoint_decoder *cxled) +{ + return ERR_PTR(-EOPNOTSUPP); +} #define CXL_REGION_ATTR(x) NULL #define CXL_REGION_TYPE(x) NULL #define SET_CXL_REGION_ATTR(x) diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c index 26238fb5e8cf..13779aeacd8e 100644 --- a/drivers/cxl/core/region.c +++ b/drivers/cxl/core/region.c @@ -2621,6 +2621,127 @@ static struct cxl_region *devm_cxl_add_region(struc= t cxl_root_decoder *cxlrd, return ERR_PTR(rc); } =20 +static ssize_t alloc_region_hpa(struct cxl_region *cxlr, u64 size) +{ + int rc; + + if (!size) + return -EINVAL; + + ACQUIRE(rwsem_write_kill, rwsem)(&cxl_rwsem.region); + if ((rc =3D ACQUIRE_ERR(rwsem_write_kill, &rwsem))) + return rc; + + return alloc_hpa(cxlr, size); +} + +static ssize_t alloc_region_dpa(struct cxl_endpoint_decoder *cxled, u64 si= ze) +{ + int rc; + + if (!size) + return -EINVAL; + + if (!IS_ALIGNED(size, SZ_256M)) + return -EINVAL; + + rc =3D cxl_dpa_free(cxled); + if (rc) + return rc; + + return cxl_dpa_alloc(cxled, size); +} + +static struct cxl_region * +cxl_pmem_region_prep(struct cxl_root_decoder *cxlrd, int id, + struct cxl_pmem_region_params *params, + struct cxl_endpoint_decoder *cxled, + enum cxl_decoder_type type) +{ + struct cxl_region_params *p; + struct device *dev; + int rc; + + struct cxl_region *cxlr __free(put_cxl_region) =3D + cxl_region_alloc(cxlrd, id); + if (IS_ERR(cxlr)) + return cxlr; + + dev =3D &cxlr->dev; + rc =3D dev_set_name(dev, "region%d", id); + if (rc) + return ERR_PTR(rc); + + cxlr->mode =3D CXL_PARTMODE_PMEM; + cxlr->type =3D type; + + p =3D &cxlr->params; + p->uuid =3D params->uuid; + p->interleave_ways =3D params->nlabel; + p->interleave_granularity =3D params->ig; + + rc =3D alloc_region_hpa(cxlr, params->rawsize); + if (rc) + return ERR_PTR(rc); + + rc =3D cxl_dpa_set_part(cxled, CXL_PARTMODE_PMEM); + if (rc) + return ERR_PTR(rc); + + rc =3D alloc_region_dpa(cxled, params->rawsize); + if (rc) + return ERR_PTR(rc); + + /* + * TODO: Currently we have support of interleave_way =3D=3D 1, where + * we can only have one region per mem device. It means mem device + * position (params->position) will always be 0. It is therefore + * attaching only one target at params->position + */ + if (params->position) + return ERR_PTR(-EOPNOTSUPP); + + rc =3D attach_target(cxlr, cxled, params->position, TASK_INTERRUPTIBLE); + if (rc) + return ERR_PTR(rc); + + rc =3D __commit(cxlr); + if (rc) + return ERR_PTR(rc); + + rc =3D device_add(dev); + if (rc) + return ERR_PTR(rc); + + return no_free_ptr(cxlr); +} + +static struct cxl_region * +devm_cxl_pmem_add_region(struct cxl_root_decoder *cxlrd, int id, + struct cxl_pmem_region_params *params, + struct cxl_endpoint_decoder *cxled, + enum cxl_decoder_type type) +{ + struct cxl_port *root_port; + struct cxl_region *cxlr; + int rc; + + cxlr =3D cxl_pmem_region_prep(cxlrd, id, params, cxled, type); + if (IS_ERR(cxlr)) + return cxlr; + + root_port =3D to_cxl_port(cxlrd->cxlsd.cxld.dev.parent); + rc =3D devm_add_action_or_reset(root_port->uport_dev, + unregister_region, cxlr); + if (rc) + return ERR_PTR(rc); + + dev_dbg(root_port->uport_dev, "%s: created %s\n", + dev_name(&cxlrd->cxlsd.cxld.dev), dev_name(&cxlr->dev)); + + return cxlr; +} + static ssize_t __create_region_show(struct cxl_root_decoder *cxlrd, char *= buf) { return sysfs_emit(buf, "region%u\n", atomic_read(&cxlrd->region_id)); @@ -2638,8 +2759,10 @@ static ssize_t create_ram_region_show(struct device = *dev, return __create_region_show(to_cxl_root_decoder(dev), buf); } =20 -static struct cxl_region *__create_region(struct cxl_root_decoder *cxlrd, - enum cxl_partition_mode mode, int id) +struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd, + enum cxl_partition_mode mode, int id, + struct cxl_pmem_region_params *pmem_params, + struct cxl_endpoint_decoder *cxled) { int rc; =20 @@ -2661,6 +2784,9 @@ static struct cxl_region *__create_region(struct cxl_= root_decoder *cxlrd, return ERR_PTR(-EBUSY); } =20 + if (pmem_params) + return devm_cxl_pmem_add_region(cxlrd, id, pmem_params, cxled, + CXL_DECODER_HOSTONLYMEM); return devm_cxl_add_region(cxlrd, id, mode, CXL_DECODER_HOSTONLYMEM); } =20 @@ -2675,7 +2801,7 @@ static ssize_t create_region_store(struct device *dev= , const char *buf, if (rc !=3D 1) return -EINVAL; =20 - cxlr =3D __create_region(cxlrd, mode, id); + cxlr =3D cxl_create_region(cxlrd, mode, id, NULL, NULL); if (IS_ERR(cxlr)) return PTR_ERR(cxlr); =20 @@ -3644,8 +3770,9 @@ static struct cxl_region *construct_region(struct cxl= _root_decoder *cxlrd, struct cxl_region *cxlr; =20 do { - cxlr =3D __create_region(cxlrd, cxlds->part[part].mode, - atomic_read(&cxlrd->region_id)); + cxlr =3D cxl_create_region(cxlrd, cxlds->part[part].mode, + atomic_read(&cxlrd->region_id), + NULL, NULL); } while (IS_ERR(cxlr) && PTR_ERR(cxlr) =3D=3D -EBUSY); =20 if (IS_ERR(cxlr)) { --=20 2.34.1 From nobody Sun Feb 8 15:08:14 2026 Received: from mailout3.samsung.com (mailout3.samsung.com [203.254.224.33]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1072035EDAC for ; Fri, 9 Jan 2026 12:45:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=203.254.224.33 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962733; cv=none; b=MCl0bk93A3AvK+Xpl6JwMigLOr2WuS7RVmHJ3CCMtJSrH/VkVMFvOctCnQd8TN0a/NrRyVqHSMWXCMpYoGbj0Qni03vCagwual0UpRSkTnt15nSxQt2RDUWWggru2zFcg3JY88jxj6FkyzcIOz/c6Oaz9mm+5jvFDrcRPgqunAo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962733; c=relaxed/simple; bh=c1tNPjnzy8cwC5zXLAhFqZAtMoA7a9S6XuLJvj+KHsQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:MIME-Version: Content-Type:References; b=ifG99jY60ZwWwVRM56HYe1su/6uNT532elTVzniSa055WE/usuuDaTBdXv/sF/d4CwwVWqu34pjxeH4VqLov7sup66e681BcliRzvp/yYM4hBi0kEybkXM7+EfyCL+/mFhXAIzvuAo0FcmM7jExWutz98/6nP6IAnEAXo8fzetM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com; spf=pass smtp.mailfrom=samsung.com; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b=mLXff4KK; arc=none smtp.client-ip=203.254.224.33 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=samsung.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="mLXff4KK" Received: from epcas5p3.samsung.com (unknown [182.195.41.41]) by mailout3.samsung.com (KnoxPortal) with ESMTP id 20260109124529epoutp033d692ecc6c3c7a4a8018edb3b5ccb554~JELw9IOX80814408144epoutp03T for ; Fri, 9 Jan 2026 12:45:29 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout3.samsung.com 20260109124529epoutp033d692ecc6c3c7a4a8018edb3b5ccb554~JELw9IOX80814408144epoutp03T DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1767962729; bh=UPmNW62pq6lNkIZnJ4v0XRR9hHjaYlJjfZ+/jEJsjTs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mLXff4KKlkPHKFo/kZYDVesTjoyDEYwrutDijMMP27zlfXXUMqcqGNHuTFPCfld99 bPCrZ2EN7RASIqTO5FhCm+RkvCivEDzgnVO9Rq76ksTmkhVY2sbr3hQIgJaVsfj8yQ necUww76G/yq7nPjZhCbIt3dtuREBY9/6shD19Wo= Received: from epsnrtp01.localdomain (unknown [182.195.42.153]) by epcas5p2.samsung.com (KnoxPortal) with ESMTPS id 20260109124528epcas5p25dc032c0ba5485ef17185187e4c2613f~JELwku-ro3051830518epcas5p2I; Fri, 9 Jan 2026 12:45:28 +0000 (GMT) Received: from epcas5p4.samsung.com (unknown [182.195.38.91]) by epsnrtp01.localdomain (Postfix) with ESMTP id 4dnhMD210Nz6B9m4; Fri, 9 Jan 2026 12:45:28 +0000 (GMT) Received: from epsmtip1.samsung.com (unknown [182.195.34.30]) by epcas5p1.samsung.com (KnoxPortal) with ESMTPA id 20260109124527epcas5p1bd7390304b8b6c99a75b0cf4e74b6c12~JELu_Dt4U3073830738epcas5p1T; Fri, 9 Jan 2026 12:45:27 +0000 (GMT) Received: from test-PowerEdge-R740xd.samsungds.net (unknown [107.99.41.79]) by epsmtip1.samsung.com (KnoxPortal) with ESMTPA id 20260109124525epsmtip128477fa5873395ef0651927b773b17c1~JELtsxLpm0978109781epsmtip1V; Fri, 9 Jan 2026 12:45:25 +0000 (GMT) From: Neeraj Kumar To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev, linux-kernel@vger.kernel.org, gost.dev@samsung.com Cc: a.manzanares@samsung.com, vishak.g@samsung.com, neeraj.kernel@gmail.com, Neeraj Kumar Subject: [PATCH V5 12/17] cxl/pmem: Preserve region information into nd_set Date: Fri, 9 Jan 2026 18:14:32 +0530 Message-Id: <20260109124437.4025893-13-s.neeraj@samsung.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260109124437.4025893-1-s.neeraj@samsung.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CMS-MailID: 20260109124527epcas5p1bd7390304b8b6c99a75b0cf4e74b6c12 X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" CMS-TYPE: 105P cpgsPolicy: CPGSC10-542,Y X-CFilter-Loop: Reflected X-CMS-RootMailID: 20260109124527epcas5p1bd7390304b8b6c99a75b0cf4e74b6c12 References: <20260109124437.4025893-1-s.neeraj@samsung.com> Save region information stored in cxlr to nd_set during cxl_pmem_region_probe in nd_set. This saved region information is being stored into LSA, which will be used for cxl region persistence Reviewed-by: Dave Jiang Signed-off-by: Neeraj Kumar Reviewed-by: Jonathan Cameron --- drivers/cxl/pmem.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/cxl/pmem.c b/drivers/cxl/pmem.c index e197883690ef..a6eba3572090 100644 --- a/drivers/cxl/pmem.c +++ b/drivers/cxl/pmem.c @@ -377,6 +377,7 @@ static int cxl_pmem_region_probe(struct device *dev) struct nd_mapping_desc mappings[CXL_DECODER_MAX_INTERLEAVE]; struct cxl_pmem_region *cxlr_pmem =3D to_cxl_pmem_region(dev); struct cxl_region *cxlr =3D cxlr_pmem->cxlr; + struct cxl_region_params *p =3D &cxlr->params; struct cxl_nvdimm_bridge *cxl_nvb =3D cxlr->cxl_nvb; struct cxl_pmem_region_info *info =3D NULL; struct nd_interleave_set *nd_set; @@ -465,12 +466,12 @@ static int cxl_pmem_region_probe(struct device *dev) ndr_desc.num_mappings =3D cxlr_pmem->nr_mappings; ndr_desc.mapping =3D mappings; =20 - /* - * TODO enable CXL labels which skip the need for 'interleave-set cookie' - */ - nd_set->cookie1 =3D - nd_fletcher64(info, sizeof(*info) * cxlr_pmem->nr_mappings, 0); - nd_set->cookie2 =3D nd_set->cookie1; + nd_set->uuid =3D p->uuid; + nd_set->interleave_ways =3D p->interleave_ways; + nd_set->interleave_granularity =3D p->interleave_granularity; + nd_set->res =3D p->res; + nd_set->nr_targets =3D p->nr_targets; + ndr_desc.nd_set =3D nd_set; =20 cxlr_pmem->nd_region =3D --=20 2.34.1 From nobody Sun Feb 8 15:08:14 2026 Received: from mailout2.samsung.com (mailout2.samsung.com [203.254.224.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AEF5135EDB4 for ; Fri, 9 Jan 2026 12:45:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=203.254.224.25 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962734; cv=none; b=Xg7EFC6q81cht5ZlE8vvqN6CR/yIkoXz+TFGzUFDpiun5zvAQwz4sVKCar9QaJLUwcgQZWYZ9Scixmn0G7qVrJSjR2Xd3Y/Ezs4Kl/WS2WErdymXrBzRxpnWfAkJYL77ggggAAzjRE1f4D4NGWPQ4XEQ16emx+vGWwilDRoCErU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962734; c=relaxed/simple; bh=yT3XM63THD49Nn5UJxpBVycoSb6abAdLRCuPoIe2elo=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:MIME-Version: Content-Type:References; b=CP4Nwu9yW9IZRGW6mObC89T4FU5LEkSUk83daWRbznWGpcSL34FMlw/3yCdGMXMTFyKeevqnLok1PFGhyTi5drtBc/yTUui6UZ/hxOFVF0nKJ/dkW/2Cf+J16sYdwjuZ9Itd9BF01aAncooWk9LZnfEDuyFJpTYS7+Gq/3cGACg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com; spf=pass smtp.mailfrom=samsung.com; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b=KfEQIl5Y; arc=none smtp.client-ip=203.254.224.25 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=samsung.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="KfEQIl5Y" Received: from epcas5p1.samsung.com (unknown [182.195.41.39]) by mailout2.samsung.com (KnoxPortal) with ESMTP id 20260109124530epoutp02d88255ed2c004ec776c1c2b54a894288~JELxixbZc2147721477epoutp02O for ; Fri, 9 Jan 2026 12:45:30 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.samsung.com 20260109124530epoutp02d88255ed2c004ec776c1c2b54a894288~JELxixbZc2147721477epoutp02O DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1767962730; bh=cZoK/1tdoPZDKSoHUpKi1C816jcv7KTDftJyu7yExGk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KfEQIl5YYNspVgtl/uQzMpvURXBC1aYSvmbnMCvMlahtVqz8kwdsOEPaRIv1Wo3mF nff+GbpTuOadpGY1xUGXsLf3DKR/8ShXkUuRzj7mxNlCr97/e/p92hODOdSv2X6oig +PDKsGhmals0O9qppJDo6ch2ATnmAFj0j8RWQ82Q= Received: from epsnrtp01.localdomain (unknown [182.195.42.153]) by epcas5p1.samsung.com (KnoxPortal) with ESMTPS id 20260109124529epcas5p1515182bd27e50548e727cf3c6b39448f~JELxGaz7-1415414154epcas5p1v; Fri, 9 Jan 2026 12:45:29 +0000 (GMT) Received: from epcas5p1.samsung.com (unknown [182.195.38.91]) by epsnrtp01.localdomain (Postfix) with ESMTP id 4dnhMD69Ddz6B9m5; Fri, 9 Jan 2026 12:45:28 +0000 (GMT) Received: from epsmtip1.samsung.com (unknown [182.195.34.30]) by epcas5p2.samsung.com (KnoxPortal) with ESMTPA id 20260109124528epcas5p2d9832310312442a47ccd71cd64e5bc46~JELwHU3NE3128331283epcas5p2B; Fri, 9 Jan 2026 12:45:28 +0000 (GMT) Received: from test-PowerEdge-R740xd.samsungds.net (unknown [107.99.41.79]) by epsmtip1.samsung.com (KnoxPortal) with ESMTPA id 20260109124527epsmtip18b66715ebb3ddfd78ea346376ea0b4f0~JELvAdaUL0978109781epsmtip1W; Fri, 9 Jan 2026 12:45:27 +0000 (GMT) From: Neeraj Kumar To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev, linux-kernel@vger.kernel.org, gost.dev@samsung.com Cc: a.manzanares@samsung.com, vishak.g@samsung.com, neeraj.kernel@gmail.com, Neeraj Kumar Subject: [PATCH V5 13/17] cxl/pmem_region: Prep patch to accommodate pmem_region attributes Date: Fri, 9 Jan 2026 18:14:33 +0530 Message-Id: <20260109124437.4025893-14-s.neeraj@samsung.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260109124437.4025893-1-s.neeraj@samsung.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CMS-MailID: 20260109124528epcas5p2d9832310312442a47ccd71cd64e5bc46 X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" CMS-TYPE: 105P cpgsPolicy: CPGSC10-542,Y X-CFilter-Loop: Reflected X-CMS-RootMailID: 20260109124528epcas5p2d9832310312442a47ccd71cd64e5bc46 References: <20260109124437.4025893-1-s.neeraj@samsung.com> For region label update, need to create device attribute, which calls nvdimm exported routine thus making pmem_region dependent on libnvdimm. Because of this dependency of pmem region on libnvdimm, segregate pmem region related code from core/region.c to core/pmem_region.c This patch has no functionality change. Its just code movement from core/region.c to core/pmem_region.c Reviewed-by: Dave Jiang Reviewed-by: Jonathan Cameron Signed-off-by: Neeraj Kumar --- drivers/cxl/core/Makefile | 2 +- drivers/cxl/core/core.h | 10 ++ drivers/cxl/core/pmem_region.c | 201 +++++++++++++++++++++++++++++++++ drivers/cxl/core/region.c | 188 +----------------------------- tools/testing/cxl/Kbuild | 2 +- 5 files changed, 214 insertions(+), 189 deletions(-) create mode 100644 drivers/cxl/core/pmem_region.c diff --git a/drivers/cxl/core/Makefile b/drivers/cxl/core/Makefile index 5ad8fef210b5..fe0fcab6d730 100644 --- a/drivers/cxl/core/Makefile +++ b/drivers/cxl/core/Makefile @@ -16,7 +16,7 @@ cxl_core-y +=3D pmu.o cxl_core-y +=3D cdat.o cxl_core-y +=3D ras.o cxl_core-$(CONFIG_TRACING) +=3D trace.o -cxl_core-$(CONFIG_CXL_REGION) +=3D region.o +cxl_core-$(CONFIG_CXL_REGION) +=3D region.o pmem_region.o cxl_core-$(CONFIG_CXL_MCE) +=3D mce.o cxl_core-$(CONFIG_CXL_FEATURES) +=3D features.o cxl_core-$(CONFIG_CXL_EDAC_MEM_FEATURES) +=3D edac.o diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h index 268f6d19ab9d..4eed243c0d7d 100644 --- a/drivers/cxl/core/core.h +++ b/drivers/cxl/core/core.h @@ -46,6 +46,8 @@ struct cxl_region *cxl_create_region(struct cxl_root_deco= der *cxlrd, enum cxl_partition_mode mode, int id, struct cxl_pmem_region_params *pmem_params, struct cxl_endpoint_decoder *cxled); +struct cxl_region *to_cxl_region(struct device *dev); +int devm_cxl_add_pmem_region(struct cxl_region *cxlr); =20 #else static inline u64 cxl_dpa_to_hpa(struct cxl_region *cxlr, @@ -83,6 +85,14 @@ cxl_create_region(struct cxl_root_decoder *cxlrd, { return ERR_PTR(-EOPNOTSUPP); } +static inline struct cxl_region *to_cxl_region(struct device *dev) +{ + return NULL; +} +static inline int devm_cxl_add_pmem_region(struct cxl_region *cxlr) +{ + return 0; +} #define CXL_REGION_ATTR(x) NULL #define CXL_REGION_TYPE(x) NULL #define SET_CXL_REGION_ATTR(x) diff --git a/drivers/cxl/core/pmem_region.c b/drivers/cxl/core/pmem_region.c new file mode 100644 index 000000000000..dcaab59108fd --- /dev/null +++ b/drivers/cxl/core/pmem_region.c @@ -0,0 +1,201 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright(c) 2020 Intel Corporation. */ +#include +#include +#include +#include +#include "core.h" + +/** + * DOC: cxl pmem region + * + * The core CXL PMEM region infrastructure supports persistent memory + * region creation using LIBNVDIMM subsystem. It has dependency on + * LIBNVDIMM, pmem region needs to update the cxl region information + * in the LSA. + */ + +static void cxl_pmem_region_release(struct device *dev) +{ + struct cxl_pmem_region *cxlr_pmem =3D to_cxl_pmem_region(dev); + int i; + + for (i =3D 0; i < cxlr_pmem->nr_mappings; i++) { + struct cxl_memdev *cxlmd =3D cxlr_pmem->mapping[i].cxlmd; + + put_device(&cxlmd->dev); + } + + kfree(cxlr_pmem); +} + +static const struct attribute_group *cxl_pmem_region_attribute_groups[] = =3D { + &cxl_base_attribute_group, + NULL +}; + +const struct device_type cxl_pmem_region_type =3D { + .name =3D "cxl_pmem_region", + .release =3D cxl_pmem_region_release, + .groups =3D cxl_pmem_region_attribute_groups, +}; + +bool is_cxl_pmem_region(struct device *dev) +{ + return dev->type =3D=3D &cxl_pmem_region_type; +} +EXPORT_SYMBOL_NS_GPL(is_cxl_pmem_region, "CXL"); + +struct cxl_pmem_region *to_cxl_pmem_region(struct device *dev) +{ + if (dev_WARN_ONCE(dev, !is_cxl_pmem_region(dev), + "not a cxl_pmem_region device\n")) + return NULL; + return container_of(dev, struct cxl_pmem_region, dev); +} +EXPORT_SYMBOL_NS_GPL(to_cxl_pmem_region, "CXL"); + +static struct lock_class_key cxl_pmem_region_key; + +static int cxl_pmem_region_alloc(struct cxl_region *cxlr) +{ + struct cxl_region_params *p =3D &cxlr->params; + struct cxl_nvdimm_bridge *cxl_nvb; + struct device *dev; + int i; + + guard(rwsem_read)(&cxl_rwsem.region); + if (p->state !=3D CXL_CONFIG_COMMIT) + return -ENXIO; + + struct cxl_pmem_region *cxlr_pmem __free(kfree) =3D + kzalloc(struct_size(cxlr_pmem, mapping, p->nr_targets), + GFP_KERNEL); + if (!cxlr_pmem) + return -ENOMEM; + + cxlr_pmem->hpa_range.start =3D p->res->start; + cxlr_pmem->hpa_range.end =3D p->res->end; + + /* Snapshot the region configuration underneath the cxl_region_rwsem */ + cxlr_pmem->nr_mappings =3D p->nr_targets; + for (i =3D 0; i < p->nr_targets; i++) { + struct cxl_endpoint_decoder *cxled =3D p->targets[i]; + struct cxl_memdev *cxlmd =3D cxled_to_memdev(cxled); + struct cxl_pmem_region_mapping *m =3D &cxlr_pmem->mapping[i]; + + /* + * Regions never span CXL root devices, so by definition the + * bridge for one device is the same for all. + */ + if (i =3D=3D 0) { + cxl_nvb =3D cxl_find_nvdimm_bridge(cxlmd->endpoint); + if (!cxl_nvb) + return -ENODEV; + cxlr->cxl_nvb =3D cxl_nvb; + } + m->cxlmd =3D cxlmd; + get_device(&cxlmd->dev); + m->start =3D cxled->dpa_res->start; + m->size =3D resource_size(cxled->dpa_res); + m->position =3D i; + } + + dev =3D &cxlr_pmem->dev; + device_initialize(dev); + lockdep_set_class(&dev->mutex, &cxl_pmem_region_key); + device_set_pm_not_required(dev); + dev->parent =3D &cxlr->dev; + dev->bus =3D &cxl_bus_type; + dev->type =3D &cxl_pmem_region_type; + cxlr_pmem->cxlr =3D cxlr; + cxlr->cxlr_pmem =3D no_free_ptr(cxlr_pmem); + + return 0; +} + +static void cxlr_pmem_unregister(void *_cxlr_pmem) +{ + struct cxl_pmem_region *cxlr_pmem =3D _cxlr_pmem; + struct cxl_region *cxlr =3D cxlr_pmem->cxlr; + struct cxl_nvdimm_bridge *cxl_nvb =3D cxlr->cxl_nvb; + + /* + * Either the bridge is in ->remove() context under the device_lock(), + * or cxlr_release_nvdimm() is cancelling the bridge's release action + * for @cxlr_pmem and doing it itself (while manually holding the bridge + * lock). + */ + device_lock_assert(&cxl_nvb->dev); + cxlr->cxlr_pmem =3D NULL; + cxlr_pmem->cxlr =3D NULL; + device_unregister(&cxlr_pmem->dev); +} + +static void cxlr_release_nvdimm(void *_cxlr) +{ + struct cxl_region *cxlr =3D _cxlr; + struct cxl_nvdimm_bridge *cxl_nvb =3D cxlr->cxl_nvb; + + scoped_guard(device, &cxl_nvb->dev) { + if (cxlr->cxlr_pmem) + devm_release_action(&cxl_nvb->dev, cxlr_pmem_unregister, + cxlr->cxlr_pmem); + } + cxlr->cxl_nvb =3D NULL; + put_device(&cxl_nvb->dev); +} + +/** + * devm_cxl_add_pmem_region() - add a cxl_region-to-nd_region bridge + * @cxlr: parent CXL region for this pmem region bridge device + * + * Return: 0 on success negative error code on failure. + */ +int devm_cxl_add_pmem_region(struct cxl_region *cxlr) +{ + struct cxl_pmem_region *cxlr_pmem; + struct cxl_nvdimm_bridge *cxl_nvb; + struct device *dev; + int rc; + + rc =3D cxl_pmem_region_alloc(cxlr); + if (rc) + return rc; + cxlr_pmem =3D cxlr->cxlr_pmem; + cxl_nvb =3D cxlr->cxl_nvb; + + dev =3D &cxlr_pmem->dev; + rc =3D dev_set_name(dev, "pmem_region%d", cxlr->id); + if (rc) + goto err; + + rc =3D device_add(dev); + if (rc) + goto err; + + dev_dbg(&cxlr->dev, "%s: register %s\n", dev_name(dev->parent), + dev_name(dev)); + + scoped_guard(device, &cxl_nvb->dev) { + if (cxl_nvb->dev.driver) + rc =3D devm_add_action_or_reset(&cxl_nvb->dev, + cxlr_pmem_unregister, + cxlr_pmem); + else + rc =3D -ENXIO; + } + + if (rc) + goto err_bridge; + + /* @cxlr carries a reference on @cxl_nvb until cxlr_release_nvdimm */ + return devm_add_action_or_reset(&cxlr->dev, cxlr_release_nvdimm, cxlr); + +err: + put_device(dev); +err_bridge: + put_device(&cxl_nvb->dev); + cxlr->cxl_nvb =3D NULL; + return rc; +} diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c index 13779aeacd8e..9a86d1c467b2 100644 --- a/drivers/cxl/core/region.c +++ b/drivers/cxl/core/region.c @@ -38,8 +38,6 @@ */ static nodemask_t nodemask_region_seen =3D NODE_MASK_NONE; =20 -static struct cxl_region *to_cxl_region(struct device *dev); - #define __ACCESS_ATTR_RO(_level, _name) { \ .attr =3D { .name =3D __stringify(_name), .mode =3D 0444 }, \ .show =3D _name##_access##_level##_show, \ @@ -2429,7 +2427,7 @@ bool is_cxl_region(struct device *dev) } EXPORT_SYMBOL_NS_GPL(is_cxl_region, "CXL"); =20 -static struct cxl_region *to_cxl_region(struct device *dev) +struct cxl_region *to_cxl_region(struct device *dev) { if (dev_WARN_ONCE(dev, dev->type !=3D &cxl_region_type, "not a cxl_region device\n")) @@ -2872,46 +2870,6 @@ static ssize_t delete_region_store(struct device *de= v, } DEVICE_ATTR_WO(delete_region); =20 -static void cxl_pmem_region_release(struct device *dev) -{ - struct cxl_pmem_region *cxlr_pmem =3D to_cxl_pmem_region(dev); - int i; - - for (i =3D 0; i < cxlr_pmem->nr_mappings; i++) { - struct cxl_memdev *cxlmd =3D cxlr_pmem->mapping[i].cxlmd; - - put_device(&cxlmd->dev); - } - - kfree(cxlr_pmem); -} - -static const struct attribute_group *cxl_pmem_region_attribute_groups[] = =3D { - &cxl_base_attribute_group, - NULL, -}; - -const struct device_type cxl_pmem_region_type =3D { - .name =3D "cxl_pmem_region", - .release =3D cxl_pmem_region_release, - .groups =3D cxl_pmem_region_attribute_groups, -}; - -bool is_cxl_pmem_region(struct device *dev) -{ - return dev->type =3D=3D &cxl_pmem_region_type; -} -EXPORT_SYMBOL_NS_GPL(is_cxl_pmem_region, "CXL"); - -struct cxl_pmem_region *to_cxl_pmem_region(struct device *dev) -{ - if (dev_WARN_ONCE(dev, !is_cxl_pmem_region(dev), - "not a cxl_pmem_region device\n")) - return NULL; - return container_of(dev, struct cxl_pmem_region, dev); -} -EXPORT_SYMBOL_NS_GPL(to_cxl_pmem_region, "CXL"); - struct cxl_poison_context { struct cxl_port *port; int part; @@ -3343,64 +3301,6 @@ static int region_offset_to_dpa_result(struct cxl_re= gion *cxlr, u64 offset, return -ENXIO; } =20 -static struct lock_class_key cxl_pmem_region_key; - -static int cxl_pmem_region_alloc(struct cxl_region *cxlr) -{ - struct cxl_region_params *p =3D &cxlr->params; - struct cxl_nvdimm_bridge *cxl_nvb; - struct device *dev; - int i; - - guard(rwsem_read)(&cxl_rwsem.region); - if (p->state !=3D CXL_CONFIG_COMMIT) - return -ENXIO; - - struct cxl_pmem_region *cxlr_pmem __free(kfree) =3D - kzalloc(struct_size(cxlr_pmem, mapping, p->nr_targets), GFP_KERNEL); - if (!cxlr_pmem) - return -ENOMEM; - - cxlr_pmem->hpa_range.start =3D p->res->start; - cxlr_pmem->hpa_range.end =3D p->res->end; - - /* Snapshot the region configuration underneath the cxl_rwsem.region */ - cxlr_pmem->nr_mappings =3D p->nr_targets; - for (i =3D 0; i < p->nr_targets; i++) { - struct cxl_endpoint_decoder *cxled =3D p->targets[i]; - struct cxl_memdev *cxlmd =3D cxled_to_memdev(cxled); - struct cxl_pmem_region_mapping *m =3D &cxlr_pmem->mapping[i]; - - /* - * Regions never span CXL root devices, so by definition the - * bridge for one device is the same for all. - */ - if (i =3D=3D 0) { - cxl_nvb =3D cxl_find_nvdimm_bridge(cxlmd->endpoint); - if (!cxl_nvb) - return -ENODEV; - cxlr->cxl_nvb =3D cxl_nvb; - } - m->cxlmd =3D cxlmd; - get_device(&cxlmd->dev); - m->start =3D cxled->dpa_res->start; - m->size =3D resource_size(cxled->dpa_res); - m->position =3D i; - } - - dev =3D &cxlr_pmem->dev; - device_initialize(dev); - lockdep_set_class(&dev->mutex, &cxl_pmem_region_key); - device_set_pm_not_required(dev); - dev->parent =3D &cxlr->dev; - dev->bus =3D &cxl_bus_type; - dev->type =3D &cxl_pmem_region_type; - cxlr_pmem->cxlr =3D cxlr; - cxlr->cxlr_pmem =3D no_free_ptr(cxlr_pmem); - - return 0; -} - static void cxl_dax_region_release(struct device *dev) { struct cxl_dax_region *cxlr_dax =3D to_cxl_dax_region(dev); @@ -3464,92 +3364,6 @@ static struct cxl_dax_region *cxl_dax_region_alloc(s= truct cxl_region *cxlr) return cxlr_dax; } =20 -static void cxlr_pmem_unregister(void *_cxlr_pmem) -{ - struct cxl_pmem_region *cxlr_pmem =3D _cxlr_pmem; - struct cxl_region *cxlr =3D cxlr_pmem->cxlr; - struct cxl_nvdimm_bridge *cxl_nvb =3D cxlr->cxl_nvb; - - /* - * Either the bridge is in ->remove() context under the device_lock(), - * or cxlr_release_nvdimm() is cancelling the bridge's release action - * for @cxlr_pmem and doing it itself (while manually holding the bridge - * lock). - */ - device_lock_assert(&cxl_nvb->dev); - cxlr->cxlr_pmem =3D NULL; - cxlr_pmem->cxlr =3D NULL; - device_unregister(&cxlr_pmem->dev); -} - -static void cxlr_release_nvdimm(void *_cxlr) -{ - struct cxl_region *cxlr =3D _cxlr; - struct cxl_nvdimm_bridge *cxl_nvb =3D cxlr->cxl_nvb; - - scoped_guard(device, &cxl_nvb->dev) { - if (cxlr->cxlr_pmem) - devm_release_action(&cxl_nvb->dev, cxlr_pmem_unregister, - cxlr->cxlr_pmem); - } - cxlr->cxl_nvb =3D NULL; - put_device(&cxl_nvb->dev); -} - -/** - * devm_cxl_add_pmem_region() - add a cxl_region-to-nd_region bridge - * @cxlr: parent CXL region for this pmem region bridge device - * - * Return: 0 on success negative error code on failure. - */ -static int devm_cxl_add_pmem_region(struct cxl_region *cxlr) -{ - struct cxl_pmem_region *cxlr_pmem; - struct cxl_nvdimm_bridge *cxl_nvb; - struct device *dev; - int rc; - - rc =3D cxl_pmem_region_alloc(cxlr); - if (rc) - return rc; - cxlr_pmem =3D cxlr->cxlr_pmem; - cxl_nvb =3D cxlr->cxl_nvb; - - dev =3D &cxlr_pmem->dev; - rc =3D dev_set_name(dev, "pmem_region%d", cxlr->id); - if (rc) - goto err; - - rc =3D device_add(dev); - if (rc) - goto err; - - dev_dbg(&cxlr->dev, "%s: register %s\n", dev_name(dev->parent), - dev_name(dev)); - - scoped_guard(device, &cxl_nvb->dev) { - if (cxl_nvb->dev.driver) - rc =3D devm_add_action_or_reset(&cxl_nvb->dev, - cxlr_pmem_unregister, - cxlr_pmem); - else - rc =3D -ENXIO; - } - - if (rc) - goto err_bridge; - - /* @cxlr carries a reference on @cxl_nvb until cxlr_release_nvdimm */ - return devm_add_action_or_reset(&cxlr->dev, cxlr_release_nvdimm, cxlr); - -err: - put_device(dev); -err_bridge: - put_device(&cxl_nvb->dev); - cxlr->cxl_nvb =3D NULL; - return rc; -} - static void cxlr_dax_unregister(void *_cxlr_dax) { struct cxl_dax_region *cxlr_dax =3D _cxlr_dax; diff --git a/tools/testing/cxl/Kbuild b/tools/testing/cxl/Kbuild index 0e151d0572d1..ad2496b38fdd 100644 --- a/tools/testing/cxl/Kbuild +++ b/tools/testing/cxl/Kbuild @@ -59,7 +59,7 @@ cxl_core-y +=3D $(CXL_CORE_SRC)/pmu.o cxl_core-y +=3D $(CXL_CORE_SRC)/cdat.o cxl_core-y +=3D $(CXL_CORE_SRC)/ras.o cxl_core-$(CONFIG_TRACING) +=3D $(CXL_CORE_SRC)/trace.o -cxl_core-$(CONFIG_CXL_REGION) +=3D $(CXL_CORE_SRC)/region.o +cxl_core-$(CONFIG_CXL_REGION) +=3D $(CXL_CORE_SRC)/region.o $(CXL_CORE_SRC= )/pmem_region.o cxl_core-$(CONFIG_CXL_MCE) +=3D $(CXL_CORE_SRC)/mce.o cxl_core-$(CONFIG_CXL_FEATURES) +=3D $(CXL_CORE_SRC)/features.o cxl_core-$(CONFIG_CXL_EDAC_MEM_FEATURES) +=3D $(CXL_CORE_SRC)/edac.o --=20 2.34.1 From nobody Sun Feb 8 15:08:14 2026 Received: from mailout2.samsung.com (mailout2.samsung.com [203.254.224.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5B6F835EDD2 for ; Fri, 9 Jan 2026 12:45:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=203.254.224.25 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962735; cv=none; b=Ljrn8ZS3r4CnJD4iUm6dizBc8+tjnH1DjNN6ugVEMwD9rA0xtp2CmvA4iyvgdo6R0885AjtYcvC7/cx0zr3Cgr3ZzS0+e1ES72UO+xKIMHA9rGP4xPTCWe028LcjAgak3ZMZgXa36bi/2DFB26yQx9p/imJyoqcXBelnUqejZbk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962735; c=relaxed/simple; bh=ZkKdwtiVXB/lWeF3AgZpQgdlWvHOCMpzKltTnKZFs2M=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:MIME-Version: Content-Type:References; b=iMeyZplnFsLKAYxxLu+//9Y01SUz/VNtSuC+P4fo/kIptm1lmSt9bOA1XMxka4mYolzmYMgAvcDFfOE/ZapIeq100Pp3hWTLmpBGaz05kDK1+BxAb7PFyabpuCsmWaRQSt/IuQJ5EBUaLQIbHy75T8LKTDs+Vf38YoAsPzlLZLc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com; spf=pass smtp.mailfrom=samsung.com; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b=bzsnCXX9; arc=none smtp.client-ip=203.254.224.25 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=samsung.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="bzsnCXX9" Received: from epcas5p4.samsung.com (unknown [182.195.41.42]) by mailout2.samsung.com (KnoxPortal) with ESMTP id 20260109124531epoutp02f68122d54b4a8c0f7f24ffbd942ac9f9~JELzAPcj72083220832epoutp02q for ; Fri, 9 Jan 2026 12:45:31 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.samsung.com 20260109124531epoutp02f68122d54b4a8c0f7f24ffbd942ac9f9~JELzAPcj72083220832epoutp02q DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1767962731; bh=f/FHwXws18MmLB1jbXYZVDE1sctsfNmc5mK+mKONCIE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bzsnCXX9gi/3cW/KFebSxluiE7/jM11LnBwGgaCxZp6jmMGgZISuCLTIoJd+aiQyz b5ktPO6QyLINcaNonUhJg8VUB27FUgNnAJttOMlt0is4hLBfEI8ul0JtdNtDnCyWI3 /YiELsFXxdv9qkLlUhkM4Kb9WfldaD3G3osRVr1k= Received: from epsnrtp04.localdomain (unknown [182.195.42.156]) by epcas5p3.samsung.com (KnoxPortal) with ESMTPS id 20260109124530epcas5p3da37884a6970d94b4ae5032e0a50507c~JELyb0ENA2090720907epcas5p3v; Fri, 9 Jan 2026 12:45:30 +0000 (GMT) Received: from epcas5p1.samsung.com (unknown [182.195.38.93]) by epsnrtp04.localdomain (Postfix) with ESMTP id 4dnhMG21s8z6B9m9; Fri, 9 Jan 2026 12:45:30 +0000 (GMT) Received: from epsmtip1.samsung.com (unknown [182.195.34.30]) by epcas5p1.samsung.com (KnoxPortal) with ESMTPA id 20260109124529epcas5p1d740589383c6428ce53b454f8ed42307~JELxafwYA3012130121epcas5p1g; Fri, 9 Jan 2026 12:45:29 +0000 (GMT) Received: from test-PowerEdge-R740xd.samsungds.net (unknown [107.99.41.79]) by epsmtip1.samsung.com (KnoxPortal) with ESMTPA id 20260109124528epsmtip13c15696e4a06b358ebaf7bab08aeb3c5~JELwVqZnc0977809778epsmtip1q; Fri, 9 Jan 2026 12:45:28 +0000 (GMT) From: Neeraj Kumar To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev, linux-kernel@vger.kernel.org, gost.dev@samsung.com Cc: a.manzanares@samsung.com, vishak.g@samsung.com, neeraj.kernel@gmail.com, Neeraj Kumar Subject: [PATCH V5 14/17] cxl/pmem_region: Introduce CONFIG_CXL_PMEM_REGION for core/pmem_region.c Date: Fri, 9 Jan 2026 18:14:34 +0530 Message-Id: <20260109124437.4025893-15-s.neeraj@samsung.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260109124437.4025893-1-s.neeraj@samsung.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CMS-MailID: 20260109124529epcas5p1d740589383c6428ce53b454f8ed42307 X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" CMS-TYPE: 105P cpgsPolicy: CPGSC10-542,Y X-CFilter-Loop: Reflected X-CMS-RootMailID: 20260109124529epcas5p1d740589383c6428ce53b454f8ed42307 References: <20260109124437.4025893-1-s.neeraj@samsung.com> As pmem region label update/delete has hard dependency on libnvdimm. It is therefore put core/pmem_region.c under CONFIG_CXL_PMEM_REGION control. It handles the dependency by selecting CONFIG_LIBNVDIMM if not enabled. Reviewed-by: Dave Jiang Signed-off-by: Neeraj Kumar Reviewed-by: Jonathan Cameron --- drivers/cxl/Kconfig | 15 +++++++++++++++ drivers/cxl/core/Makefile | 3 ++- drivers/cxl/core/core.h | 18 +++++++++++------- drivers/cxl/cxl.h | 24 ++++++++++++++---------- tools/testing/cxl/Kbuild | 3 ++- 5 files changed, 44 insertions(+), 19 deletions(-) diff --git a/drivers/cxl/Kconfig b/drivers/cxl/Kconfig index f1361ed6a0d4..307fed8f1f56 100644 --- a/drivers/cxl/Kconfig +++ b/drivers/cxl/Kconfig @@ -211,6 +211,21 @@ config CXL_REGION =20 If unsure say 'y' =20 +config CXL_PMEM_REGION + bool "CXL: Pmem Region Support" + default CXL_BUS + depends on CXL_REGION + depends on ARCH_HAS_PMEM_API + depends on PHYS_ADDR_T_64BIT + depends on BLK_DEV + select LIBNVDIMM + help + Enable the CXL core to enumerate and provision CXL pmem regions. + A CXL pmem region need to update region label into LSA. For LSA + update/delete libnvdimm is required. + + If unsure say 'y' + config CXL_REGION_INVALIDATION_TEST bool "CXL: Region Cache Management Bypass (TEST)" depends on CXL_REGION diff --git a/drivers/cxl/core/Makefile b/drivers/cxl/core/Makefile index fe0fcab6d730..399157beb917 100644 --- a/drivers/cxl/core/Makefile +++ b/drivers/cxl/core/Makefile @@ -16,7 +16,8 @@ cxl_core-y +=3D pmu.o cxl_core-y +=3D cdat.o cxl_core-y +=3D ras.o cxl_core-$(CONFIG_TRACING) +=3D trace.o -cxl_core-$(CONFIG_CXL_REGION) +=3D region.o pmem_region.o +cxl_core-$(CONFIG_CXL_REGION) +=3D region.o +cxl_core-$(CONFIG_CXL_PMEM_REGION) +=3D pmem_region.o cxl_core-$(CONFIG_CXL_MCE) +=3D mce.o cxl_core-$(CONFIG_CXL_FEATURES) +=3D features.o cxl_core-$(CONFIG_CXL_EDAC_MEM_FEATURES) +=3D edac.o diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h index 4eed243c0d7d..5ae693269771 100644 --- a/drivers/cxl/core/core.h +++ b/drivers/cxl/core/core.h @@ -34,7 +34,6 @@ int cxl_decoder_detach(struct cxl_region *cxlr, #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), -#define CXL_PMEM_REGION_TYPE(x) (&cxl_pmem_region_type) #define CXL_DAX_REGION_TYPE(x) (&cxl_dax_region_type) int cxl_region_init(void); void cxl_region_exit(void); @@ -47,7 +46,6 @@ struct cxl_region *cxl_create_region(struct cxl_root_deco= der *cxlrd, struct cxl_pmem_region_params *pmem_params, struct cxl_endpoint_decoder *cxled); struct cxl_region *to_cxl_region(struct device *dev); -int devm_cxl_add_pmem_region(struct cxl_region *cxlr); =20 #else static inline u64 cxl_dpa_to_hpa(struct cxl_region *cxlr, @@ -89,17 +87,23 @@ static inline struct cxl_region *to_cxl_region(struct d= evice *dev) { return NULL; } -static inline int devm_cxl_add_pmem_region(struct cxl_region *cxlr) -{ - return 0; -} #define CXL_REGION_ATTR(x) NULL #define CXL_REGION_TYPE(x) NULL #define SET_CXL_REGION_ATTR(x) -#define CXL_PMEM_REGION_TYPE(x) NULL #define CXL_DAX_REGION_TYPE(x) NULL #endif =20 +#ifdef CONFIG_CXL_PMEM_REGION +#define CXL_PMEM_REGION_TYPE(x) (&cxl_pmem_region_type) +int devm_cxl_add_pmem_region(struct cxl_region *cxlr); +#else +#define CXL_PMEM_REGION_TYPE(x) NULL +static inline int devm_cxl_add_pmem_region(struct cxl_region *cxlr) +{ + return -EINVAL; +} +#endif + struct cxl_send_command; struct cxl_mem_query_commands; int cxl_query_cmd(struct cxl_mailbox *cxl_mbox, diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h index 684a0d1b441a..6ac3b40cb5ff 100644 --- a/drivers/cxl/cxl.h +++ b/drivers/cxl/cxl.h @@ -899,21 +899,11 @@ int devm_cxl_add_nvdimm(struct cxl_port *parent_port,= struct cxl_memdev *cxlmd); struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(struct cxl_port *port); =20 #ifdef CONFIG_CXL_REGION -bool is_cxl_pmem_region(struct device *dev); -struct cxl_pmem_region *to_cxl_pmem_region(struct device *dev); int cxl_add_to_region(struct cxl_endpoint_decoder *cxled); struct cxl_dax_region *to_cxl_dax_region(struct device *dev); u64 cxl_port_get_spa_cache_alias(struct cxl_port *endpoint, u64 spa); int cxl_region_discovery(struct cxl_memdev *cxlmd); #else -static inline bool is_cxl_pmem_region(struct device *dev) -{ - return false; -} -static inline struct cxl_pmem_region *to_cxl_pmem_region(struct device *de= v) -{ - return NULL; -} static inline int cxl_add_to_region(struct cxl_endpoint_decoder *cxled) { return 0; @@ -933,6 +923,20 @@ static inline int cxl_region_discovery(struct cxl_memd= ev *cxlmd) } #endif =20 +#ifdef CONFIG_CXL_PMEM_REGION +bool is_cxl_pmem_region(struct device *dev); +struct cxl_pmem_region *to_cxl_pmem_region(struct device *dev); +#else +static inline bool is_cxl_pmem_region(struct device *dev) +{ + return false; +} +static inline struct cxl_pmem_region *to_cxl_pmem_region(struct device *de= v) +{ + return NULL; +} +#endif + void cxl_endpoint_parse_cdat(struct cxl_port *port); void cxl_switch_parse_cdat(struct cxl_dport *dport); =20 diff --git a/tools/testing/cxl/Kbuild b/tools/testing/cxl/Kbuild index ad2496b38fdd..024922326a6b 100644 --- a/tools/testing/cxl/Kbuild +++ b/tools/testing/cxl/Kbuild @@ -59,7 +59,8 @@ cxl_core-y +=3D $(CXL_CORE_SRC)/pmu.o cxl_core-y +=3D $(CXL_CORE_SRC)/cdat.o cxl_core-y +=3D $(CXL_CORE_SRC)/ras.o cxl_core-$(CONFIG_TRACING) +=3D $(CXL_CORE_SRC)/trace.o -cxl_core-$(CONFIG_CXL_REGION) +=3D $(CXL_CORE_SRC)/region.o $(CXL_CORE_SRC= )/pmem_region.o +cxl_core-$(CONFIG_CXL_REGION) +=3D $(CXL_CORE_SRC)/region.o +cxl_core-$(CONFIG_CXL_PMEM_REGION) +=3D $(CXL_CORE_SRC)/pmem_region.o cxl_core-$(CONFIG_CXL_MCE) +=3D $(CXL_CORE_SRC)/mce.o cxl_core-$(CONFIG_CXL_FEATURES) +=3D $(CXL_CORE_SRC)/features.o cxl_core-$(CONFIG_CXL_EDAC_MEM_FEATURES) +=3D $(CXL_CORE_SRC)/edac.o --=20 2.34.1 From nobody Sun Feb 8 15:08:14 2026 Received: from mailout1.samsung.com (mailout1.samsung.com [203.254.224.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5FA2A35F8A6 for ; Fri, 9 Jan 2026 12:45:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=203.254.224.24 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962736; cv=none; b=WHgFY0DWMmSsuLD3h299Jy+0/OtbETl68bpnEr5VqegtVp8FJ/idv5PtF8aGXPIGLomLlRTJtSBqwWiDymJX47Q5ONWqhIqH3FZ6un4t+p9+ltdZUAtDmFjyTb/6XCe/f2DJYqv/sUqCV6t/ysMlDrs/hkIDLAfY0zB4/dsESdU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962736; c=relaxed/simple; bh=KHQP1Ri5R5r961NvMzWeFoCFfxmrNpKFaJKeimQ5gkg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:MIME-Version: Content-Type:References; b=KensIc22nCHWd3pKkJBlPhOkl307yJpLGw2gaNnfO+N7J2xS5/SGHZbqO6Z6aRIZ5ud6xU6ChN5tWvZiGW9hOrVq4boy7Bm54FrNwNFfY3W2ZRS6nEtWaxWK6s9jrI5KSGzzmGbaKjamOlC52tt9THzREHClxzqiTZ1qb8RveLI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com; spf=pass smtp.mailfrom=samsung.com; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b=sMI1RfU7; arc=none smtp.client-ip=203.254.224.24 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=samsung.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="sMI1RfU7" Received: from epcas5p3.samsung.com (unknown [182.195.41.41]) by mailout1.samsung.com (KnoxPortal) with ESMTP id 20260109124532epoutp01e4c14b2f046b2e23fdab5267e7d57449~JEL0IygzT0739707397epoutp01F for ; Fri, 9 Jan 2026 12:45:32 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.samsung.com 20260109124532epoutp01e4c14b2f046b2e23fdab5267e7d57449~JEL0IygzT0739707397epoutp01F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1767962732; bh=+aRZfdCXYDuTDq7UU5fYBpXy51NIcZ3A0+f+Fnp4q50=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sMI1RfU7Vo7PfmgMe9Sp5txggxWxaoSioAJk8aXuaubgMA3gr2s1IBw4LDGD6OiHS xddyzEh0Zd+17pKq6eotjzH9wJH3t1EKvRMceegfap98NmyQR7qz6nD4m2ncAEkFwu /hdhzA94Zgd+mC8KkyXh01cH/AaCjSN8BO9CfxtY= Received: from epsnrtp03.localdomain (unknown [182.195.42.155]) by epcas5p2.samsung.com (KnoxPortal) with ESMTPS id 20260109124532epcas5p209cc71d77964df592675c691ef50bff0~JELz2XAlx0900009000epcas5p2i; Fri, 9 Jan 2026 12:45:32 +0000 (GMT) Received: from epcas5p1.samsung.com (unknown [182.195.38.87]) by epsnrtp03.localdomain (Postfix) with ESMTP id 4dnhMH5bR5z3hhT8; Fri, 9 Jan 2026 12:45:31 +0000 (GMT) Received: from epsmtip1.samsung.com (unknown [182.195.34.30]) by epcas5p1.samsung.com (KnoxPortal) with ESMTPA id 20260109124531epcas5p118e7306860bcd57a0106948375df5c9c~JELyvgO8J1415414154epcas5p1x; Fri, 9 Jan 2026 12:45:31 +0000 (GMT) Received: from test-PowerEdge-R740xd.samsungds.net (unknown [107.99.41.79]) by epsmtip1.samsung.com (KnoxPortal) with ESMTPA id 20260109124530epsmtip1fce3c83ba6e0514b7825d9e5ae596b94~JELxpe4d50978109781epsmtip1X; Fri, 9 Jan 2026 12:45:30 +0000 (GMT) From: Neeraj Kumar To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev, linux-kernel@vger.kernel.org, gost.dev@samsung.com Cc: a.manzanares@samsung.com, vishak.g@samsung.com, neeraj.kernel@gmail.com, Neeraj Kumar Subject: [PATCH V5 15/17] cxl/pmem_region: Add sysfs attribute cxl region label updation/deletion Date: Fri, 9 Jan 2026 18:14:35 +0530 Message-Id: <20260109124437.4025893-16-s.neeraj@samsung.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260109124437.4025893-1-s.neeraj@samsung.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CMS-MailID: 20260109124531epcas5p118e7306860bcd57a0106948375df5c9c X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" CMS-TYPE: 105P cpgsPolicy: CPGSC10-542,Y X-CFilter-Loop: Reflected X-CMS-RootMailID: 20260109124531epcas5p118e7306860bcd57a0106948375df5c9c References: <20260109124437.4025893-1-s.neeraj@samsung.com> Using these attributes region label is added/deleted into LSA. These attributes are called from userspace (ndctl) after region creation. Signed-off-by: Neeraj Kumar Reviewed-by: Dave Jiang Reviewed-by: Jonathan Cameron --- Documentation/ABI/testing/sysfs-bus-cxl | 22 +++++++ drivers/cxl/core/pmem_region.c | 88 +++++++++++++++++++++++++ drivers/cxl/cxl.h | 7 ++ 3 files changed, 117 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-cxl b/Documentation/ABI/te= sting/sysfs-bus-cxl index c80a1b5a03db..011a5e8d354f 100644 --- a/Documentation/ABI/testing/sysfs-bus-cxl +++ b/Documentation/ABI/testing/sysfs-bus-cxl @@ -624,3 +624,25 @@ Description: The count is persistent across power loss and wraps back to 0 upon overflow. If this file is not present, the device does not have the necessary support for dirty tracking. + + +What: /sys/bus/cxl/devices/regionZ/pmem_regionZ/region_label_update +Date: Jan, 2026 +KernelVersion: v6.19 +Contact: linux-cxl@vger.kernel.org +Description: + (RW) Write a boolean 'true' string value to this attribute to + update cxl region information into LSA as region label. It is + used to update cxl region information saved during cxl region + creation into LSA. This attribute must be written last during + cxl region creation. Reading this attribute indicates whether + the region label is active or not. + + +What: /sys/bus/cxl/devices/regionZ/pmem_regionZ/region_label_delete +Date: Jan, 2026 +KernelVersion: v6.19 +Contact: linux-cxl@vger.kernel.org +Description: + (WO) When a boolean 'true' is written to this attribute then + pmem_region driver deletes cxl region label from LSA. diff --git a/drivers/cxl/core/pmem_region.c b/drivers/cxl/core/pmem_region.c index dcaab59108fd..53d3d81e9676 100644 --- a/drivers/cxl/core/pmem_region.c +++ b/drivers/cxl/core/pmem_region.c @@ -29,8 +29,96 @@ static void cxl_pmem_region_release(struct device *dev) kfree(cxlr_pmem); } =20 +static ssize_t region_label_update_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct cxl_pmem_region *cxlr_pmem =3D to_cxl_pmem_region(dev); + struct cxl_region *cxlr =3D cxlr_pmem->cxlr; + ssize_t rc; + bool update; + + rc =3D kstrtobool(buf, &update); + if (rc) + return rc; + + ACQUIRE(rwsem_write_kill, rwsem)(&cxl_rwsem.region); + if ((rc =3D ACQUIRE_ERR(rwsem_write_kill, &rwsem))) + return rc; + + /* Region not yet committed */ + if (update && cxlr && cxlr->params.state !=3D CXL_CONFIG_COMMIT) { + dev_dbg(dev, "region not committed, can't update into LSA\n"); + return -ENXIO; + } + + if (!cxlr || !cxlr->cxlr_pmem || !cxlr->cxlr_pmem->nd_region) + return 0; + + rc =3D nd_region_label_update(cxlr->cxlr_pmem->nd_region); + if (rc) + return rc; + + cxlr->params.state_region_label =3D CXL_REGION_LABEL_ACTIVE; + + return len; +} + +static ssize_t region_label_update_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct cxl_pmem_region *cxlr_pmem =3D to_cxl_pmem_region(dev); + struct cxl_region *cxlr =3D cxlr_pmem->cxlr; + struct cxl_region_params *p =3D &cxlr->params; + ssize_t rc; + + ACQUIRE(rwsem_read_intr, rwsem)(&cxl_rwsem.region); + if ((rc =3D ACQUIRE_ERR(rwsem_read_intr, &rwsem))) + return rc; + + return sysfs_emit(buf, "%d\n", p->state_region_label); +} +static DEVICE_ATTR_RW(region_label_update); + +static ssize_t region_label_delete_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct cxl_pmem_region *cxlr_pmem =3D to_cxl_pmem_region(dev); + struct cxl_region *cxlr =3D cxlr_pmem->cxlr; + ssize_t rc; + + ACQUIRE(rwsem_write_kill, rwsem)(&cxl_rwsem.region); + if ((rc =3D ACQUIRE_ERR(rwsem_write_kill, &rwsem))) + return rc; + + if (!cxlr && !cxlr->cxlr_pmem && !cxlr->cxlr_pmem->nd_region) + return 0; + + rc =3D nd_region_label_delete(cxlr->cxlr_pmem->nd_region); + if (rc) + return rc; + + cxlr->params.state_region_label =3D CXL_REGION_LABEL_INACTIVE; + + return len; +} +static DEVICE_ATTR_WO(region_label_delete); + +static struct attribute *cxl_pmem_region_attrs[] =3D { + &dev_attr_region_label_update.attr, + &dev_attr_region_label_delete.attr, + NULL +}; + +static struct attribute_group cxl_pmem_region_group =3D { + .attrs =3D cxl_pmem_region_attrs, +}; + static const struct attribute_group *cxl_pmem_region_attribute_groups[] = =3D { &cxl_base_attribute_group, + &cxl_pmem_region_group, NULL }; =20 diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h index 6ac3b40cb5ff..8c76c4a981bf 100644 --- a/drivers/cxl/cxl.h +++ b/drivers/cxl/cxl.h @@ -473,9 +473,15 @@ enum cxl_config_state { CXL_CONFIG_COMMIT, }; =20 +enum region_label_state { + CXL_REGION_LABEL_INACTIVE, + CXL_REGION_LABEL_ACTIVE, +}; + /** * struct cxl_region_params - region settings * @state: allow the driver to lockdown further parameter changes + * @state: region label state * @uuid: unique id for persistent regions * @interleave_ways: number of endpoints in the region * @interleave_granularity: capacity each endpoint contributes to a stripe @@ -488,6 +494,7 @@ enum cxl_config_state { */ struct cxl_region_params { enum cxl_config_state state; + enum region_label_state state_region_label; uuid_t uuid; int interleave_ways; int interleave_granularity; --=20 2.34.1 From nobody Sun Feb 8 15:08:14 2026 Received: from mailout1.samsung.com (mailout1.samsung.com [203.254.224.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E985335F8D3 for ; Fri, 9 Jan 2026 12:45:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=203.254.224.24 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962739; cv=none; b=PRtJWk0Cs35FKq1DZbEUZ1Q2XLr9vsYJM4ti11LhZQP7xEZKzAEBBH0cnfRJ3gwfIQnfbTZt0Ma+DSSiCZMvL6bWk3pB/Gyqre71n03sOfqO91ypkqSBsakE7THjLZoN2+z5XAFKiVZT9FOaDcXOLIyW/o36oseYtMDGY1Pg4aQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962739; c=relaxed/simple; bh=SRpErQFAGIe5nLQ85rgj4y3tPYj4P021hJOo9neEJ1s=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:MIME-Version: Content-Type:References; b=UdiwZIlEbZrEngCugCVooP/OAz64QgwfwqLqf0CCIihSPQJv8vX/j9q9kuK38RhNtNklJQ4cC4jjPPmxwIvdl77PMjZgvhAJCuwpVUxVypB2cmAPqMacEC9epZp4jAovnhzrSO+kPYFc7/z6C8sy13BYSBknnWUzHpnSTZNQP5Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com; spf=pass smtp.mailfrom=samsung.com; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b=P/Xt9OhR; arc=none smtp.client-ip=203.254.224.24 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=samsung.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="P/Xt9OhR" Received: from epcas5p1.samsung.com (unknown [182.195.41.39]) by mailout1.samsung.com (KnoxPortal) with ESMTP id 20260109124534epoutp010c8762c891637bd804ca21e2de9e2a99~JEL1eam_20753707537epoutp01O for ; Fri, 9 Jan 2026 12:45:34 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.samsung.com 20260109124534epoutp010c8762c891637bd804ca21e2de9e2a99~JEL1eam_20753707537epoutp01O DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1767962734; bh=9aNUNULuIT8Pshadtnl/hm/yM6UsRG1F6TD25Pz0Yaw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=P/Xt9OhRFOTNl+IMedS+DulxNxso1VTDr+VkcZwgktlWipWstj1futSF0PIIzkqFI Mg+0SdoGux6bc9jNO0nDpU6m9TKAK/7qSTw6FqrU4YmvCzoC3szg44Szowc+MrN5k4 je99RwIQb/BftcfsOl7n+DHCTZ9KURD6cmC2xlrU= Received: from epsnrtp02.localdomain (unknown [182.195.42.154]) by epcas5p2.samsung.com (KnoxPortal) with ESMTPS id 20260109124533epcas5p2ae2510a39153bf8ace1535a13c70629e~JEL1L4DzP0900009000epcas5p2l; Fri, 9 Jan 2026 12:45:33 +0000 (GMT) Received: from epcas5p1.samsung.com (unknown [182.195.38.87]) by epsnrtp02.localdomain (Postfix) with ESMTP id 4dnhMK1ZdWz2SSKZ; Fri, 9 Jan 2026 12:45:33 +0000 (GMT) Received: from epsmtip1.samsung.com (unknown [182.195.34.30]) by epcas5p4.samsung.com (KnoxPortal) with ESMTPA id 20260109124532epcas5p403ad41a20c916855bf3fea644ee6e5ec~JEL0EXVqa1264312643epcas5p4Z; Fri, 9 Jan 2026 12:45:32 +0000 (GMT) Received: from test-PowerEdge-R740xd.samsungds.net (unknown [107.99.41.79]) by epsmtip1.samsung.com (KnoxPortal) with ESMTPA id 20260109124531epsmtip14df269dcc7116eb68cdbbc2a66ef4805~JELy_rqgZ0972509725epsmtip1j; Fri, 9 Jan 2026 12:45:31 +0000 (GMT) From: Neeraj Kumar To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev, linux-kernel@vger.kernel.org, gost.dev@samsung.com Cc: a.manzanares@samsung.com, vishak.g@samsung.com, neeraj.kernel@gmail.com, Neeraj Kumar Subject: [PATCH V5 16/17] cxl/pmem_region: Create pmem region using information parsed from LSA Date: Fri, 9 Jan 2026 18:14:36 +0530 Message-Id: <20260109124437.4025893-17-s.neeraj@samsung.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260109124437.4025893-1-s.neeraj@samsung.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CMS-MailID: 20260109124532epcas5p403ad41a20c916855bf3fea644ee6e5ec X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" CMS-TYPE: 105P cpgsPolicy: CPGSC10-542,Y X-CFilter-Loop: Reflected X-CMS-RootMailID: 20260109124532epcas5p403ad41a20c916855bf3fea644ee6e5ec References: <20260109124437.4025893-1-s.neeraj@samsung.com> create_pmem_region() creates CXL region based on region information parsed from the Label Storage Area (LSA). This routine requires cxl endpoint decoder and root decoder. Add cxl_find_root_decoder_by_port() and cxl_find_free_ep_decoder() to find the root decoder and a free endpoint decoder respectively. Signed-off-by: Neeraj Kumar --- drivers/cxl/core/core.h | 5 ++ drivers/cxl/core/pmem_region.c | 136 +++++++++++++++++++++++++++++++++ drivers/cxl/core/region.c | 21 +++-- drivers/cxl/cxl.h | 5 ++ 4 files changed, 159 insertions(+), 8 deletions(-) diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h index 5ae693269771..8421ea0ef834 100644 --- a/drivers/cxl/core/core.h +++ b/drivers/cxl/core/core.h @@ -46,6 +46,7 @@ struct cxl_region *cxl_create_region(struct cxl_root_deco= der *cxlrd, struct cxl_pmem_region_params *pmem_params, struct cxl_endpoint_decoder *cxled); struct cxl_region *to_cxl_region(struct device *dev); +bool is_free_decoder(struct device *dev); =20 #else static inline u64 cxl_dpa_to_hpa(struct cxl_region *cxlr, @@ -87,6 +88,10 @@ static inline struct cxl_region *to_cxl_region(struct de= vice *dev) { return NULL; } +static inline bool is_free_decoder(struct device *dev) +{ + return false; +} #define CXL_REGION_ATTR(x) NULL #define CXL_REGION_TYPE(x) NULL #define SET_CXL_REGION_ATTR(x) diff --git a/drivers/cxl/core/pmem_region.c b/drivers/cxl/core/pmem_region.c index 53d3d81e9676..4a8cf8322cf0 100644 --- a/drivers/cxl/core/pmem_region.c +++ b/drivers/cxl/core/pmem_region.c @@ -287,3 +287,139 @@ int devm_cxl_add_pmem_region(struct cxl_region *cxlr) cxlr->cxl_nvb =3D NULL; return rc; } + +static int match_root_decoder_by_dport(struct device *dev, const void *dat= a) +{ + const struct cxl_port *ep_port =3D data; + struct cxl_root_decoder *cxlrd; + struct cxl_port *root_port; + struct cxl_decoder *cxld; + struct cxl_dport *dport; + bool dport_matched =3D false; + + if (!is_root_decoder(dev)) + return 0; + + cxld =3D to_cxl_decoder(dev); + if (!(cxld->flags & CXL_DECODER_F_PMEM)) + return 0; + + cxlrd =3D to_cxl_root_decoder(dev); + + root_port =3D cxlrd_to_port(cxlrd); + dport =3D cxl_find_dport_by_dev(root_port, ep_port->host_bridge); + if (!dport) + return 0; + + for (int i =3D 0; i < cxlrd->cxlsd.nr_targets; i++) { + if (dport =3D=3D cxlrd->cxlsd.target[i]) { + dport_matched =3D true; + break; + } + } + + if (!dport_matched) + return 0; + + return is_root_decoder(dev); +} + +/** + * cxl_find_root_decoder_by_port() - find a cxl root decoder on cxl bus + * @port: any descendant port in CXL port topology + * @cxled: endpoint decoder + * + * Caller of this function must call put_device() when done as a device ref + * is taken via device_find_child() + */ +static struct cxl_root_decoder * +cxl_find_root_decoder_by_port(struct cxl_port *port, + struct cxl_endpoint_decoder *cxled) +{ + struct cxl_root *cxl_root __free(put_cxl_root) =3D find_cxl_root(port); + struct cxl_port *ep_port =3D cxled_to_port(cxled); + struct device *dev; + + if (!cxl_root) + return NULL; + + dev =3D device_find_child(&cxl_root->port.dev, ep_port, + match_root_decoder_by_dport); + if (!dev) + return NULL; + + return to_cxl_root_decoder(dev); +} + +static int match_free_ep_decoder(struct device *dev, const void *data) +{ + if (!is_endpoint_decoder(dev)) + return 0; + + return is_free_decoder(dev); +} + +/** + * cxl_find_endpoint_decoder_by_port() - find a cxl root decoder on cxl bus + * @port: any descendant port in CXL port topology + * + * Caller of this function must call put_device() when done as a device ref + * is taken via device_find_child() + */ +static struct cxl_decoder *cxl_find_free_ep_decoder(struct cxl_port *port) +{ + struct device *dev; + + dev =3D device_find_child(&port->dev, NULL, match_free_ep_decoder); + if (!dev) + return NULL; + + return to_cxl_decoder(dev); +} + +void create_pmem_region(struct nvdimm *nvdimm) +{ + struct cxl_region *cxlr; + struct cxl_memdev *cxlmd; + struct cxl_nvdimm *cxl_nvd; + struct cxl_endpoint_decoder *cxled; + struct cxl_pmem_region_params *params; + + if (!nvdimm_has_cxl_region(nvdimm)) + return; + + lockdep_assert_held(&cxl_rwsem.region); + cxl_nvd =3D nvdimm_provider_data(nvdimm); + params =3D nvdimm_get_cxl_region_param(nvdimm); + cxlmd =3D cxl_nvd->cxlmd; + + /* TODO: Region creation support only for interleave way =3D=3D 1 */ + if (!(params->nlabel =3D=3D 1)) { + dev_dbg(&cxlmd->dev, + "Region Creation is not supported with iw > 1\n"); + return; + } + + struct cxl_decoder *cxld __free(put_cxl_decoder) =3D + cxl_find_free_ep_decoder(cxlmd->endpoint); + if (!cxld) { + dev_err(&cxlmd->dev, "CXL endpoint decoder not found\n"); + return; + } + + cxled =3D to_cxl_endpoint_decoder(&cxld->dev); + + struct cxl_root_decoder *cxlrd __free(put_cxl_root_decoder) =3D + cxl_find_root_decoder_by_port(cxlmd->endpoint, cxled); + if (!cxlrd) { + dev_err(&cxlmd->dev, "CXL root decoder not found\n"); + return; + } + + cxlr =3D cxl_create_region(cxlrd, CXL_PARTMODE_PMEM, + atomic_read(&cxlrd->region_id), + params, cxled); + if (IS_ERR(cxlr)) + dev_warn(&cxlmd->dev, "Region Creation failed\n"); +} +EXPORT_SYMBOL_NS_GPL(create_pmem_region, "CXL"); diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c index 9a86d1c467b2..1b39f7028ca1 100644 --- a/drivers/cxl/core/region.c +++ b/drivers/cxl/core/region.c @@ -838,25 +838,22 @@ static int check_commit_order(struct device *dev, voi= d *data) return 0; } =20 -static int match_free_decoder(struct device *dev, const void *data) +bool is_free_decoder(struct device *dev) { struct cxl_port *port =3D to_cxl_port(dev->parent); struct cxl_decoder *cxld; int rc; =20 - if (!is_switch_decoder(dev)) - return 0; - cxld =3D to_cxl_decoder(dev); =20 if (cxld->id !=3D port->commit_end + 1) - return 0; + return false; =20 if (cxld->region) { dev_dbg(dev->parent, "next decoder to commit (%s) is already reserved (%s)\n", dev_name(dev), dev_name(&cxld->region->dev)); - return 0; + return false; } =20 rc =3D device_for_each_child_reverse_from(dev->parent, dev, NULL, @@ -865,9 +862,17 @@ static int match_free_decoder(struct device *dev, cons= t void *data) dev_dbg(dev->parent, "unable to allocate %s due to out of order shutdown\n", dev_name(dev)); - return 0; + return false; } - return 1; + return true; +} + +static int match_free_decoder(struct device *dev, const void *data) +{ + if (!is_switch_decoder(dev)) + return 0; + + return is_free_decoder(dev); } =20 static bool spa_maps_hpa(const struct cxl_region_params *p, diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h index 8c76c4a981bf..088841a3e238 100644 --- a/drivers/cxl/cxl.h +++ b/drivers/cxl/cxl.h @@ -792,6 +792,7 @@ struct cxl_root *find_cxl_root(struct cxl_port *port); DEFINE_FREE(put_cxl_root, struct cxl_root *, if (_T) put_device(&_T->port.= dev)) DEFINE_FREE(put_cxl_port, struct cxl_port *, if (!IS_ERR_OR_NULL(_T)) put_= device(&_T->dev)) DEFINE_FREE(put_cxl_root_decoder, struct cxl_root_decoder *, if (!IS_ERR_O= R_NULL(_T)) put_device(&_T->cxlsd.cxld.dev)) +DEFINE_FREE(put_cxl_decoder, struct cxl_decoder *, if (!IS_ERR_OR_NULL(_T)= ) put_device(&_T->dev)) DEFINE_FREE(put_cxl_region, struct cxl_region *, if (!IS_ERR_OR_NULL(_T)) = put_device(&_T->dev)) =20 int devm_cxl_enumerate_ports(struct cxl_memdev *cxlmd); @@ -933,6 +934,7 @@ static inline int cxl_region_discovery(struct cxl_memde= v *cxlmd) #ifdef CONFIG_CXL_PMEM_REGION bool is_cxl_pmem_region(struct device *dev); struct cxl_pmem_region *to_cxl_pmem_region(struct device *dev); +void create_pmem_region(struct nvdimm *nvdimm); #else static inline bool is_cxl_pmem_region(struct device *dev) { @@ -942,6 +944,9 @@ static inline struct cxl_pmem_region *to_cxl_pmem_regio= n(struct device *dev) { return NULL; } +static inline void create_pmem_region(struct nvdimm *nvdimm) +{ +} #endif =20 void cxl_endpoint_parse_cdat(struct cxl_port *port); --=20 2.34.1 From nobody Sun Feb 8 15:08:14 2026 Received: from mailout1.samsung.com (mailout1.samsung.com [203.254.224.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E5A8C35FF57 for ; Fri, 9 Jan 2026 12:45:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=203.254.224.24 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962739; cv=none; b=DQbNSQVx2NHp6relHfz8AztKzB5IJHbKLtxyivyL4+RaBCSBk3mWVlVIPyVJc781f8NpOVRfVhWzK/91XlEI/Sl8STCOy5Ws6+mKUXOFYJZn3q1Nj6iGEncVhkWvfCHanwb8wHoSs7Sn2RixUYi4pRrb5cnr+LWPfUO8QrVKBpk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767962739; c=relaxed/simple; bh=EhYuxnRW3T+38D3RogRWydt55MzA3B0k4DPqzmHGf2s=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:MIME-Version: Content-Type:References; b=BDsCj++Bov+7e7ldMGkeWn8h0rekQMW3JpCDu1IF+wutRULnyoTMrFcrDceuwENEZC5PrpEpM3TIHdypqis7twt/L8lzMdlN8rsT4HE4np3ORGkh6BJds6w7rFIdUTp1oMX+2DYpp5Fz+d9BTmR3y5TNqYwftaXYnrsLcmJxuJY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com; spf=pass smtp.mailfrom=samsung.com; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b=LdlifuX2; arc=none smtp.client-ip=203.254.224.24 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=samsung.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="LdlifuX2" Received: from epcas5p2.samsung.com (unknown [182.195.41.40]) by mailout1.samsung.com (KnoxPortal) with ESMTP id 20260109124536epoutp0148ca3868fef72287f4f8230846f394d1~JEL3Uwoke0793407934epoutp01t for ; Fri, 9 Jan 2026 12:45:36 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.samsung.com 20260109124536epoutp0148ca3868fef72287f4f8230846f394d1~JEL3Uwoke0793407934epoutp01t DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1767962736; bh=c2KxUsO9ytOrBf7X4mfY7fSpb3M6uH0SntlKavJZqz0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=LdlifuX2DaCIWnCvJjI58YI0vAiYicA97CWRmB3RjbFnXwabXpjFftfn9VaX0Rxgn rJNudBDNx81CBSJ2yFoBTImKqoZZiVJ8YSFoJy1dAXKF5AycarCVUAN4rw4TRWgrNL C2VJcdk0bGnCwLKYJ4VF+lA82ZoqYb2J5AHf6GXs= Received: from epsnrtp02.localdomain (unknown [182.195.42.154]) by epcas5p2.samsung.com (KnoxPortal) with ESMTPS id 20260109124535epcas5p2f9abcdcc26f7459a79e5d3020277dc8b~JEL27yUTL3051830518epcas5p2U; Fri, 9 Jan 2026 12:45:35 +0000 (GMT) Received: from epcas5p3.samsung.com (unknown [182.195.38.94]) by epsnrtp02.localdomain (Postfix) with ESMTP id 4dnhMM0n6Zz2SSKX; Fri, 9 Jan 2026 12:45:35 +0000 (GMT) Received: from epsmtip1.samsung.com (unknown [182.195.34.30]) by epcas5p4.samsung.com (KnoxPortal) with ESMTPA id 20260109124534epcas5p47d59d746b77254f428735268d7731623~JEL1on_Kl0099900999epcas5p4a; Fri, 9 Jan 2026 12:45:34 +0000 (GMT) Received: from test-PowerEdge-R740xd.samsungds.net (unknown [107.99.41.79]) by epsmtip1.samsung.com (KnoxPortal) with ESMTPA id 20260109124532epsmtip1af04cb5e85158423bed17bbf6264adc0~JEL0TJlMG0977009770epsmtip1o; Fri, 9 Jan 2026 12:45:32 +0000 (GMT) From: Neeraj Kumar To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev, linux-kernel@vger.kernel.org, gost.dev@samsung.com Cc: a.manzanares@samsung.com, vishak.g@samsung.com, neeraj.kernel@gmail.com, Neeraj Kumar Subject: [PATCH V5 17/17] cxl/pmem: Add CXL LSA 2.1 support in cxl pmem Date: Fri, 9 Jan 2026 18:14:37 +0530 Message-Id: <20260109124437.4025893-18-s.neeraj@samsung.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260109124437.4025893-1-s.neeraj@samsung.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CMS-MailID: 20260109124534epcas5p47d59d746b77254f428735268d7731623 X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" CMS-TYPE: 105P cpgsPolicy: CPGSC10-542,Y X-CFilter-Loop: Reflected X-CMS-RootMailID: 20260109124534epcas5p47d59d746b77254f428735268d7731623 References: <20260109124437.4025893-1-s.neeraj@samsung.com> Add support of CXL LSA 2.1 using NDD_REGION_LABELING flag. It creates cxl region based on region information parsed from LSA Reviewed-by: Dave Jiang Signed-off-by: Neeraj Kumar Reviewed-by: Jonathan Cameron --- drivers/cxl/pmem.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/cxl/pmem.c b/drivers/cxl/pmem.c index a6eba3572090..5970d1792be8 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; =20 set_bit(NDD_LABELING, &flags); + set_bit(NDD_REGION_LABELING, &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; =20 dev_set_drvdata(dev, nvdimm); + create_pmem_region(nvdimm); return devm_add_action_or_reset(dev, unregister_nvdimm, nvdimm); } =20 --=20 2.34.1