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