Blame SOURCES/0182-cxl-list-Emit-mode-for-endpoint-decoder-objects.patch

e0018b
From d2a7fc7fb87396eb267cf6c8948468f7e56bea89 Mon Sep 17 00:00:00 2001
e0018b
From: Dan Williams <dan.j.williams@intel.com>
e0018b
Date: Thu, 14 Jul 2022 10:02:33 -0700
e0018b
Subject: [PATCH 182/217] cxl/list: Emit 'mode' for endpoint decoder objects
e0018b
e0018b
The 'mode' property of an endpoint decoder indicates the access
e0018b
properties of the DPA (device physical address) mapped into HPA (host
e0018b
physical address) by the decoder. Where the modes are 'none'
e0018b
(decoder-disabled), 'ram' (voltaile memory), 'pmem' (persistent memory),
e0018b
and 'mixed' (an unexpected, but possible, case where the decoder
e0018b
straddles a mode / partition boundary).
e0018b
e0018b
Link: https://lore.kernel.org/r/165781815306.1555691.17541956592287631419.stgit@dwillia2-xfh.jf.intel.com
e0018b
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
e0018b
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
e0018b
---
e0018b
 Documentation/cxl/lib/libcxl.txt |  9 +++++++++
e0018b
 cxl/json.c                       |  8 ++++++++
e0018b
 cxl/lib/libcxl.c                 | 30 ++++++++++++++++++++++++++++++
e0018b
 cxl/lib/libcxl.sym               |  1 +
e0018b
 cxl/lib/private.h                |  1 +
e0018b
 cxl/libcxl.h                     | 23 +++++++++++++++++++++++
e0018b
 6 files changed, 72 insertions(+)
e0018b
e0018b
diff --git a/Documentation/cxl/lib/libcxl.txt b/Documentation/cxl/lib/libcxl.txt
e0018b
index 2aef489..90fe338 100644
e0018b
--- a/Documentation/cxl/lib/libcxl.txt
e0018b
+++ b/Documentation/cxl/lib/libcxl.txt
e0018b
@@ -405,6 +405,15 @@ enum cxl_decoder_target_type {
e0018b
 };
e0018b
 
e0018b
 cxl_decoder_get_target_type(struct cxl_decoder *decoder);
e0018b
+
e0018b
+enum cxl_decoder_mode {
e0018b
+	CXL_DECODER_MODE_NONE,
e0018b
+	CXL_DECODER_MODE_MIXED,
e0018b
+	CXL_DECODER_MODE_PMEM,
e0018b
+	CXL_DECODER_MODE_RAM,
e0018b
+};
e0018b
+enum cxl_decoder_mode cxl_decoder_get_mode(struct cxl_decoder *decoder);
e0018b
+
e0018b
 bool cxl_decoder_is_pmem_capable(struct cxl_decoder *decoder);
e0018b
 bool cxl_decoder_is_volatile_capable(struct cxl_decoder *decoder);
e0018b
 bool cxl_decoder_is_mem_capable(struct cxl_decoder *decoder);
e0018b
diff --git a/cxl/json.c b/cxl/json.c
e0018b
index 3f52d3b..ae9c812 100644
e0018b
--- a/cxl/json.c
e0018b
+++ b/cxl/json.c
e0018b
@@ -473,6 +473,8 @@ struct json_object *util_cxl_decoder_to_json(struct cxl_decoder *decoder,
e0018b
 	}
e0018b
 
