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

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