From: Vaibhav Jain <vaibhav@linux.ibm.com>
To: linux-nvdimm@lists.01.org
Cc: Vaibhav Jain <vaibhav@linux.ibm.com>,
"Aneesh Kumar K . V" <aneesh.kumar@linux.ibm.com>
Subject: [ndctl PATCH v7 2/5] libncdtl: Add initial support for NVDIMM_FAMILY_PAPR nvdimm family
Date: Thu, 18 Jun 2020 12:31:01 +0530 [thread overview]
Message-ID: <20200618070104.239446-3-vaibhav@linux.ibm.com> (raw)
In-Reply-To: <20200618070104.239446-1-vaibhav@linux.ibm.com>
Add necessary scaffolding in libndctl for dimms that support the
papr_scm specification[1]. Since there can be platforms that support
Open-Firmware[2] but not the papr_scm specification, the changes
proposed first add support for probing if the dimm bus supports
Open-Firmware. This is done by querying for the sysfs attribute
'of_node' in dimm device sysfs directory. If available newly
introduced member 'struct ndctl_bus.has_of_node' is set. During
'add_dimm()', the newly introduced add_papr_dimm() is called if dimm
bus reports supports Open-Firmware.
Function add_papr_dimm() queries the 'compatible' device tree
attribute via newly introduced ndctl_bus_is_papr_scm() and based on
its value assigns NVDIMM_FAMILY_PAPR to the dimm command family. In
the future, based on the contents of 'compatible' attribute more
of_pmem dimm families can be queried.
Additionally add support for parsing the dimm flags for
NVDIMM_FAMILY_PAPR supporting nvdimms as described at [3]. A newly
introduced function parse_papr_flags() reads the contents of this
flag file and sets appropriate flag bits in 'struct
ndctl_dimm.flags'.
Also, advertise support for monitor mode.
References:
[1] Documentation/powerpc/papr_hcalls.rst
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/powerpc/papr_hcalls.rst
[2] https://en.wikipedia.org/wiki/Open_Firmware
[3] Documentation/ABI/testing/sysfs-bus-papr-pmem
https://git.kernel.org/nvdimm/nvdimm/c/b791abf3201d724ac372c2ba1fa6e90d192e1dbf
Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com>
---
Changelog:
v6..v7:
* Updated patch description based of review comments on v6 [ Vishal ]
* Updated links in patch description to current version. [ Vishal ]
* Added the missing copyright text in 'papr.c'
v5..v6:
* Updated various dbg messages to use consistent dimm device name
rather than dimm-id. [Vishal]
* Minor changes to log messages in add_papr_dimm() [ Vishal ]
* Minor change in parse_papr_flags() to aid in code readability [Vishal]
* Added ndctl_bus_has_of_node() to library ld version script. [Vishal]
* Added new library function ndctl_bus_is_papr_scm() that checks the
device tree compatible field [Vishal]
* Updated add_papr_dimm() to use ndctl_bus_is_papr_scm() [Vishal]
* Updated the license header of 'papr.c' to LGPL 2.1
v4..v5:
* Renamed file 'papr_scm.c' to 'papr.c'
* s/NVDIMM_FAMILY_PAPR_SCM/NVDIMM_FAMILY_PAPR/g
* s/papr_scm_dimm_ops/papr_dimm_ops/g
* s/parse_papr_scm_flags()/parse_papr_flags()/g
* Updated patch description & title to reflect new command family name
and file-names.
v3..v4:
* None
v2..v3:
* Renamed add_of_pmem() to add_papr_dimm() [ Aneesh ]
v1..v2:
* Squashed the patch to parse dimm flags
* Updated the dimm flags parsing to add case for 'restore_fail' and
'flush_fail'.
* Renamed parse_of_pmem_flags() to parse_papr_scm_flags().
* Updated the path to dimm flags file to 'papr/flags'.
* Introduced 'papr_scm.c' file in this patch rather than later in the
patch series.
* Update add_of_pmem_dimm() to parse dimm flags and enable monitoring
only if 'ibm,pmemory' compatible nvdimm is found.
---
ndctl/lib/Makefile.am | 1 +
ndctl/lib/libndctl.c | 84 ++++++++++++++++++++++++++++++++++++++++++
ndctl/lib/libndctl.sym | 5 +++
ndctl/lib/papr.c | 28 ++++++++++++++
ndctl/lib/private.h | 2 +
ndctl/libndctl.h | 2 +
ndctl/ndctl.h | 1 +
7 files changed, 123 insertions(+)
create mode 100644 ndctl/lib/papr.c
diff --git a/ndctl/lib/Makefile.am b/ndctl/lib/Makefile.am
index d6be5c3acd26..e15bb2288575 100644
--- a/ndctl/lib/Makefile.am
+++ b/ndctl/lib/Makefile.am
@@ -23,6 +23,7 @@ libndctl_la_SOURCES =\
hpe1.c \
msft.c \
hyperv.c \
+ papr.c \
ars.c \
firmware.c \
libndctl.c \
diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c
index 5f6dad71975b..24ae27d5979e 100644
--- a/ndctl/lib/libndctl.c
+++ b/ndctl/lib/libndctl.c
@@ -799,6 +799,28 @@ static void parse_nfit_mem_flags(struct ndctl_dimm *dimm, char *flags)
ndctl_dimm_get_devname(dimm), flags);
}
+static void parse_papr_flags(struct ndctl_dimm *dimm, char *flags)
+{
+ struct ndctl_ctx *ctx = ndctl_dimm_get_ctx(dimm);
+ char *start, *end;
+
+ start = flags;
+ while ((end = strchr(start, ' '))) {
+ *end = '\0';
+ if (strcmp(start, "not_armed") == 0)
+ dimm->flags.f_arm = 1;
+ else if (strcmp(start, "flush_fail") == 0)
+ dimm->flags.f_flush = 1;
+ else if (strcmp(start, "restore_fail") == 0)
+ dimm->flags.f_restore = 1;
+ else if (strcmp(start, "smart_notify") == 0)
+ dimm->flags.f_smart = 1;
+ start = end + 1;
+ }
+ if (end != start)
+ dbg(ctx, "%s: Flags:%s\n", ndctl_dimm_get_devname(dimm), flags);
+}
+
static void parse_dimm_flags(struct ndctl_dimm *dimm, char *flags)
{
char *start, *end;
@@ -856,6 +878,12 @@ static void *add_bus(void *parent, int id, const char *ctl_base)
bus->revision = strtoul(buf, NULL, 0);
}
+ sprintf(path, "%s/device/of_node/compatible", ctl_base);
+ if (sysfs_read_attr(ctx, path, buf) < 0)
+ bus->has_of_node = 0;
+ else
+ bus->has_of_node = 1;
+
sprintf(path, "%s/device/nfit/dsm_mask", ctl_base);
if (sysfs_read_attr(ctx, path, buf) < 0)
bus->nfit_dsm_mask = 0;
@@ -964,6 +992,23 @@ NDCTL_EXPORT int ndctl_bus_has_nfit(struct ndctl_bus *bus)
return bus->has_nfit;
}
+NDCTL_EXPORT int ndctl_bus_has_of_node(struct ndctl_bus *bus)
+{
+ return bus->has_of_node;
+}
+
+NDCTL_EXPORT int ndctl_bus_is_papr_scm(struct ndctl_bus *bus)
+{
+ char buf[SYSFS_ATTR_SIZE];
+
+ snprintf(bus->bus_buf, bus->buf_len,
+ "%s/of_node/compatible", bus->bus_path);
+ if (sysfs_read_attr(bus->ctx, bus->bus_buf, buf) < 0)
+ return 0;
+
+ return (strcmp(buf, "ibm,pmemory") == 0);
+}
+
/**
* ndctl_bus_get_major - nd bus character device major number
* @bus: ndctl_bus instance returned from ndctl_bus_get_{first|next}
@@ -1441,6 +1486,40 @@ static int ndctl_bind(struct ndctl_ctx *ctx, struct kmod_module *module,
static int ndctl_unbind(struct ndctl_ctx *ctx, const char *devpath);
static struct kmod_module *to_module(struct ndctl_ctx *ctx, const char *alias);
+static int add_papr_dimm(struct ndctl_dimm *dimm, const char *dimm_base)
+{
+ int rc = -ENODEV;
+ char buf[SYSFS_ATTR_SIZE];
+ struct ndctl_ctx *ctx = dimm->bus->ctx;
+ char *path = calloc(1, strlen(dimm_base) + 100);
+ const char * const devname = ndctl_dimm_get_devname(dimm);
+
+ dbg(ctx, "%s: Probing of_pmem dimm at %s\n", devname, dimm_base);
+
+ if (!path)
+ return -ENOMEM;
+
+ /* construct path to the papr compatible dimm flags file */
+ sprintf(path, "%s/papr/flags", dimm_base);
+
+ if (ndctl_bus_is_papr_scm(dimm->bus) &&
+ sysfs_read_attr(ctx, path, buf) == 0) {
+
+ dbg(ctx, "%s: Adding papr-scm dimm flags:\"%s\"\n", devname, buf);
+ dimm->cmd_family = NVDIMM_FAMILY_PAPR;
+
+ /* Parse dimm flags */
+ parse_papr_flags(dimm, buf);
+
+ /* Allocate monitor mode fd */
+ dimm->health_eventfd = open(path, O_RDONLY|O_CLOEXEC);
+ rc = 0;
+ }
+
+ free(path);
+ return rc;
+}
+
static int add_nfit_dimm(struct ndctl_dimm *dimm, const char *dimm_base)
{
int i, rc = -1;
@@ -1619,6 +1698,8 @@ static void *add_dimm(void *parent, int id, const char *dimm_base)
if (ndctl_bus_has_nfit(bus)) {
dimm->formats = formats;
rc = add_nfit_dimm(dimm, dimm_base);
+ } else if (ndctl_bus_has_of_node(bus)) {
+ rc = add_papr_dimm(dimm, dimm_base);
}
if (rc == -ENODEV) {
@@ -1636,6 +1717,9 @@ static void *add_dimm(void *parent, int id, const char *dimm_base)
dimm->ops = msft_dimm_ops;
if (dimm->cmd_family == NVDIMM_FAMILY_HYPERV)
dimm->ops = hyperv_dimm_ops;
+ if (dimm->cmd_family == NVDIMM_FAMILY_PAPR)
+ dimm->ops = papr_dimm_ops;
+
out:
if (rc) {
err(ctx, "%s: probe failed: %s\n", ndctl_dimm_get_devname(dimm),
diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym
index ac575a23d035..9cfaccf5d3b7 100644
--- a/ndctl/lib/libndctl.sym
+++ b/ndctl/lib/libndctl.sym
@@ -431,3 +431,8 @@ LIBNDCTL_23 {
ndctl_region_get_align;
ndctl_region_set_align;
} LIBNDCTL_22;
+
+LIBNDCTL_24 {
+ ndctl_bus_has_of_node;
+ ndctl_bus_is_papr_scm;
+} LIBNDCTL_23;
diff --git a/ndctl/lib/papr.c b/ndctl/lib/papr.c
new file mode 100644
index 000000000000..2d1be73e455f
--- /dev/null
+++ b/ndctl/lib/papr.c
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: LGPL-2.1
+/*
+ * libndctl support for PAPR-SCM based NVDIMMs
+ *
+ * (C) Copyright IBM 2020
+ *
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <util/log.h>
+#include <ndctl.h>
+#include <ndctl/libndctl.h>
+#include <lib/private.h>
+
+static bool papr_cmd_is_supported(struct ndctl_dimm *dimm, int cmd)
+{
+ /* Handle this separately to support monitor mode */
+ if (cmd == ND_CMD_SMART)
+ return true;
+
+ return !!(dimm->cmd_mask & (1ULL << cmd));
+}
+
+struct ndctl_dimm_ops * const papr_dimm_ops = &(struct ndctl_dimm_ops) {
+ .cmd_is_supported = papr_cmd_is_supported,
+};
diff --git a/ndctl/lib/private.h b/ndctl/lib/private.h
index 2e537f0a8649..d90236b1f98b 100644
--- a/ndctl/lib/private.h
+++ b/ndctl/lib/private.h
@@ -167,6 +167,7 @@ struct ndctl_bus {
int dimms_init;
int regions_init;
int has_nfit;
+ int has_of_node;
char *bus_path;
char *bus_buf;
size_t buf_len;
@@ -352,6 +353,7 @@ extern struct ndctl_dimm_ops * const intel_dimm_ops;
extern struct ndctl_dimm_ops * const hpe1_dimm_ops;
extern struct ndctl_dimm_ops * const msft_dimm_ops;
extern struct ndctl_dimm_ops * const hyperv_dimm_ops;
+extern struct ndctl_dimm_ops * const papr_dimm_ops;
static inline struct ndctl_bus *cmd_to_bus(struct ndctl_cmd *cmd)
{
diff --git a/ndctl/libndctl.h b/ndctl/libndctl.h
index 2580f433ade8..e16fb7eaf34b 100644
--- a/ndctl/libndctl.h
+++ b/ndctl/libndctl.h
@@ -119,6 +119,8 @@ struct ndctl_bus *ndctl_bus_get_next(struct ndctl_bus *bus);
bus = ndctl_bus_get_next(bus))
struct ndctl_ctx *ndctl_bus_get_ctx(struct ndctl_bus *bus);
int ndctl_bus_has_nfit(struct ndctl_bus *bus);
+int ndctl_bus_has_of_node(struct ndctl_bus *bus);
+int ndctl_bus_is_papr_scm(struct ndctl_bus *bus);
unsigned int ndctl_bus_get_major(struct ndctl_bus *bus);
unsigned int ndctl_bus_get_minor(struct ndctl_bus *bus);
const char *ndctl_bus_get_devname(struct ndctl_bus *bus);
diff --git a/ndctl/ndctl.h b/ndctl/ndctl.h
index 008f81cdeb9f..3b64f66d58cc 100644
--- a/ndctl/ndctl.h
+++ b/ndctl/ndctl.h
@@ -263,6 +263,7 @@ struct nd_cmd_pkg {
#define NVDIMM_FAMILY_HPE2 2
#define NVDIMM_FAMILY_MSFT 3
#define NVDIMM_FAMILY_HYPERV 4
+#define NVDIMM_FAMILY_PAPR 5
#define ND_IOCTL_CALL _IOWR(ND_IOCTL, ND_CMD_CALL,\
struct nd_cmd_pkg)
--
2.26.2
_______________________________________________
Linux-nvdimm mailing list -- linux-nvdimm@lists.01.org
To unsubscribe send an email to linux-nvdimm-leave@lists.01.org
next prev parent reply other threads:[~2020-06-18 7:01 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-06-18 7:00 [ndctl PATCH v7 0/5] Add support for reporting papr nvdimm health Vaibhav Jain
2020-06-18 7:01 ` [ndctl PATCH v7 1/5] libndctl: Refactor out add_dimm() to handle NFIT specific init Vaibhav Jain
2020-06-18 7:01 ` Vaibhav Jain [this message]
2020-06-18 7:01 ` [ndctl PATCH v7 3/5] libndctl,papr_scm: Add definitions for PAPR nvdimm specific methods Vaibhav Jain
2020-06-18 7:01 ` [ndctl PATCH v7 4/5] papr: Add scaffolding to issue and handle PDSM requests Vaibhav Jain
2020-06-18 7:01 ` [ndctl PATCH v7 5/5] libndctl,papr_scm: Implement support for PAPR_PDSM_HEALTH Vaibhav Jain
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200618070104.239446-3-vaibhav@linux.ibm.com \
--to=vaibhav@linux.ibm.com \
--cc=aneesh.kumar@linux.ibm.com \
--cc=linux-nvdimm@lists.01.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox