mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [RFC PATCH] cxl: Share media event DPA accessors
@ 2026-11-02  9:58 Richard Cheng
  0 siblings, 0 replies; only message in thread
From: Richard Cheng @ 2026-11-02  9:58 UTC (permalink / raw)
  To: dave, jic23, dave.jiang, alison.schofield, vishal.l.verma
  Cc: iweiny, ming.li, icheng, linux-cxl, linux-kernel

This patch is inspired by Jognwon Lee's series [1], "cxl/edac: Fix
event record lookups for memory repair". While reviewing the series,
I found address unmasking and the packed byte design scattered
around the code base.

Design the common interface to interpret them consistently. Move the DPA
masks and flag def from trace.h to include/cxl/event.h and add typed
accessors, use them in both media trace events, DPA-to-region lookup,
cache insertion, and the existing NOT_REPAIRABLE predicate.

Following CXL 4.0 sections 8.2.10.2.1.1 and 8.2.10.2.1.2, Tables 8-224
and 8-225, preserve bits 63:6 in their byte-address positions, expose
flags 1:0 separately, and exclude reserved bits 5:2 from both results.

Keeping this interpretation beside the record definition gives consumers
a common interface and makes future decoding changes easier to audit.

[1]: https://lore.kernel.org/r/20261101013418.87326-1-ai@linux.com
Signed-off-by: Richard Cheng <icheng@nvidia.com>
---
 drivers/cxl/core/edac.c  | 16 +++-------------
 drivers/cxl/core/mbox.c  |  2 +-
 drivers/cxl/core/trace.h | 25 ++++---------------------
 include/cxl/event.h      | 23 +++++++++++++++++++++++
 4 files changed, 31 insertions(+), 35 deletions(-)

diff --git a/drivers/cxl/core/edac.c b/drivers/cxl/core/edac.c
index 94d44a3dc1f2..8c3b7da1fb9d 100644
--- a/drivers/cxl/core/edac.c
+++ b/drivers/cxl/core/edac.c
@@ -918,19 +918,9 @@ struct cxl_mem_repair_attrbs {
 	enum cxl_mem_repair_type repair_type;
 };
 