e0018b
 	if (cxl_port_is_endpoint(port)) {
e0018b
+		enum cxl_decoder_mode mode = cxl_decoder_get_mode(decoder);
e0018b
+
e0018b
 		size = cxl_decoder_get_dpa_size(decoder);
e0018b
 		val = cxl_decoder_get_dpa_resource(decoder);
e0018b
 		if (size && val < ULLONG_MAX) {
e0018b
@@ -488,6 +490,12 @@ struct json_object *util_cxl_decoder_to_json(struct cxl_decoder *decoder,
e0018b
 				json_object_object_add(jdecoder, "dpa_size",
e0018b
 						       jobj);
e0018b
 		}
e0018b
+
e0018b
+		if (mode > CXL_DECODER_MODE_NONE) {
e0018b
+			jobj = json_object_new_string(cxl_decoder_mode_name(mode));
e0018b
+			if (jobj)
e0018b
+				json_object_object_add(jdecoder, "mode", jobj);
e0018b
+		}
e0018b
 	}
e0018b
 
e0018b
 	if (cxl_port_is_root(port) && cxl_decoder_is_mem_capable(decoder)) {
e0018b
diff --git a/cxl/lib/libcxl.c b/cxl/lib/libcxl.c
e0018b
index ea597f6..b802e5d 100644
e0018b
--- a/cxl/lib/libcxl.c
e0018b
+++ b/cxl/lib/libcxl.c
e0018b
@@ -961,6 +961,21 @@ static void *add_cxl_decoder(void *parent, int id, const char *cxldecoder_base)
e0018b
 	else
e0018b
 		decoder->size = strtoull(buf, NULL, 0);
e0018b
 
e0018b
+	sprintf(path, "%s/mode", cxldecoder_base);
e0018b
+	if (sysfs_read_attr(ctx, path, buf) == 0) {
e0018b
+		if (strcmp(buf, "ram") == 0)
e0018b
+			decoder->mode = CXL_DECODER_MODE_RAM;
e0018b
+		else if (strcmp(buf, "pmem") == 0)
e0018b
+			decoder->mode = CXL_DECODER_MODE_PMEM;
e0018b
+		else if (strcmp(buf, "mixed") == 0)
e0018b
+			decoder->mode = CXL_DECODER_MODE_MIXED;
e0018b
+		else if (strcmp(buf, "none") == 0)
e0018b
+			decoder->mode = CXL_DECODER_MODE_NONE;
e0018b
+		else
e0018b
+			decoder->mode = CXL_DECODER_MODE_MIXED;
e0018b
+	} else
e0018b
+		decoder->mode = CXL_DECODER_MODE_NONE;
e0018b
+
e0018b
 	switch (port->type) {
e0018b
 	case CXL_PORT_ENDPOINT:
e0018b
 		sprintf(path, "%s/dpa_resource", cxldecoder_base);
e0018b
@@ -1161,6 +1176,21 @@ cxl_decoder_get_dpa_size(struct cxl_decoder *decoder)
e0018b
 	return decoder->dpa_size;
e0018b
 }
e0018b
 
e0018b
+CXL_EXPORT enum cxl_decoder_mode
e0018b
+cxl_decoder_get_mode(struct cxl_decoder *decoder)
e0018b
+{
e0018b
+	struct cxl_port *port = cxl_decoder_get_port(decoder);
e0018b
+	struct cxl_ctx *ctx = cxl_decoder_get_ctx(decoder);
e0018b
+
e0018b
+	if (!cxl_port_is_endpoint(port)) {
e0018b
+		err(ctx, "%s: not an endpoint decoder\n",
e0018b
+		    cxl_decoder_get_devname(decoder));
e0018b
+		return CXL_DECODER_MODE_NONE;
e0018b
+	}
e0018b
+
e0018b
+	return decoder->mode;
e0018b
+}
e0018b
+
e0018b
 CXL_EXPORT enum cxl_decoder_target_type
e0018b
 cxl_decoder_get_target_type(struct cxl_decoder *decoder)
e0018b
 {
e0018b
diff --git a/cxl/lib/libcxl.sym b/cxl/lib/libcxl.sym
e0018b
index 8e2fc75..88c5a7e 100644
e0018b
--- a/cxl/lib/libcxl.sym
e0018b
+++ b/cxl/lib/libcxl.sym
e0018b
@@ -172,4 +172,5 @@ LIBCXL_3 {
e0018b
 global:
e0018b
 	cxl_decoder_get_dpa_resource;
e0018b
 	cxl_decoder_get_dpa_size;
e0018b
+	cxl_decoder_get_mode;
e0018b
 } LIBCXL_2;
e0018b
diff --git a/cxl/lib/private.h b/cxl/lib/private.h
e0018b
index 24a2ae6..f6d4573 100644
e0018b
--- a/cxl/lib/private.h
e0018b
+++ b/cxl/lib/private.h
e0018b
@@ -108,6 +108,7 @@ struct cxl_decoder {
e0018b
 	char *dev_path;
e0018b
 	int nr_targets;
e0018b
 	int id;
e0018b
+	enum cxl_decoder_mode mode;
e0018b
 	bool pmem_capable;
e0018b
 	bool volatile_capable;
e0018b
 	bool mem_capable;
e0018b
diff --git a/cxl/libcxl.h b/cxl/libcxl.h
e0018b
index 76aebe3..1436dc4 100644
e0018b
--- a/cxl/libcxl.h
e0018b
+++ b/cxl/libcxl.h
e0018b
@@ -127,10 +127,33 @@ struct cxl_dport *cxl_port_get_dport_by_memdev(struct cxl_port *port,
e0018b
 struct cxl_decoder;
e0018b
 struct cxl_decoder *cxl_decoder_get_first(struct cxl_port *port);
e0018b
 struct cxl_decoder *cxl_decoder_get_next(struct cxl_decoder *decoder);
e0018b
+struct cxl_decoder *cxl_decoder_get_last(struct cxl_port *port);
e0018b
+struct cxl_decoder *cxl_decoder_get_prev(struct cxl_decoder *decoder);
e0018b
 unsigned long long cxl_decoder_get_resource(struct cxl_decoder *decoder);
e0018b
 unsigned long long cxl_decoder_get_size(struct cxl_decoder *decoder);
e0018b
 unsigned long long cxl_decoder_get_dpa_resource(struct cxl_decoder *decoder);
e0018b
 unsigned long long cxl_decoder_get_dpa_size(struct cxl_decoder *decoder);
e0018b
+enum cxl_decoder_mode {
e0018b
+	CXL_DECODER_MODE_NONE,
e0018b
+	CXL_DECODER_MODE_MIXED,
e0018b
+	CXL_DECODER_MODE_PMEM,
e0018b
+	CXL_DECODER_MODE_RAM,
e0018b
+};
e0018b
+static inline const char *cxl_decoder_mode_name(enum cxl_decoder_mode mode)
e0018b
+{
e0018b
+	static const char *names[] = {
e0018b
+		[CXL_DECODER_MODE_NONE] = "none",
e0018b
+		[CXL_DECODER_MODE_MIXED] = "mixed",
e0018b
+		[CXL_DECODER_MODE_PMEM] = "pmem",
e0018b
+		[CXL_DECODER_MODE_RAM] = "ram",
e0018b
+	};
e0018b
+
e0018b
+	if (mode < CXL_DECODER_MODE_NONE || mode > CXL_DECODER_MODE_RAM)
e0018b
+		mode = CXL_DECODER_MODE_NONE;
e0018b
+	return names[mode];
e0018b
+}
e0018b
+
e0018b
+enum cxl_decoder_mode cxl_decoder_get_mode(struct cxl_decoder *decoder);
e0018b
 const char *cxl_decoder_get_devname(struct cxl_decoder *decoder);
e0018b
 struct cxl_target *cxl_decoder_get_target_by_memdev(struct cxl_decoder *decoder,
e0018b
 						    struct cxl_memdev *memdev);
e0018b
-- 
e0018b
2.27.0
e0018b