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

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