public inbox for linux-nvdimm@lists.01.org
 help / color / mirror / Atom feed
From: Yasunori Goto <y-goto@jp.fujitsu.com>
To: NVDIMM-ML <linux-nvdimm@lists.01.org>
Subject: [RFC/Patch 4/5] libndctl Make interfaces to use Translate SPA
Date: Fri, 04 Aug 2017 18:12:25 +0900	[thread overview]
Message-ID: <20170804181223.27CC.E1E9C6FF@jp.fujitsu.com> (raw)
In-Reply-To: <20170804180231.27BC.E1E9C6FF@jp.fujitsu.com>

ndctl:libndctl Make interfaces to use Translate SPA.

This patch makes 3 new interfaces :
  - to ask bus has translate SPA feature.
  - to call translate SPA.
  - to find DIMM by SPA address.


Note) I'm not sure how many buffer should be prepared, because
      it depends on max # of mirroring way.
      This patch assume maxmum # is 4 way.


Signed-off-by: Yasunori Goto <y-goto@jp.fujitsu.com>

---
 configure.ac                 |  19 ++++++++
 ndctl/lib/libndctl-private.h |   7 +++
 ndctl/lib/libndctl.c         | 103 ++++++++++++++++++++++++++++++++++++++++++-
 ndctl/lib/libndctl.sym       |   3 ++
 ndctl/libndctl.h.in          |  23 ++++++++++
 ndctl/ndctl.h                |   8 ++++
 6 files changed, 162 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index 316f5b7..653fde0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -162,6 +162,25 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
 )
 AM_CONDITIONAL([ENABLE_CLEAR_ERROR], [test "x$enable_clear_err" = "xyes"])
 
+AC_MSG_CHECKING([for TRANSLATE SPA support])
+AC_LANG(C)
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+                       #ifdef HAVE_NDCTL_H
+                       #include <linux/ndctl.h>
+                       #else
+                       #include "ndctl/ndctl.h"
+                       #endif
+                       ]], [[
+                       int x = ND_CMD_TRANS_SPA;
+                       ]]
+               )], [AC_MSG_RESULT([yes])
+                    enable_trans_spa=yes
+                    AC_DEFINE([HAVE_NDCTL_TRANS_SPA], [1],
+                               [Define to 1 if ndctl.h has TRANSLATE SPA support.])
+               ], [AC_MSG_RESULT([no])]
+)
+AM_CONDITIONAL([ENABLE_TRANS_SPA], [test "x$enable_trans_spa" = "xyes"])
+
 AC_MSG_CHECKING([for device DAX support])
 AC_LANG(C)
 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