-/*
- * The low bits of the event record DPA are flags (VOLATILE, NOT_REPAIRABLE).
- * Records are looked up by the DPA user space writes back, which comes from
- * the trace event and has the flags masked off, so key them the same way.
- */
-static unsigned long cxl_rec_key(const struct cxl_event_media_hdr *hdr)
-{
-	return le64_to_cpu(hdr->phys_addr) & CXL_DPA_MASK;
-}
-
 static bool cxl_rec_not_repairable(const struct cxl_event_media_hdr *hdr)
 {
-	return le64_to_cpu(hdr->phys_addr) & CXL_DPA_NOT_REPAIRABLE;
+	return cxl_event_dpa_flags(hdr) & CXL_DPA_NOT_REPAIRABLE;
 }
 
 static bool cxl_find_rec_gen_media(struct cxl_memdev *cxlmd,
@@ -1143,7 +1133,7 @@ int cxl_store_rec_gen_media(struct cxl_memdev *cxlmd, union cxl_event *evt)
 		return -ENOMEM;
 
 	old_rec = xa_store(&array_rec->rec_gen_media,
-			   cxl_rec_key(&rec->media_hdr), rec, GFP_KERNEL);
+			   cxl_event_dpa(&rec->media_hdr), rec, GFP_KERNEL);
 	if (xa_is_err(old_rec)) {
 		kfree(rec);
 		return xa_err(old_rec);
@@ -1172,7 +1162,7 @@ int cxl_store_rec_dram(struct cxl_memdev *cxlmd, union cxl_event *evt)
 		return -ENOMEM;
 
 	old_rec = xa_store(&array_rec->rec_dram,
-			   cxl_rec_key(&rec->media_hdr), rec, GFP_KERNEL);
+			   cxl_event_dpa(&rec->media_hdr), rec, GFP_KERNEL);
 	if (xa_is_err(old_rec)) {
 		kfree(rec);
 		return xa_err(old_rec);
diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c
index 39485b6bcb97..ea35787dedb4 100644
--- a/drivers/cxl/core/mbox.c
+++ b/drivers/cxl/core/mbox.c
@@ -965,7 +965,7 @@ void cxl_event_trace_record(struct cxl_memdev *cxlmd,
 		guard(rwsem_read)(&cxl_rwsem.region);
 		guard(rwsem_read)(&cxl_rwsem.dpa);
 
-		dpa = le64_to_cpu(evt->media_hdr.phys_addr) & CXL_DPA_MASK;
+		dpa = cxl_event_dpa(&evt->media_hdr);
 		cxlr = cxl_dpa_to_region(cxlmd, dpa);
 		if (cxlr) {
 			u64 cache_size = cxlr->params.cache_size;
diff --git a/drivers/cxl/core/trace.h b/drivers/cxl/core/trace.h
index c379d60047fc..31f8e1f13184 100644
--- a/drivers/cxl/core/trace.h
+++ b/drivers/cxl/core/trace.h
@@ -314,20 +314,6 @@ TRACE_EVENT(cxl_generic_event,
 		__print_hex(__entry->data, CXL_EVENT_RECORD_DATA_LENGTH))
 );
 
-/*
- * Physical Address field masks
- *
- * General Media Event Record
- * CXL rev 3.0 Section 8.2.9.2.1.1; Table 8-43
- *
- * DRAM Event Record
- * CXL rev 3.0 section 8.2.9.2.1.2; Table 8-44
- */
-#define CXL_DPA_FLAGS_MASK			GENMASK(1, 0)
-#define CXL_DPA_MASK				GENMASK_ULL(63, 6)
-
-#define CXL_DPA_VOLATILE			BIT(0)
-#define CXL_DPA_NOT_REPAIRABLE			BIT(1)
 #define show_dpa_flags(flags)	__print_flags(flags, "|",		   \
 	{ CXL_DPA_VOLATILE,			"VOLATILE"		}, \
 	{ CXL_DPA_NOT_REPAIRABLE,		"NOT_REPAIRABLE"	}  \
@@ -490,10 +476,8 @@ TRACE_EVENT(cxl_general_media,
 		__entry->hdr_uuid = CXL_EVENT_GEN_MEDIA_UUID;
 
 		/* General Media */
-		__entry->dpa = le64_to_cpu(rec->media_hdr.phys_addr);
-		__entry->dpa_flags = __entry->dpa & CXL_DPA_FLAGS_MASK;
-		/* Mask after flags have been parsed */
-		__entry->dpa &= CXL_DPA_MASK;
+		__entry->dpa = cxl_event_dpa(&rec->media_hdr);
+		__entry->dpa_flags = cxl_event_dpa_flags(&rec->media_hdr);
 		__entry->descriptor = rec->media_hdr.descriptor;
 		__entry->type = rec->media_hdr.type;
 		__entry->sub_type = rec->sub_type;
@@ -639,9 +623,8 @@ TRACE_EVENT(cxl_dram,
 		__entry->hdr_uuid = CXL_EVENT_DRAM_UUID;
 
 		/* DRAM */
-		__entry->dpa = le64_to_cpu(rec->media_hdr.phys_addr);
-		__entry->dpa_flags = __entry->dpa & CXL_DPA_FLAGS_MASK;
-		__entry->dpa &= CXL_DPA_MASK;
+		__entry->dpa = cxl_event_dpa(&rec->media_hdr);
+		__entry->dpa_flags = cxl_event_dpa_flags(&rec->media_hdr);
 		__entry->descriptor = rec->media_hdr.descriptor;
 		__entry->type = rec->media_hdr.type;
 		__entry->sub_type = rec->sub_type;
diff --git a/include/cxl/event.h b/include/cxl/event.h
index b5673384d930..2c7028116e53 100644
--- a/include/cxl/event.h
+++ b/include/cxl/event.h
@@ -3,7 +3,9 @@
 #ifndef _LINUX_CXL_EVENT_H
 #define _LINUX_CXL_EVENT_H
 
+#include <linux/bits.h>
 #include <linux/types.h>
+#include <linux/unaligned.h>
 #include <linux/uuid.h>
 #include <linux/workqueue_types.h>
 
@@ -39,6 +41,27 @@ struct cxl_event_media_hdr {
 	u8 rank;
 } __packed;
 
+/*
+ * Physical Address encoding shared by General Media and DRAM event records.
+ * CXL rev 4.0 sections 8.2.10.2.1.1 and 8.2.10.2.1.2; Tables 8-224 and 8-225.
+ * Bits 63:6 contain DPA[63:6], bits 5:2 are reserved, and bits 1:0 are flags.
+ */
+#define CXL_DPA_FLAGS_MASK	GENMASK(1, 0)
+#define CXL_DPA_MASK		GENMASK_ULL(63, 6)
+#define CXL_DPA_VOLATILE		BIT(0)
+#define CXL_DPA_NOT_REPAIRABLE	BIT(1)
+
+/* Return a byte address, keeping the DPA bits in their original positions. */
+static inline u64 cxl_event_dpa(const struct cxl_event_media_hdr *hdr)
+{
+	return get_unaligned_le64(&hdr->phys_addr) & CXL_DPA_MASK;
+}
+
+static inline u8 cxl_event_dpa_flags(const struct cxl_event_media_hdr *hdr)
+{
+	return get_unaligned_le64(&hdr->phys_addr) & CXL_DPA_FLAGS_MASK;
+}
+
 #define CXL_EVENT_RECORD_DATA_LENGTH 0x50
 struct cxl_event_generic {
 	struct cxl_event_record_hdr hdr;
-- 
2.43.0


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2026-11-02  9:59 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-02  9:58 [RFC PATCH] cxl: Share media event DPA accessors Richard Cheng

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®