|
|
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 |
|