diff --git a/ndctl/lib/libndctl-private.h b/ndctl/lib/libndctl-private.h
index 8f10fbc..a1fcd2f 100644
--- a/ndctl/lib/libndctl-private.h
+++ b/ndctl/lib/libndctl-private.h
@@ -196,6 +196,7 @@ struct ndctl_cmd {
 #ifdef HAVE_NDCTL_CLEAR_ERROR
 		struct nd_cmd_clear_error clear_err[0];
 #endif
+		struct nd_cmd_trans_spa trans_spa[0];
 		struct ndn_pkg_hpe1 hpe1[0];
 		struct ndn_pkg_msft msft[0];
 		struct nd_cmd_smart smart[0];
@@ -250,6 +251,12 @@ static const int nd_cmd_clear_error = ND_CMD_CLEAR_ERROR;
 static const int nd_cmd_clear_error;
 #endif
 
+#ifdef HAVE_NDCTL_TRANS_SPA
+static const int nd_cmd_trans_spa = ND_CMD_TRANS_SPA;
+#else
+static const int nd_cmd_trans_spa;
+#endif
+
 static inline struct ndctl_bus *cmd_to_bus(struct ndctl_cmd *cmd)
 {
 	if (cmd->dimm)
diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c
index 68d8064..5ebcc45 100644
--- a/ndctl/lib/libndctl.c
+++ b/ndctl/lib/libndctl.c
@@ -744,7 +744,9 @@ static int to_dsm_index(const char *name, int dimm)
 		end_cmd = ND_CMD_CALL;
 		cmd_name_fn = nvdimm_cmd_name;
 	} else {
-		end_cmd = nd_cmd_clear_error;
+		end_cmd = nd_cmd_trans_spa;
+		if (!end_cmd)
+			end_cmd = nd_cmd_clear_error;
 		if (!end_cmd)
 			end_cmd = nd_cmd_ars_status;
 		cmd_name_fn = nvdimm_bus_cmd_name;
@@ -1943,6 +1945,102 @@ NDCTL_EXPORT struct badblock *ndctl_region_get_first_badblock(struct ndctl_regio
 	return ndctl_region_get_next_badblock(region);
 }
 
+#ifdef HAVE_NDCTL_TRANS_SPA
+NDCTL_EXPORT int ndctl_bus_has_trans_spa(struct ndctl_bus *bus)
+{
+	if (!bus)
+		return 0;
+
+	return ndctl_bus_is_cmd_supported(bus, ND_CMD_TRANS_SPA);
+}
+
+static struct ndctl_cmd *ndctl_bus_cmd_new_trans_spa(struct ndctl_bus *bus)
+{
+	struct ndctl_cmd *cmd;
+	size_t size, spa_length;
+
+	spa_length = sizeof(struct nd_cmd_trans_spa)
+		+ sizeof(struct nd_nvdimm_device) * ND_MIRROR_MAX_WAY;
+	size = sizeof(*cmd) + spa_length;
+	cmd = calloc(1, size);
+	if (!cmd)
+		return NULL;
+
+	cmd->bus = bus;
+	ndctl_cmd_ref(cmd);
+	cmd->type = ND_CMD_TRANS_SPA;
+	cmd->size = size;
+	cmd->status = 1;
+	cmd->firmware_status = &cmd->trans_spa->status;
+	cmd->trans_spa->trans_length = spa_length;
+
+	return cmd;
+}
+
+static int ndctl_bus_cmd_get_trans_spa(struct ndctl_cmd *cmd,
+					unsigned int *handles, unsigned long long *dpas)
+{
+	int i;
+	int num_nvdimms;
+
+	if (cmd->trans_spa->status == ND_TRANS_SPA_STATUS_INVALID_SPA)
+		return -EINVAL;
+
+	num_nvdimms = cmd->trans_spa->num_nvdimms;
+	for (i = 0; i < num_nvdimms; i++) {
+		handles[i] = cmd->trans_spa->devices[i].nfit_device_handle;
+		dpas[i] = cmd->trans_spa->devices[i].dpa;
+	}
+
+	ndctl_cmd_unref(cmd);
+	return 0;
+}
+
+NDCTL_EXPORT int ndctl_bus_cmd_trans_spa(struct ndctl_bus *bus,
+	unsigned long long addr, unsigned int *handles, unsigned long long *dpas)
+{
+
+	struct ndctl_cmd *cmd;
+	int rc;
+
+	cmd = ndctl_bus_cmd_new_trans_spa(bus);
+	cmd->trans_spa->spa = addr;
+
+	rc = ndctl_cmd_submit(cmd);
+	if (rc) {
+		ndctl_cmd_unref(cmd);
+		return rc;
+	}
+
+	rc = ndctl_bus_cmd_get_trans_spa(cmd, handles, dpas);
+
+	return rc;
+}
+
+NDCTL_EXPORT int ndctl_dimms_get_by_spa(struct ndctl_bus *bus, unsigned long long spa,
+				struct ndctl_dimm **dimms)
+{
+	int i, rc;
+	unsigned int handles[ND_MIRROR_MAX_WAY];
+	unsigned long long dpas[ND_MIRROR_MAX_WAY];
+
+	if (!bus || !spa || !dimms)
+		return -EINVAL;
+
+	memset(handles, 0, sizeof(handles));
+	memset(dpas, 0, sizeof(dpas));
+
+	rc = ndctl_bus_cmd_trans_spa(bus, spa, &handles[0], &dpas[0]);
+	if (rc)
+		return rc;
+
+	for (i = 0; i < ND_MIRROR_MAX_WAY && handles[i]; i++)
+		dimms[i] = ndctl_dimm_get_by_handle(bus, handles[i]);
+
+	return 0;
+}
+#endif /* HAVE_NDCTL_TRANS_SPA */
+
 static struct nd_cmd_vendor_tail *to_vendor_tail(struct ndctl_cmd *cmd)
 {
 	struct nd_cmd_vendor_tail *tail = (struct nd_cmd_vendor_tail *)
@@ -2314,6 +2412,9 @@ static int to_ioctl_cmd(int cmd, int dimm)
 #ifdef HAVE_NDCTL_CLEAR_ERROR
 		case ND_CMD_CLEAR_ERROR:     return ND_IOCTL_CLEAR_ERROR;
 #endif
+#ifdef HAVE_NDCTL_TRANS_SPA
+		case ND_CMD_TRANS_SPA:       return ND_CMD_TRANS_SPA;
+#endif
 		default:
 						       return 0;
 		};
diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym
index 0e59243..6846f20 100644
--- a/ndctl/lib/libndctl.sym
+++ b/ndctl/lib/libndctl.sym
@@ -36,6 +36,9 @@ global:
 	ndctl_bus_get_provider;
 	ndctl_bus_get_ctx;
 	ndctl_bus_wait_probe;
+	ndctl_bus_has_trans_spa;
+	ndctl_bus_cmd_trans_spa;
+	ndctl_dimms_get_by_spa;
 	ndctl_dimm_get_first;
 	ndctl_dimm_get_next;
 	ndctl_dimm_get_handle;
diff --git a/ndctl/libndctl.h.in b/ndctl/libndctl.h.in
index 200c5cf..3a6256b 100644
--- a/ndctl/libndctl.h.in
+++ b/ndctl/libndctl.h.in
@@ -347,6 +347,29 @@ static inline unsigned int ndctl_cmd_smart_threshold_get_spares(
 }
 #endif
 
+#if HAVE_NDCTL_TRANS_SPA == 1
+int ndctl_bus_has_trans_spa(struct ndctl_bus *bus);
+int ndctl_bus_cmd_trans_spa(struct ndctl_bus *bus,
+	unsigned long long addr, unsigned int *handles, unsigned long long *dpas);
+int ndctl_dimms_get_by_spa(struct ndctl_bus *bus,
+	unsigned long long spa, struct ndctl_dimm **dimms);
+#else
+static inline int ndctl_bus_has_trans_spa(struct ndctl_bus *bus)
+{
+	return 0;
+}
+static inline int ndctl_bus_cmd_trans_spa(struct ndctl_bus *bus,
+	unsigned long long addr, unsigned int *handles, unsigned long long *dpas)
+{
+	return 0;
+}
+static inline int ndctl_dimms_get_by_spa(struct ndctl_bus *bus,
+	unsigned long long spa, struct ndctl_dimm **dimms)
+{
+	return 0;
+}
+#endif
+
 struct ndctl_cmd *ndctl_dimm_cmd_new_vendor_specific(struct ndctl_dimm *dimm,
 		unsigned int opcode, size_t input_size, size_t output_size);
 ssize_t ndctl_cmd_vendor_set_input(struct ndctl_cmd *cmd, void *buf,
diff --git a/ndctl/ndctl.h b/ndctl/ndctl.h
index d70b97d..add0d58 100644
--- a/ndctl/ndctl.h
+++ b/ndctl/ndctl.h
@@ -35,6 +35,9 @@ struct nd_cmd_smart {
 #define ND_SMART_CRITICAL_HEALTH	(1 << 1)
 #define ND_SMART_FATAL_HEALTH		(1 << 2)
 
+#define ND_MIRROR_MAX_WAY 4 /* XXX: assume max mirroring way */
+#define ND_TRANS_SPA_STATUS_INVALID_SPA  2
+
 struct nd_smart_payload {
 	__u32 flags;
 	__u8 reserved0[4];
@@ -190,6 +193,7 @@ enum {
 	ND_CMD_ARS_START = 2,
 	ND_CMD_ARS_STATUS = 3,
 	ND_CMD_CLEAR_ERROR = 4,
+	ND_CMD_TRANS_SPA = 5,
 
 	/* per-dimm commands */
 	ND_CMD_SMART = 1,
@@ -217,6 +221,7 @@ static __inline__ const char *nvdimm_bus_cmd_name(unsigned cmd)
 		[ND_CMD_ARS_START] = "ars_start",
 		[ND_CMD_ARS_STATUS] = "ars_status",
 		[ND_CMD_CLEAR_ERROR] = "clear_error",
+		[ND_CMD_TRANS_SPA] = "trans_spa",
 		[ND_CMD_CALL] = "cmd_call",
 	};
 
@@ -280,6 +285,9 @@ static __inline__ const char *nvdimm_cmd_name(unsigned cmd)
 #define ND_IOCTL_CLEAR_ERROR		_IOWR(ND_IOCTL, ND_CMD_CLEAR_ERROR,\
 					struct nd_cmd_clear_error)
 
+#define ND_IOCTL_TRANS_SPA 		_IOWR(ND_IOCTL, ND_CMD_TRANS_SPA,\
+					struct nd_cmd_trans_spa)
+
 #define ND_DEVICE_DIMM 1            /* nd_dimm: container for "config data" */
 #define ND_DEVICE_REGION_PMEM 2     /* nd_region: (parent of PMEM namespaces) */
 #define ND_DEVICE_REGION_BLK 3      /* nd_region: (parent of BLK namespaces) */



_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

  parent reply	other threads:[~2017-08-04  9:10 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-08-04  9:02 [RFC/Patch 0/5] ndctl list show broken nvdimm info Yasunori Goto
2017-08-04  9:06 ` [RFC/Patch 1/5] Remove old enum definition of "Translate Spa" Yasunori Goto
2017-08-04 23:09   ` Dan Williams
2017-08-07  0:03     ` Yasunori Goto
2017-08-04  9:08 ` [RFC/Patch 2/5] Support Translate SPA for NVDIMM Root Device Yasunori Goto
2017-08-04 23:30   ` Dan Williams
2017-08-04  9:10 ` [RFC/Patch 3/5] nfit_test supports Translate SPA Yasunori Goto
2017-08-04  9:12 ` Yasunori Goto [this message]
2017-08-05  0:03   ` [RFC/Patch 4/5] libndctl Make interfaces to use " Dan Williams
2017-08-07  0:08     ` Yasunori Goto
2017-08-04  9:13 ` [RFC/Patch 5/5] ndctl: show dimm's name which has badblock by ndctl list command Yasunori Goto

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=20170804181223.27CC.E1E9C6FF@jp.fujitsu.com \
    --to=y-goto@jp.fujitsu.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