* [ndctl PATCH 00/16] ndctl: update SMART support for NVDIMM_FAMILY_INTEL
@ 2017-12-01 23:24 Dan Williams
2017-12-01 23:24 ` [ndctl PATCH 01/17] libndctl: rename dimm dsm_mask to cmd_mask Dan Williams
` (17 more replies)
0 siblings, 18 replies; 19+ messages in thread
From: Dan Williams @ 2017-12-01 23:24 UTC (permalink / raw)
To: linux-nvdimm; +Cc: Lijun Pan
The v1.6 release of the NVDIMM_FAMILY_INTEL DSM specification [1]
updates the format of the 'SMART Threshold Command' payload and
introduces the 'SMART Set Threshold Command'. Given that the new SMART
Threshold format is broken with respect to the initial / generic
ND_IOCTL_SMART_THRESHOLD format the generic SMART commands are now
deprecated. The NVDIMM_FAMILY_INTEL SMART support is updated to use
the ND_IOCTL_CALL path similar to how libndctl abstracts the per vendor
differences of the NVDIMM_FAMILY_{HPE1,MSFT} SMART implementations.
Included in this overhaul is better infrastructure for supporting the
rest of the v1.6 DSMs that need to go through the ND_IOCTL_CALL
interface.
Note, the v1.6 specification also includes a 'SMART Error Injection'
facility, but that enabling is deferred for a later update and will be
integrated with the 'ndctl inject-error' command.
[1]: http://pmem.io/documents/NVDIMM_DSM_Interface-V1.6.pdf
---
Dan Williams (16):
libndctl: rename dimm dsm_mask to cmd_mask
libndctl: add nfit_dsm_mask as a private dimm property
ndctl, smart: rename 'temperature' helpers to 'media_temperature'
ndctl, intel: switch to ND_CMD_CALL passthrough for SMART commands
ndctl: remove support for compiling against the kernel ndctl.h header
ndctl, test: emit smart field names
ndctl, smart: cleanup smart_cmd_op() macro
ndctl, test: reset all nfit_test data for each test/libndctl run
ndctl, region: cleanup error message
ndctl: support set smart alarm/threshold
ndctl: refactor 'smart_ops' into generic 'dimm_ops'
ndctl, debug: improve do_cmd output for ND_CMD_CALL
ndctl, list: teach the list command about the 'fsdax' and 'devdax' modes
ndctl, smart: move smart temperature parsing to a library routine
ndctl, test: trigger notifications
ndctl, test: listen for smart notifications
Documentation/ndctl/ndctl-list.txt | 2
configure.ac | 120 -------------
ndctl.spec.in | 4
ndctl/Makefile.am | 5 -
ndctl/check.c | 7 -
ndctl/inject-error.c | 6 -
ndctl/lib/Makefile.am | 22 +-
ndctl/lib/ars.c | 9 -
ndctl/lib/hpe1.c | 24 ++-
ndctl/lib/intel.c | 334 ++++++++++++++++++++++++++++++++++++
ndctl/lib/intel.h | 82 +++++++++
ndctl/lib/libndctl.c | 114 +++++++-----
ndctl/lib/libndctl.sym | 12 +
ndctl/lib/msft.c | 11 +
ndctl/lib/private.h | 80 ++++-----
ndctl/lib/smart.c | 206 ++++++----------------
ndctl/libndctl.h | 190 +++++---------------
ndctl/list.c | 9 +
ndctl/namespace.c | 9 -
ndctl/ndctl.h | 59 ------
ndctl/region.c | 2
ndctl/util/json-smart.c | 24 ---
test.h | 3
test/Makefile.am | 7 +
test/blk_namespaces.c | 9 -
test/core.c | 25 +++
test/daxdev-errors.c | 6 -
test/dpa-alloc.c | 9 -
test/dsm-fail.c | 6 -
test/libndctl.c | 118 ++++++++-----
test/multi-pmem.c | 7 -
test/parent-uuid.c | 2
test/pmem_namespaces.c | 7 -
test/smart-listen.c | 109 ++++++++++++
test/smart-notify.c | 220 ++++++++++++++++++++++++
util/json.c | 5 -
util/json.h | 8 -
37 files changed, 1130 insertions(+), 742 deletions(-)
create mode 100644 ndctl/lib/intel.c
create mode 100644 ndctl/lib/intel.h
rename ndctl/{libndctl.h.in => libndctl.h} (89%)
create mode 100644 test/smart-listen.c
create mode 100644 test/smart-notify.c
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply [flat|nested] 19+ messages in thread
* [ndctl PATCH 01/17] libndctl: rename dimm dsm_mask to cmd_mask
2017-12-01 23:24 [ndctl PATCH 00/16] ndctl: update SMART support for NVDIMM_FAMILY_INTEL Dan Williams
@ 2017-12-01 23:24 ` Dan Williams
2017-12-01 23:24 ` [ndctl PATCH 02/17] libndctl: add nfit_dsm_mask as a private dimm property Dan Williams
` (16 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Dan Williams @ 2017-12-01 23:24 UTC (permalink / raw)
To: linux-nvdimm
In preparation for converting the NVDIMM_FAMILY_INTEL support to use
ND_CMD_CALL for SMART and other operations, rename dsm_mask to cmd_mask.
"DSM" is ACPI specific and the Linux kernel ND_CMD number are generic
numbers that Linux understands for any NVDIMM bus, ACPI-defined or not.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
ndctl/lib/libndctl.c | 26 +++++++++++++-------------
ndctl/lib/private.h | 6 +++---
2 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c
index 44348463dc0a..bb47c9d1f522 100644
--- a/ndctl/lib/libndctl.c
+++ b/ndctl/lib/libndctl.c
@@ -622,7 +622,7 @@ static int device_parse(struct ndctl_ctx *ctx, struct ndctl_bus *bus,
return sysfs_device_parse(ctx, base_path, dev_name, parent, add_dev);
}
-static int to_dsm_index(const char *name, int dimm)
+static int to_cmd_index(const char *name, int dimm)
{
const char *(*cmd_name_fn)(unsigned cmd);
int i, end_cmd;
@@ -650,7 +650,7 @@ static int to_dsm_index(const char *name, int dimm)
static unsigned long parse_commands(char *commands, int dimm)
{
- unsigned long dsm_mask = 0;
+ unsigned long cmd_mask = 0;
char *start, *end;
start = commands;
@@ -658,12 +658,12 @@ static unsigned long parse_commands(char *commands, int dimm)
int cmd;
*end = '\0';
- cmd = to_dsm_index(start, dimm);
+ cmd = to_cmd_index(start, dimm);
if (cmd)
- dsm_mask |= 1 << cmd;
+ cmd_mask |= 1 << cmd;
start = end + 1;
}
- return dsm_mask;
+ return cmd_mask;
}
static void parse_nfit_mem_flags(struct ndctl_dimm *dimm, char *flags)
@@ -740,7 +740,7 @@ static void *add_bus(void *parent, int id, const char *ctl_base)
sprintf(path, "%s/device/commands", ctl_base);
if (sysfs_read_attr(ctx, path, buf) < 0)
goto err_read;
- bus->dsm_mask = parse_commands(buf, 0);
+ bus->cmd_mask = parse_commands(buf, 0);
sprintf(path, "%s/device/nfit/revision", ctl_base);
if (sysfs_read_attr(ctx, path, buf) < 0) {
@@ -1016,7 +1016,7 @@ NDCTL_EXPORT const char *ndctl_bus_get_cmd_name(struct ndctl_bus *bus, int cmd)
NDCTL_EXPORT int ndctl_bus_is_cmd_supported(struct ndctl_bus *bus,
int cmd)
{
- return !!(bus->dsm_mask & (1ULL << cmd));
+ return !!(bus->cmd_mask & (1ULL << cmd));
}
NDCTL_EXPORT unsigned int ndctl_bus_get_revision(struct ndctl_bus *bus)
@@ -1202,7 +1202,7 @@ static void *add_dimm(void *parent, int id, const char *dimm_base)
sprintf(path, "%s/commands", dimm_base);
if (sysfs_read_attr(ctx, path, buf) < 0)
goto err_read;
- dimm->dsm_mask = parse_commands(buf, 1);
+ dimm->cmd_mask = parse_commands(buf, 1);
dimm->dimm_buf = calloc(1, strlen(dimm_base) + 50);
if (!dimm->dimm_buf)
@@ -1231,7 +1231,7 @@ static void *add_dimm(void *parent, int id, const char *dimm_base)
dimm->subsystem_revision_id = -1;
dimm->manufacturing_date = -1;
dimm->manufacturing_location = -1;
- dimm->dsm_family = -1;
+ dimm->cmd_family = -1;
for (i = 0; i < formats; i++)
dimm->format[i] = -1;
@@ -1304,10 +1304,10 @@ static void *add_dimm(void *parent, int id, const char *dimm_base)
sprintf(path, "%s/nfit/family", dimm_base);
if (sysfs_read_attr(ctx, path, buf) == 0)
- dimm->dsm_family = strtoul(buf, NULL, 0);
- if (dimm->dsm_family == NVDIMM_FAMILY_HPE1)
+ dimm->cmd_family = strtoul(buf, NULL, 0);
+ if (dimm->cmd_family == NVDIMM_FAMILY_HPE1)
dimm->smart_ops = hpe1_smart_ops;
- if (dimm->dsm_family == NVDIMM_FAMILY_MSFT)
+ if (dimm->cmd_family == NVDIMM_FAMILY_MSFT)
dimm->smart_ops = msft_smart_ops;
dimm->formats = formats;
@@ -1524,7 +1524,7 @@ NDCTL_EXPORT int ndctl_dimm_failed_map(struct ndctl_dimm *dimm)
NDCTL_EXPORT int ndctl_dimm_is_cmd_supported(struct ndctl_dimm *dimm,
int cmd)
{
- return !!(dimm->dsm_mask & (1ULL << cmd));
+ return !!(dimm->cmd_mask & (1ULL << cmd));
}
NDCTL_EXPORT int ndctl_dimm_get_health_eventfd(struct ndctl_dimm *dimm)
diff --git a/ndctl/lib/private.h b/ndctl/lib/private.h
index 499316b3b19d..64bc5aee1134 100644
--- a/ndctl/lib/private.h
+++ b/ndctl/lib/private.h
@@ -75,8 +75,8 @@ struct ndctl_dimm {
unsigned short subsystem_revision_id;
unsigned short manufacturing_date;
unsigned char manufacturing_location;
- unsigned long dsm_family;
- unsigned long dsm_mask;
+ unsigned long cmd_family;
+ unsigned long cmd_mask;
char *unique_id;
char *dimm_path;
char *dimm_buf;
@@ -155,7 +155,7 @@ struct ndctl_bus {
size_t buf_len;
char *wait_probe_path;
char *scrub_path;
- unsigned long dsm_mask;
+ unsigned long cmd_mask;
unsigned long nfit_dsm_mask;
};
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [ndctl PATCH 02/17] libndctl: add nfit_dsm_mask as a private dimm property
2017-12-01 23:24 [ndctl PATCH 00/16] ndctl: update SMART support for NVDIMM_FAMILY_INTEL Dan Williams
2017-12-01 23:24 ` [ndctl PATCH 01/17] libndctl: rename dimm dsm_mask to cmd_mask Dan Williams
@ 2017-12-01 23:24 ` Dan Williams
2017-12-01 23:24 ` [ndctl PATCH 03/17] ndctl, smart: rename 'temperature' helpers to 'media_temperature' Dan Williams
` (15 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Dan Williams @ 2017-12-01 23:24 UTC (permalink / raw)
To: linux-nvdimm; +Cc: Lijun Pan
Validate vendor specific ACPI-defined command implementations against
the published dsm_mask.
Cc: Lijun Pan <Lijun.Pan@dell.com>
Cc: Jerry Hoemann <jerry.hoemann@hpe.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
ndctl/lib/hpe1.c | 12 ++++++++++++
ndctl/lib/libndctl.c | 5 +++++
ndctl/lib/msft.c | 5 +++++
ndctl/lib/private.h | 16 ++++++++++++++++
4 files changed, 38 insertions(+)
diff --git a/ndctl/lib/hpe1.c b/ndctl/lib/hpe1.c
index 45cb5cc6db73..addebe952ce6 100644
--- a/ndctl/lib/hpe1.c
+++ b/ndctl/lib/hpe1.c
@@ -36,6 +36,12 @@ static struct ndctl_cmd *hpe1_dimm_cmd_new_smart(struct ndctl_dimm *dimm)
return NULL;
}
+ if (test_dimm_dsm(dimm, NDN_HPE1_CMD_SMART)
+ == DIMM_DSM_UNSUPPORTED) {
+ dbg(ctx, "unsupported function\n");
+ return NULL;
+ }
+
size = sizeof(*cmd) + sizeof(struct ndn_pkg_hpe1);
cmd = calloc(1, size);
if (!cmd)
@@ -214,6 +220,12 @@ static struct ndctl_cmd *hpe1_dimm_cmd_new_smart_threshold(struct ndctl_dimm *di
return NULL;
}
+ if (test_dimm_dsm(dimm, NDN_HPE1_CMD_SMART_THRESHOLD)
+ == DIMM_DSM_UNSUPPORTED) {
+ dbg(ctx, "unsupported function\n");
+ return NULL;
+ }
+
size = sizeof(*cmd) + sizeof(struct ndn_pkg_hpe1);
cmd = calloc(1, size);
if (!cmd)
diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c
index bb47c9d1f522..0473b482ad23 100644
--- a/ndctl/lib/libndctl.c
+++ b/ndctl/lib/libndctl.c
@@ -1232,6 +1232,7 @@ static void *add_dimm(void *parent, int id, const char *dimm_base)
dimm->manufacturing_date = -1;
dimm->manufacturing_location = -1;
dimm->cmd_family = -1;
+ dimm->nfit_dsm_mask = ULONG_MAX;
for (i = 0; i < formats; i++)
dimm->format[i] = -1;
@@ -1310,6 +1311,10 @@ static void *add_dimm(void *parent, int id, const char *dimm_base)
if (dimm->cmd_family == NVDIMM_FAMILY_MSFT)
dimm->smart_ops = msft_smart_ops;
+ sprintf(path, "%s/nfit/dsm_mask", dimm_base);
+ if (sysfs_read_attr(ctx, path, buf) == 0)
+ dimm->nfit_dsm_mask = strtoul(buf, NULL, 0);
+
dimm->formats = formats;
sprintf(path, "%s/nfit/format", dimm_base);
if (sysfs_read_attr(ctx, path, buf) == 0)
diff --git a/ndctl/lib/msft.c b/ndctl/lib/msft.c
index 8c226f5602f1..1c4c8913714f 100644
--- a/ndctl/lib/msft.c
+++ b/ndctl/lib/msft.c
@@ -35,6 +35,11 @@ static struct ndctl_cmd *msft_dimm_cmd_new_smart(struct ndctl_dimm *dimm)
return NULL;
}
+ if (test_dimm_dsm(dimm, NDN_MSFT_CMD_SMART) == DIMM_DSM_UNSUPPORTED) {
+ dbg(ctx, "unsupported function\n");
+ return NULL;
+ }
+
size = sizeof(*cmd) + sizeof(struct ndn_pkg_msft);
cmd = calloc(1, size);
if (!cmd)
diff --git a/ndctl/lib/private.h b/ndctl/lib/private.h
index 64bc5aee1134..685d65d89a06 100644
--- a/ndctl/lib/private.h
+++ b/ndctl/lib/private.h
@@ -77,6 +77,7 @@ struct ndctl_dimm {
unsigned char manufacturing_location;
unsigned long cmd_family;
unsigned long cmd_mask;
+ unsigned long nfit_dsm_mask;
char *unique_id;
char *dimm_path;
char *dimm_buf;
@@ -102,6 +103,21 @@ struct ndctl_dimm {
int format[0];
};
+enum dsm_support {
+ DIMM_DSM_UNSUPPORTED, /* don't attempt command */
+ DIMM_DSM_SUPPORTED, /* good to go */
+ DIMM_DSM_UNKNOWN, /* try ND_CMD_CALL on older kernels */
+};
+
+static inline enum dsm_support test_dimm_dsm(struct ndctl_dimm *dimm, int fn)
+{
+ if (dimm->nfit_dsm_mask == ULONG_MAX) {
+ return DIMM_DSM_UNKNOWN;
+ } else if (dimm->nfit_dsm_mask & (1 << fn))
+ return DIMM_DSM_SUPPORTED;
+ return DIMM_DSM_UNSUPPORTED;
+}
+
void region_flag_refresh(struct ndctl_region *region);
/**
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [ndctl PATCH 03/17] ndctl, smart: rename 'temperature' helpers to 'media_temperature'
2017-12-01 23:24 [ndctl PATCH 00/16] ndctl: update SMART support for NVDIMM_FAMILY_INTEL Dan Williams
2017-12-01 23:24 ` [ndctl PATCH 01/17] libndctl: rename dimm dsm_mask to cmd_mask Dan Williams
2017-12-01 23:24 ` [ndctl PATCH 02/17] libndctl: add nfit_dsm_mask as a private dimm property Dan Williams
@ 2017-12-01 23:24 ` Dan Williams
2017-12-01 23:24 ` [ndctl PATCH 04/17] ndctl, intel: switch to ND_CMD_CALL passthrough for SMART commands Dan Williams
` (14 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Dan Williams @ 2017-12-01 23:24 UTC (permalink / raw)
To: linux-nvdimm
In preparation for adding controller temperature support rename the
current ambiguous 'temperature' to 'media_temperature'.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
ndctl/lib/hpe1.c | 10 ++++++----
ndctl/lib/libndctl.sym | 2 ++
ndctl/lib/msft.c | 4 ++--
ndctl/lib/private.h | 4 ++--
ndctl/lib/smart.c | 34 ++++++++++++++++++++++++++++++----
ndctl/libndctl.h.in | 17 +++++++++++++++++
6 files changed, 59 insertions(+), 12 deletions(-)
diff --git a/ndctl/lib/hpe1.c b/ndctl/lib/hpe1.c
index addebe952ce6..81f60ab27a07 100644
--- a/ndctl/lib/hpe1.c
+++ b/ndctl/lib/hpe1.c
@@ -134,7 +134,7 @@ static unsigned int hpe1_cmd_smart_get_health(struct ndctl_cmd *cmd)
return health;
}
-static unsigned int hpe1_cmd_smart_get_temperature(struct ndctl_cmd *cmd)
+static unsigned int hpe1_cmd_smart_get_media_temperature(struct ndctl_cmd *cmd)
{
if (hpe1_smart_valid(cmd) < 0)
return UINT_MAX;
@@ -279,7 +279,8 @@ static unsigned int hpe1_cmd_smart_threshold_get_alarm_control(struct ndctl_cmd
return flags;
}
-static unsigned int hpe1_cmd_smart_threshold_get_temperature(struct ndctl_cmd *cmd)
+static unsigned int hpe1_cmd_smart_threshold_get_media_temperature(
+ struct ndctl_cmd *cmd)
{
if (hpe1_smart_threshold_valid(cmd) < 0)
return UINT_MAX;
@@ -299,7 +300,7 @@ struct ndctl_smart_ops * const hpe1_smart_ops = &(struct ndctl_smart_ops) {
.new_smart = hpe1_dimm_cmd_new_smart,
.smart_get_flags = hpe1_cmd_smart_get_flags,
.smart_get_health = hpe1_cmd_smart_get_health,
- .smart_get_temperature = hpe1_cmd_smart_get_temperature,
+ .smart_get_media_temperature = hpe1_cmd_smart_get_media_temperature,
.smart_get_spares = hpe1_cmd_smart_get_spares,
.smart_get_alarm_flags = hpe1_cmd_smart_get_alarm_flags,
.smart_get_life_used = hpe1_cmd_smart_get_life_used,
@@ -308,6 +309,7 @@ struct ndctl_smart_ops * const hpe1_smart_ops = &(struct ndctl_smart_ops) {
.smart_get_vendor_data = hpe1_cmd_smart_get_vendor_data,
.new_smart_threshold = hpe1_dimm_cmd_new_smart_threshold,
.smart_threshold_get_alarm_control = hpe1_cmd_smart_threshold_get_alarm_control,
- .smart_threshold_get_temperature = hpe1_cmd_smart_threshold_get_temperature,
+ .smart_threshold_get_media_temperature =
+ hpe1_cmd_smart_threshold_get_media_temperature,
.smart_threshold_get_spares = hpe1_cmd_smart_threshold_get_spares,
};
diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym
index 30480074d2ef..b3fab6232df6 100644
--- a/ndctl/lib/libndctl.sym
+++ b/ndctl/lib/libndctl.sym
@@ -310,4 +310,6 @@ global:
ndctl_namespace_injection_get_next_bb;
ndctl_bb_get_block;
ndctl_bb_get_count;
+ ndctl_cmd_smart_get_media_temperature;
+ ndctl_cmd_smart_threshold_get_media_temperature;
} LIBNDCTL_13;
diff --git a/ndctl/lib/msft.c b/ndctl/lib/msft.c
index 1c4c8913714f..d61c065e752d 100644
--- a/ndctl/lib/msft.c
+++ b/ndctl/lib/msft.c
@@ -120,7 +120,7 @@ static unsigned int msft_cmd_smart_get_health(struct ndctl_cmd *cmd)
return health;
}
-static unsigned int msft_cmd_smart_get_temperature(struct ndctl_cmd *cmd)
+static unsigned int msft_cmd_smart_get_media_temperature(struct ndctl_cmd *cmd)
{
if (msft_smart_valid(cmd) < 0)
return UINT_MAX;
@@ -140,6 +140,6 @@ struct ndctl_smart_ops * const msft_smart_ops = &(struct ndctl_smart_ops) {
.new_smart = msft_dimm_cmd_new_smart,
.smart_get_flags = msft_cmd_smart_get_flags,
.smart_get_health = msft_cmd_smart_get_health,
- .smart_get_temperature = msft_cmd_smart_get_temperature,
+ .smart_get_media_temperature = msft_cmd_smart_get_media_temperature,
.smart_get_life_used = msft_cmd_smart_get_life_used,
};
diff --git a/ndctl/lib/private.h b/ndctl/lib/private.h
index 685d65d89a06..c2ce519ebad2 100644
--- a/ndctl/lib/private.h
+++ b/ndctl/lib/private.h
@@ -288,7 +288,7 @@ struct ndctl_smart_ops {
struct ndctl_cmd *(*new_smart)(struct ndctl_dimm *);
unsigned int (*smart_get_flags)(struct ndctl_cmd *);
unsigned int (*smart_get_health)(struct ndctl_cmd *);
- unsigned int (*smart_get_temperature)(struct ndctl_cmd *);
+ unsigned int (*smart_get_media_temperature)(struct ndctl_cmd *);
unsigned int (*smart_get_spares)(struct ndctl_cmd *);
unsigned int (*smart_get_alarm_flags)(struct ndctl_cmd *);
unsigned int (*smart_get_life_used)(struct ndctl_cmd *);
@@ -298,7 +298,7 @@ struct ndctl_smart_ops {
unsigned char *(*smart_get_vendor_data)(struct ndctl_cmd *);
struct ndctl_cmd *(*new_smart_threshold)(struct ndctl_dimm *);
unsigned int (*smart_threshold_get_alarm_control)(struct ndctl_cmd *);
- unsigned int (*smart_threshold_get_temperature)(struct ndctl_cmd *);
+ unsigned int (*smart_threshold_get_media_temperature)(struct ndctl_cmd *);
unsigned int (*smart_threshold_get_spares)(struct ndctl_cmd *);
};
diff --git a/ndctl/lib/smart.c b/ndctl/lib/smart.c
index 1821af2289d3..d30288a1486a 100644
--- a/ndctl/lib/smart.c
+++ b/ndctl/lib/smart.c
@@ -53,7 +53,8 @@ NDCTL_EXPORT rettype name(struct ndctl_cmd *cmd) \
smart_cmd_op(ndctl_cmd_smart_get_flags, smart_get_flags, unsigned int, 0)
smart_cmd_op(ndctl_cmd_smart_get_health, smart_get_health, unsigned int, 0)
-smart_cmd_op(ndctl_cmd_smart_get_temperature, smart_get_temperature, unsigned int, 0)
+smart_cmd_op(ndctl_cmd_smart_get_media_temperature, smart_get_media_temperature,
+ unsigned int, 0)
smart_cmd_op(ndctl_cmd_smart_get_spares, smart_get_spares, unsigned int, 0)
smart_cmd_op(ndctl_cmd_smart_get_alarm_flags, smart_get_alarm_flags, unsigned int, 0)
smart_cmd_op(ndctl_cmd_smart_get_life_used, smart_get_life_used, unsigned int, 0)
@@ -62,9 +63,21 @@ smart_cmd_op(ndctl_cmd_smart_get_shutdown_count, smart_get_shutdown_count, unsig
smart_cmd_op(ndctl_cmd_smart_get_vendor_size, smart_get_vendor_size, unsigned int, 0)
smart_cmd_op(ndctl_cmd_smart_get_vendor_data, smart_get_vendor_data, unsigned char *, NULL)
smart_cmd_op(ndctl_cmd_smart_threshold_get_alarm_control, smart_threshold_get_alarm_control, unsigned int, 0)
-smart_cmd_op(ndctl_cmd_smart_threshold_get_temperature, smart_threshold_get_temperature, unsigned int, 0)
+smart_cmd_op(ndctl_cmd_smart_threshold_get_media_temperature,
+ smart_threshold_get_media_temperature, unsigned int, 0)
smart_cmd_op(ndctl_cmd_smart_threshold_get_spares, smart_threshold_get_spares, unsigned int, 0)
+NDCTL_EXPORT unsigned int ndctl_cmd_smart_get_temperature(struct ndctl_cmd *cmd)
+{
+ return ndctl_cmd_smart_get_media_temperature(cmd);
+}
+
+NDCTL_EXPORT unsigned int ndctl_cmd_smart_threshold_get_temperature(
+ struct ndctl_cmd *cmd)
+{
+ return ndctl_cmd_smart_threshold_get_media_temperature(cmd);
+}
+
/*
* The following intel_dimm_*() and intel_smart_*() functions implement
* the ndctl_smart_ops for the Intel DSM family (NVDIMM_FAMILY_INTEL):
@@ -126,6 +139,12 @@ intel_smart_get_field(cmd, shutdown_state)
intel_smart_get_field(cmd, shutdown_count)
intel_smart_get_field(cmd, vendor_size)
+static unsigned int intel_cmd_smart_get_media_temperature(
+ struct ndctl_cmd *cmd)
+{
+ return intel_cmd_smart_get_temperature(cmd);
+}
+
static unsigned char *intel_cmd_smart_get_vendor_data(struct ndctl_cmd *cmd)
{
struct nd_smart_payload *smart_data;
@@ -159,6 +178,12 @@ intel_smart_threshold_get_field(cmd, alarm_control)
intel_smart_threshold_get_field(cmd, temperature)
intel_smart_threshold_get_field(cmd, spares)
+static unsigned int intel_cmd_smart_threshold_get_media_temperature(
+ struct ndctl_cmd *cmd)
+{
+ return intel_cmd_smart_threshold_get_temperature(cmd);
+}
+
static struct ndctl_cmd *intel_dimm_cmd_new_smart_threshold(
struct ndctl_dimm *dimm)
{
@@ -193,7 +218,7 @@ struct ndctl_smart_ops * const intel_smart_ops = &(struct ndctl_smart_ops) {
.new_smart = intel_dimm_cmd_new_smart,
.smart_get_flags = intel_cmd_smart_get_flags,
.smart_get_health = intel_cmd_smart_get_health,
- .smart_get_temperature = intel_cmd_smart_get_temperature,
+ .smart_get_media_temperature = intel_cmd_smart_get_media_temperature,
.smart_get_spares = intel_cmd_smart_get_spares,
.smart_get_alarm_flags = intel_cmd_smart_get_alarm_flags,
.smart_get_life_used = intel_cmd_smart_get_life_used,
@@ -203,6 +228,7 @@ struct ndctl_smart_ops * const intel_smart_ops = &(struct ndctl_smart_ops) {
.smart_get_vendor_data = intel_cmd_smart_get_vendor_data,
.new_smart_threshold = intel_dimm_cmd_new_smart_threshold,
.smart_threshold_get_alarm_control = intel_cmd_smart_threshold_get_alarm_control,
- .smart_threshold_get_temperature = intel_cmd_smart_threshold_get_temperature,
+ .smart_threshold_get_media_temperature
+ = intel_cmd_smart_threshold_get_media_temperature,
.smart_threshold_get_spares = intel_cmd_smart_threshold_get_spares,
};
diff --git a/ndctl/libndctl.h.in b/ndctl/libndctl.h.in
index fb77d243a893..298adff476c7 100644
--- a/ndctl/libndctl.h.in
+++ b/ndctl/libndctl.h.in
@@ -275,12 +275,18 @@ static inline unsigned long long ndctl_cmd_clear_error_get_cleared(
}
#endif
+/*
+ * Note: ndctl_cmd_smart_get_temperature is an alias for
+ * ndctl_cmd_smart_get_temperature
+ */
+
#define HAS_SMART HAVE_NDCTL_SMART
#if HAS_SMART == 1
struct ndctl_cmd *ndctl_dimm_cmd_new_smart(struct ndctl_dimm *dimm);
unsigned int ndctl_cmd_smart_get_flags(struct ndctl_cmd *cmd);
unsigned int ndctl_cmd_smart_get_health(struct ndctl_cmd *cmd);
unsigned int ndctl_cmd_smart_get_temperature(struct ndctl_cmd *cmd);
+unsigned int ndctl_cmd_smart_get_media_temperature(struct ndctl_cmd *cmd);
unsigned int ndctl_cmd_smart_get_spares(struct ndctl_cmd *cmd);
unsigned int ndctl_cmd_smart_get_alarm_flags(struct ndctl_cmd *cmd);
unsigned int ndctl_cmd_smart_get_life_used(struct ndctl_cmd *cmd);
@@ -291,6 +297,7 @@ unsigned char *ndctl_cmd_smart_get_vendor_data(struct ndctl_cmd *cmd);
struct ndctl_cmd *ndctl_dimm_cmd_new_smart_threshold(struct ndctl_dimm *dimm);
unsigned int ndctl_cmd_smart_threshold_get_alarm_control(struct ndctl_cmd *cmd);
unsigned int ndctl_cmd_smart_threshold_get_temperature(struct ndctl_cmd *cmd);
+unsigned int ndctl_cmd_smart_threshold_get_media_temperature(struct ndctl_cmd *cmd);
unsigned int ndctl_cmd_smart_threshold_get_spares(struct ndctl_cmd *cmd);
#else
static inline struct ndctl_cmd *ndctl_dimm_cmd_new_smart(struct ndctl_dimm *dimm)
@@ -309,6 +316,11 @@ static inline unsigned int ndctl_cmd_smart_get_temperature(struct ndctl_cmd *cmd
{
return 0;
}
+static inline unsigned int ndctl_cmd_smart_get_media_temperature(
+ struct ndctl_cmd *cmd)
+{
+ return 0;
+}
static inline unsigned int ndctl_cmd_smart_get_spares(struct ndctl_cmd *cmd)
{
return 0;
@@ -352,6 +364,11 @@ static inline unsigned int ndctl_cmd_smart_threshold_get_temperature(
{
return 0;
}
+static inline unsigned int ndctl_cmd_smart_threshold_get_media_temperature(
+ struct ndctl_cmd *cmd)
+{
+ return 0;
+}
static inline unsigned int ndctl_cmd_smart_threshold_get_spares(
struct ndctl_cmd *cmd)
{
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [ndctl PATCH 04/17] ndctl, intel: switch to ND_CMD_CALL passthrough for SMART commands
2017-12-01 23:24 [ndctl PATCH 00/16] ndctl: update SMART support for NVDIMM_FAMILY_INTEL Dan Williams
` (2 preceding siblings ...)
2017-12-01 23:24 ` [ndctl PATCH 03/17] ndctl, smart: rename 'temperature' helpers to 'media_temperature' Dan Williams
@ 2017-12-01 23:24 ` Dan Williams
2017-12-01 23:24 ` [ndctl PATCH 05/17] ndctl: remove support for compiling against the kernel ndctl.h header Dan Williams
` (13 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Dan Williams @ 2017-12-01 23:24 UTC (permalink / raw)
To: linux-nvdimm
The kernel's ND_IOCTL_SMART_THRESHOLD command is based on a payload
definition that has become broken / out-of-sync with recent versions of
the NVDIMM_FAMILY_INTEL definition. Deprecate the use of the
ND_IOCTL_SMART_THRESHOLD command in favor of the ND_CMD_CALL approach
taken by NVDIMM_FAMILY_{HPE,MSFT}, and update to the new payload format.
In a couple years, when the new scheme is widely deployed, the
ND_IOCTL_SMART_THRESHOLD definition can be removed.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
ndctl/lib/Makefile.am | 1
ndctl/lib/intel.c | 230 +++++++++++++++++++++++++++++++++++++++++++++++++
ndctl/lib/intel.h | 72 +++++++++++++++
ndctl/lib/libndctl.c | 3 -
ndctl/lib/private.h | 4 -
ndctl/lib/smart.c | 155 ---------------------------------
6 files changed, 307 insertions(+), 158 deletions(-)
create mode 100644 ndctl/lib/intel.c
create mode 100644 ndctl/lib/intel.h
diff --git a/ndctl/lib/Makefile.am b/ndctl/lib/Makefile.am
index 3a6024ead6fb..3a51e799afa1 100644
--- a/ndctl/lib/Makefile.am
+++ b/ndctl/lib/Makefile.am
@@ -33,6 +33,7 @@ endif
if ENABLE_SMART
libndctl_la_SOURCES += smart.c
+libndctl_la_SOURCES += intel.c
libndctl_la_SOURCES += hpe1.c
libndctl_la_SOURCES += msft.c
endif
diff --git a/ndctl/lib/intel.c b/ndctl/lib/intel.c
new file mode 100644
index 000000000000..5aad8c24f00c
--- /dev/null
+++ b/ndctl/lib/intel.c
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 2016-2017, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+ * more details.
+ */
+#include <stdlib.h>
+#include <limits.h>
+#include <util/log.h>
+#include <ndctl/libndctl.h>
+#include "private.h"
+
+static struct ndctl_cmd *alloc_intel_cmd(struct ndctl_dimm *dimm,
+ unsigned func, size_t in_size, size_t out_size)
+{
+ struct ndctl_ctx *ctx = ndctl_dimm_get_ctx(dimm);
+ struct ndctl_cmd *cmd;
+ size_t size;
+
+ if (!ndctl_dimm_is_cmd_supported(dimm, ND_CMD_CALL)) {
+ dbg(ctx, "unsupported cmd: %d\n", ND_CMD_CALL);
+ return NULL;
+ }
+
+ if (test_dimm_dsm(dimm, func) == DIMM_DSM_UNSUPPORTED) {
+ dbg(ctx, "unsupported function: %d\n", func);
+ return NULL;
+ }
+
+ size = sizeof(*cmd) + sizeof(struct nd_pkg_intel);
+ cmd = calloc(1, size);
+ if (!cmd)
+ return NULL;
+
+ cmd->dimm = dimm;
+ ndctl_cmd_ref(cmd);
+ cmd->type = ND_CMD_CALL;
+ cmd->size = size;
+ cmd->status = 1;
+
+ *(cmd->intel) = (struct nd_pkg_intel) {
+ .gen = {
+ .nd_family = NVDIMM_FAMILY_INTEL,
+ .nd_command = func,
+ .nd_size_in = in_size,
+ .nd_size_out = out_size,
+ },
+ };
+
+ return cmd;
+}
+
+static struct ndctl_cmd *intel_dimm_cmd_new_smart(struct ndctl_dimm *dimm)
+{
+ struct ndctl_cmd *cmd;
+
+ BUILD_ASSERT(sizeof(struct nd_intel_smart) == 132);
+
+ cmd = alloc_intel_cmd(dimm, ND_INTEL_SMART,
+ 0, sizeof(cmd->intel->smart));
+ if (!cmd)
+ return NULL;
+ cmd->firmware_status = &cmd->intel->smart.status;
+
+ return cmd;
+}
+
+static int intel_smart_valid(struct ndctl_cmd *cmd)
+{
+ struct nd_pkg_intel *pkg = cmd->intel;
+
+ if (cmd->type != ND_CMD_CALL || cmd->status != 0
+ || pkg->gen.nd_family != NVDIMM_FAMILY_INTEL
+ || pkg->gen.nd_command != ND_INTEL_SMART)
+ return cmd->status < 0 ? cmd->status : -EINVAL;
+ return 0;
+}
+
+#define intel_smart_get_field(cmd, field) \
+static unsigned int intel_cmd_smart_get_##field(struct ndctl_cmd *cmd) \
+{ \
+ if (intel_smart_valid(cmd) < 0) \
+ return UINT_MAX; \
+ return cmd->intel->smart.field; \
+}
+
+static unsigned int intel_cmd_smart_get_flags(struct ndctl_cmd *cmd)
+{
+ unsigned int flags = 0;
+ unsigned int intel_flags;
+
+ if (intel_smart_valid(cmd) < 0)
+ return 0;
+
+ /* translate intel specific flags to libndctl api smart flags */
+ intel_flags = cmd->intel->smart.flags;
+ if (intel_flags & ND_INTEL_SMART_HEALTH_VALID)
+ flags |= ND_SMART_HEALTH_VALID;
+ if (intel_flags & ND_INTEL_SMART_SPARES_VALID)
+ flags |= ND_SMART_SPARES_VALID;
+ if (intel_flags & ND_INTEL_SMART_USED_VALID)
+ flags |= ND_SMART_USED_VALID;
+ if (intel_flags & ND_INTEL_SMART_MTEMP_VALID)
+ flags |= ND_SMART_TEMP_VALID;
+ if (intel_flags & ND_INTEL_SMART_SHUTDOWN_COUNT_VALID)
+ flags |= ND_SMART_SHUTDOWN_COUNT_VALID;
+ if (intel_flags & ND_INTEL_SMART_ALARM_VALID)
+ flags |= ND_SMART_ALARM_VALID;
+ if (intel_flags & ND_INTEL_SMART_SHUTDOWN_VALID)
+ flags |= ND_SMART_SHUTDOWN_VALID;
+ if (intel_flags & ND_INTEL_SMART_VENDOR_VALID)
+ flags |= ND_SMART_VENDOR_VALID;
+ return flags;
+}
+
+static unsigned int intel_cmd_smart_get_health(struct ndctl_cmd *cmd)
+{
+ unsigned int health = 0;
+ unsigned int intel_health;
+
+ if (intel_smart_valid(cmd) < 0)
+ return 0;
+ intel_health = cmd->intel->smart.health;
+ if (intel_health & ND_INTEL_SMART_NON_CRITICAL_HEALTH)
+ health |= ND_SMART_NON_CRITICAL_HEALTH;
+ if (intel_health & ND_INTEL_SMART_CRITICAL_HEALTH)
+ health |= ND_SMART_CRITICAL_HEALTH;
+ if (intel_health & ND_INTEL_SMART_FATAL_HEALTH)
+ health |= ND_SMART_FATAL_HEALTH;
+ return health;
+}
+
+intel_smart_get_field(cmd, media_temperature)
+intel_smart_get_field(cmd, spares)
+intel_smart_get_field(cmd, alarm_flags)
+intel_smart_get_field(cmd, life_used)
+intel_smart_get_field(cmd, shutdown_state)
+intel_smart_get_field(cmd, shutdown_count)
+intel_smart_get_field(cmd, vendor_size)
+
+static unsigned char *intel_cmd_smart_get_vendor_data(struct ndctl_cmd *cmd)
+{
+ if (intel_smart_valid(cmd) < 0)
+ return NULL;
+ return cmd->intel->smart.vendor_data;
+}
+
+static int intel_smart_threshold_valid(struct ndctl_cmd *cmd)
+{
+ struct nd_pkg_intel *pkg = cmd->intel;
+
+ if (cmd->type != ND_CMD_CALL || cmd->status != 0
+ || pkg->gen.nd_family != NVDIMM_FAMILY_INTEL
+ || pkg->gen.nd_command != ND_INTEL_SMART_THRESHOLD)
+ return cmd->status < 0 ? cmd->status : -EINVAL;
+ return 0;
+}
+
+#define intel_smart_threshold_get_field(cmd, field) \
+static unsigned int intel_cmd_smart_threshold_get_##field( \
+ struct ndctl_cmd *cmd) \
+{ \
+ if (intel_smart_threshold_valid(cmd) < 0) \
+ return UINT_MAX; \
+ return cmd->intel->thresh.field; \
+}
+
+static unsigned int intel_cmd_smart_threshold_get_alarm_control(
+ struct ndctl_cmd *cmd)
+{
+ struct nd_intel_smart_threshold *thresh;
+ unsigned int flags = 0;
+
+ if (intel_smart_threshold_valid(cmd) < 0)
+ return 0;
+
+ thresh = &cmd->intel->thresh;
+ if (thresh->alarm_control & ND_INTEL_SMART_SPARE_TRIP)
+ flags |= ND_SMART_SPARE_TRIP;
+ if (thresh->alarm_control & ND_INTEL_SMART_TEMP_TRIP)
+ flags |= ND_SMART_TEMP_TRIP;
+ if (thresh->alarm_control & ND_INTEL_SMART_CTEMP_TRIP)
+ flags |= ND_SMART_CTEMP_TRIP;
+
+ return flags;
+}
+
+intel_smart_threshold_get_field(cmd, media_temperature)
+intel_smart_threshold_get_field(cmd, spares)
+
+static struct ndctl_cmd *intel_dimm_cmd_new_smart_threshold(
+ struct ndctl_dimm *dimm)
+{
+ struct ndctl_cmd *cmd;
+
+ BUILD_ASSERT(sizeof(struct nd_intel_smart_threshold) == 12);
+
+ cmd = alloc_intel_cmd(dimm, ND_INTEL_SMART_THRESHOLD,
+ 0, sizeof(cmd->intel->thresh));
+ if (!cmd)
+ return NULL;
+ cmd->firmware_status = &cmd->intel->thresh.status;
+
+ return cmd;
+}
+
+struct ndctl_smart_ops * const intel_smart_ops = &(struct ndctl_smart_ops) {
+ .new_smart = intel_dimm_cmd_new_smart,
+ .smart_get_flags = intel_cmd_smart_get_flags,
+ .smart_get_health = intel_cmd_smart_get_health,
+ .smart_get_media_temperature = intel_cmd_smart_get_media_temperature,
+ .smart_get_spares = intel_cmd_smart_get_spares,
+ .smart_get_alarm_flags = intel_cmd_smart_get_alarm_flags,
+ .smart_get_life_used = intel_cmd_smart_get_life_used,
+ .smart_get_shutdown_state = intel_cmd_smart_get_shutdown_state,
+ .smart_get_shutdown_count = intel_cmd_smart_get_shutdown_count,
+ .smart_get_vendor_size = intel_cmd_smart_get_vendor_size,
+ .smart_get_vendor_data = intel_cmd_smart_get_vendor_data,
+ .new_smart_threshold = intel_dimm_cmd_new_smart_threshold,
+ .smart_threshold_get_alarm_control = intel_cmd_smart_threshold_get_alarm_control,
+ .smart_threshold_get_media_temperature
+ = intel_cmd_smart_threshold_get_media_temperature,
+ .smart_threshold_get_spares = intel_cmd_smart_threshold_get_spares,
+};
diff --git a/ndctl/lib/intel.h b/ndctl/lib/intel.h
new file mode 100644
index 000000000000..8cecc02f9ae6
--- /dev/null
+++ b/ndctl/lib/intel.h
@@ -0,0 +1,72 @@
+/* SPDX-License-Identifier: LGPL-2.1 */
+/* Copyright (c) 2017, Intel Corporation. All rights reserved. */
+
+#ifndef __INTEL_H__
+#define __INTEL_H__
+#define ND_INTEL_SMART 1
+#define ND_INTEL_SMART_THRESHOLD 2
+
+#define ND_INTEL_SMART_HEALTH_VALID (1 << 0)
+#define ND_INTEL_SMART_SPARES_VALID (1 << 1)
+#define ND_INTEL_SMART_USED_VALID (1 << 2)
+#define ND_INTEL_SMART_MTEMP_VALID (1 << 3)
+#define ND_INTEL_SMART_CTEMP_VALID (1 << 4)
+#define ND_INTEL_SMART_SHUTDOWN_COUNT_VALID (1 << 5)
+#define ND_INTEL_SMART_AIT_STATUS_VALID (1 << 6)
+#define ND_INTEL_SMART_PTEMP_VALID (1 << 7)
+#define ND_INTEL_SMART_ALARM_VALID (1 << 9)
+#define ND_INTEL_SMART_SHUTDOWN_VALID (1 << 10)
+#define ND_INTEL_SMART_VENDOR_VALID (1 << 11)
+#define ND_INTEL_SMART_SPARE_TRIP (1 << 0)
+#define ND_INTEL_SMART_TEMP_TRIP (1 << 1)
+#define ND_INTEL_SMART_CTEMP_TRIP (1 << 2)
+#define ND_INTEL_SMART_NON_CRITICAL_HEALTH (1 << 0)
+#define ND_INTEL_SMART_CRITICAL_HEALTH (1 << 1)
+#define ND_INTEL_SMART_FATAL_HEALTH (1 << 2)
+
+struct nd_intel_smart {
+ __u32 status;
+ union {
+ struct {
+ __u32 flags;
+ __u8 reserved0[4];
+ __u8 health;
+ __u8 spares;
+ __u8 life_used;
+ __u8 alarm_flags;
+ __u16 media_temperature;
+ __u16 ctrl_temperature;
+ __u32 shutdown_count;
+ __u8 ait_status;
+ __u16 pmic_temperature;
+ __u8 reserved1[8];
+ __u8 shutdown_state;
+ __u32 vendor_size;
+ __u8 vendor_data[92];
+ } __attribute__((packed));
+ __u8 data[128];
+ };
+} __attribute__((packed));
+
+struct nd_intel_smart_threshold {
+ __u32 status;
+ union {
+ struct {
+ __u16 alarm_control;
+ __u8 spares;
+ __u16 media_temperature;
+ __u16 ctrl_temperature;
+ __u8 reserved[1];
+ } __attribute__((packed));
+ __u8 data[8];
+ };
+} __attribute__((packed));
+
+struct nd_pkg_intel {
+ struct nd_cmd_pkg gen;
+ union {
+ struct nd_intel_smart smart;
+ struct nd_intel_smart_threshold thresh;
+ };
+};
+#endif /* __INTEL_H__ */
diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c
index 0473b482ad23..26d1a1705397 100644
--- a/ndctl/lib/libndctl.c
+++ b/ndctl/lib/libndctl.c
@@ -1218,7 +1218,6 @@ static void *add_dimm(void *parent, int id, const char *dimm_base)
goto err_read;
dimm->module = to_module(ctx, buf);
- dimm->smart_ops = intel_smart_ops;
dimm->handle = -1;
dimm->phys_id = -1;
dimm->serial = -1;
@@ -1306,6 +1305,8 @@ static void *add_dimm(void *parent, int id, const char *dimm_base)
sprintf(path, "%s/nfit/family", dimm_base);
if (sysfs_read_attr(ctx, path, buf) == 0)
dimm->cmd_family = strtoul(buf, NULL, 0);
+ if (dimm->cmd_family == NVDIMM_FAMILY_INTEL)
+ dimm->smart_ops = intel_smart_ops;
if (dimm->cmd_family == NVDIMM_FAMILY_HPE1)
dimm->smart_ops = hpe1_smart_ops;
if (dimm->cmd_family == NVDIMM_FAMILY_MSFT)
diff --git a/ndctl/lib/private.h b/ndctl/lib/private.h
index c2ce519ebad2..08e60af95e9e 100644
--- a/ndctl/lib/private.h
+++ b/ndctl/lib/private.h
@@ -31,6 +31,7 @@
#include <ndctl/libndctl.h>
#include <ccan/endian/endian.h>
#include <ccan/short_types/short_types.h>
+#include "intel.h"
#include "hpe1.h"
#include "msft.h"
@@ -268,8 +269,7 @@ struct ndctl_cmd {
#endif
struct ndn_pkg_hpe1 hpe1[0];
struct ndn_pkg_msft msft[0];
- struct nd_cmd_smart smart[0];
- struct nd_cmd_smart_threshold smart_t[0];
+ struct nd_pkg_intel intel[0];
struct nd_cmd_get_config_size get_size[0];
struct nd_cmd_get_config_data_hdr get_data[0];
struct nd_cmd_set_config_hdr set_data[0];
diff --git a/ndctl/lib/smart.c b/ndctl/lib/smart.c
index d30288a1486a..3eeb70e0d2b1 100644
--- a/ndctl/lib/smart.c
+++ b/ndctl/lib/smart.c
@@ -77,158 +77,3 @@ NDCTL_EXPORT unsigned int ndctl_cmd_smart_threshold_get_temperature(
{
return ndctl_cmd_smart_threshold_get_media_temperature(cmd);
}
-
-/*
- * The following intel_dimm_*() and intel_smart_*() functions implement
- * the ndctl_smart_ops for the Intel DSM family (NVDIMM_FAMILY_INTEL):
- */
-
-static struct ndctl_cmd *intel_dimm_cmd_new_smart(struct ndctl_dimm *dimm)
-{
- struct ndctl_bus *bus = ndctl_dimm_get_bus(dimm);
- struct ndctl_ctx *ctx = ndctl_bus_get_ctx(bus);
- struct ndctl_cmd *cmd;
- size_t size;
-
- BUILD_ASSERT(sizeof(struct nd_smart_payload) == 128);
-
- if (!ndctl_dimm_is_cmd_supported(dimm, ND_CMD_SMART)) {
- dbg(ctx, "unsupported cmd\n");
- return NULL;
- }
-
- size = sizeof(*cmd) + sizeof(struct nd_cmd_smart);
- cmd = calloc(1, size);
- if (!cmd)
- return NULL;
-
- cmd->dimm = dimm;
- ndctl_cmd_ref(cmd);
- cmd->type = ND_CMD_SMART;
- cmd->size = size;
- cmd->status = 1;
- cmd->firmware_status = &cmd->smart->status;
-
- return cmd;
-}
-
-static int intel_smart_valid(struct ndctl_cmd *cmd)
-{
- if (cmd->type != ND_CMD_SMART || cmd->status != 0)
- return cmd->status < 0 ? cmd->status : -EINVAL;
- return 0;
-}
-
-#define intel_smart_get_field(cmd, field) \
-static unsigned int intel_cmd_smart_get_##field(struct ndctl_cmd *cmd) \
-{ \
- struct nd_smart_payload *smart_data; \
- if (intel_smart_valid(cmd) < 0) \
- return UINT_MAX; \
- smart_data = (struct nd_smart_payload *) cmd->smart->data; \
- return smart_data->field; \
-}
-
-intel_smart_get_field(cmd, flags)
-intel_smart_get_field(cmd, health)
-intel_smart_get_field(cmd, temperature)
-intel_smart_get_field(cmd, spares)
-intel_smart_get_field(cmd, alarm_flags)
-intel_smart_get_field(cmd, life_used)
-intel_smart_get_field(cmd, shutdown_state)
-intel_smart_get_field(cmd, shutdown_count)
-intel_smart_get_field(cmd, vendor_size)
-
-static unsigned int intel_cmd_smart_get_media_temperature(
- struct ndctl_cmd *cmd)
-{
- return intel_cmd_smart_get_temperature(cmd);
-}
-
-static unsigned char *intel_cmd_smart_get_vendor_data(struct ndctl_cmd *cmd)
-{
- struct nd_smart_payload *smart_data;
-
- if (intel_smart_valid(cmd) < 0)
- return NULL;
- smart_data = (struct nd_smart_payload *) cmd->smart->data;
- return (unsigned char *) smart_data->vendor_data;
-}
-
-static int intel_smart_threshold_valid(struct ndctl_cmd *cmd)
-{
- if (cmd->type != ND_CMD_SMART_THRESHOLD || cmd->status != 0)
- return cmd->status < 0 ? cmd->status : -EINVAL;
- return 0;
-}
-
-#define intel_smart_threshold_get_field(cmd, field) \
-static unsigned int intel_cmd_smart_threshold_get_##field( \
- struct ndctl_cmd *cmd) \
-{ \
- struct nd_smart_threshold_payload *smart_t_data; \
- if (intel_smart_threshold_valid(cmd) < 0) \
- return UINT_MAX; \
- smart_t_data = (struct nd_smart_threshold_payload *) \
- cmd->smart_t->data; \
- return smart_t_data->field; \
-}
-
-intel_smart_threshold_get_field(cmd, alarm_control)
-intel_smart_threshold_get_field(cmd, temperature)
-intel_smart_threshold_get_field(cmd, spares)
-
-static unsigned int intel_cmd_smart_threshold_get_media_temperature(
- struct ndctl_cmd *cmd)
-{
- return intel_cmd_smart_threshold_get_temperature(cmd);
-}
-
-static struct ndctl_cmd *intel_dimm_cmd_new_smart_threshold(
- struct ndctl_dimm *dimm)
-{
- struct ndctl_bus *bus = ndctl_dimm_get_bus(dimm);
- struct ndctl_ctx *ctx = ndctl_bus_get_ctx(bus);
- struct ndctl_cmd *cmd;
- size_t size;
-
- BUILD_ASSERT(sizeof(struct nd_smart_threshold_payload) == 8);
-
- if (!ndctl_dimm_is_cmd_supported(dimm, ND_CMD_SMART_THRESHOLD)) {
- dbg(ctx, "unsupported cmd\n");
- return NULL;
- }
-
- size = sizeof(*cmd) + sizeof(struct nd_cmd_smart_threshold);
- cmd = calloc(1, size);
- if (!cmd)
- return NULL;
-
- cmd->dimm = dimm;
- ndctl_cmd_ref(cmd);
- cmd->type = ND_CMD_SMART_THRESHOLD;
- cmd->size = size;
- cmd->status = 1;
- cmd->firmware_status = &cmd->smart_t->status;
-
- return cmd;
-}
-
-struct ndctl_smart_ops * const intel_smart_ops = &(struct ndctl_smart_ops) {
- .new_smart = intel_dimm_cmd_new_smart,
- .smart_get_flags = intel_cmd_smart_get_flags,
- .smart_get_health = intel_cmd_smart_get_health,
- .smart_get_media_temperature = intel_cmd_smart_get_media_temperature,
- .smart_get_spares = intel_cmd_smart_get_spares,
- .smart_get_alarm_flags = intel_cmd_smart_get_alarm_flags,
- .smart_get_life_used = intel_cmd_smart_get_life_used,
- .smart_get_shutdown_state = intel_cmd_smart_get_shutdown_state,
- .smart_get_shutdown_count = intel_cmd_smart_get_shutdown_count,
- .smart_get_vendor_size = intel_cmd_smart_get_vendor_size,
- .smart_get_vendor_data = intel_cmd_smart_get_vendor_data,
- .new_smart_threshold = intel_dimm_cmd_new_smart_threshold,
- .smart_threshold_get_alarm_control = intel_cmd_smart_threshold_get_alarm_control,
- .smart_threshold_get_media_temperature
- = intel_cmd_smart_threshold_get_media_temperature,
- .smart_threshold_get_spares = intel_cmd_smart_threshold_get_spares,
-};
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [ndctl PATCH 05/17] ndctl: remove support for compiling against the kernel ndctl.h header
2017-12-01 23:24 [ndctl PATCH 00/16] ndctl: update SMART support for NVDIMM_FAMILY_INTEL Dan Williams
` (3 preceding siblings ...)
2017-12-01 23:24 ` [ndctl PATCH 04/17] ndctl, intel: switch to ND_CMD_CALL passthrough for SMART commands Dan Williams
@ 2017-12-01 23:24 ` Dan Williams
2017-12-01 23:25 ` [ndctl PATCH 06/17] ndctl, test: emit smart field names Dan Williams
` (12 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Dan Williams @ 2017-12-01 23:24 UTC (permalink / raw)
To: linux-nvdimm
Building against the local copy of ndctl.h has been the default for
almost 2 years (commit df5a175efe6b "ndctl: make --enable-local the
default"). Now that SMART definitions are moving from ndctl.h to
libndctl.h remove the ability to build against local kernel headers, and
update the local ND_SMART_*_VALID flags to include CTEMP (controller
temperature), AIT_STATUS, and PTEMP (pmic temperature).
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
configure.ac | 120 -------------------------------
ndctl.spec.in | 4 +
ndctl/Makefile.am | 5 -
ndctl/check.c | 7 --
ndctl/inject-error.c | 6 --
ndctl/lib/Makefile.am | 23 ++----
ndctl/lib/ars.c | 9 --
ndctl/lib/intel.c | 8 ++
ndctl/lib/libndctl.c | 21 +----
ndctl/lib/private.h | 30 --------
ndctl/libndctl.h | 181 ++++++-----------------------------------------
ndctl/list.c | 5 -
ndctl/namespace.c | 9 +-
ndctl/ndctl.h | 59 ---------------
ndctl/util/json-smart.c | 7 --
test/blk_namespaces.c | 7 --
test/daxdev-errors.c | 6 --
test/dpa-alloc.c | 7 --
test/dsm-fail.c | 4 -
test/libndctl.c | 49 +++++--------
test/multi-pmem.c | 5 -
test/pmem_namespaces.c | 5 -
util/json.c | 5 -
util/json.h | 8 --
24 files changed, 73 insertions(+), 517 deletions(-)
rename ndctl/{libndctl.h.in => libndctl.h} (88%)
diff --git a/configure.ac b/configure.ac
index 5b103813ee6f..70ba36028eea 100644
--- a/configure.ac
+++ b/configure.ac
@@ -126,126 +126,6 @@ AC_ARG_ENABLE([local],
AS_HELP_STRING([--disable-local], [build against kernel ndctl.h @<:@default=system@:>@]),
[], [enable_local=yes])
-AS_IF([test "x$enable_local" = "xyes"], [], [
- AC_CHECK_HEADER([linux/ndctl.h], [
- AC_DEFINE([HAVE_NDCTL_H], [1],
- [Define to 1 if you have <linux/ndctl.h>.])
- ], [])
- ]
-)
-
-# when building against kernel headers check version specific features
-AC_MSG_CHECKING([for ARS 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 = ARS_STATUS_MASK;
- ]]
- )], [AC_MSG_RESULT([yes])
- enable_ars=yes
- AC_DEFINE([HAVE_NDCTL_ARS], [1],
- [Define to 1 if ndctl.h has ARS support.])
- ], [AC_MSG_RESULT([no])]
-)
-AM_CONDITIONAL([ENABLE_ARS], [test "x$enable_ars" = "xyes"])
-
-AC_MSG_CHECKING([for CLEAR ERR 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_CLEAR_ERROR;
- ]]
- )], [AC_MSG_RESULT([yes])
- enable_clear_err=yes
- AC_DEFINE([HAVE_NDCTL_CLEAR_ERROR], [1],
- [Define to 1 if ndctl.h has CLEAR ERR support.])
- ], [AC_MSG_RESULT([no])]
-)
-AM_CONDITIONAL([ENABLE_CLEAR_ERROR], [test "x$enable_clear_err" = "xyes"])
-
-AC_MSG_CHECKING([for device DAX 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_DEVICE_DAX_PMEM;
- ]]
- )], [AC_MSG_RESULT([yes])
- enable_dev_dax=yes
- AC_DEFINE([HAVE_NDCTL_DEVICE_DAX], [1],
- [Define to 1 if ndctl.h has device DAX support.])
- ], [AC_MSG_RESULT([no])]
-)
-AM_CONDITIONAL([ENABLE_DEV_DAX], [test "x$enable_dev_dax" = "xyes"])
-
-AC_MSG_CHECKING([for SMART 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_SMART_HEALTH_VALID;
- ]]
- )], [AC_MSG_RESULT([yes])
- enable_smart=yes
- AC_DEFINE([HAVE_NDCTL_SMART], [1],
- [Define to 1 if ndctl.h has SMART support.])
- ], [AC_MSG_RESULT([no])]
-)
-AM_CONDITIONAL([ENABLE_SMART], [test "x$enable_smart" = "xyes"])
-
-AC_CONFIG_COMMANDS([gen-libndctl.h],
- [[
- if test "x$enable_ars" = "xyes"; then
- enable_ars=1
- else
- enable_ars=0
- fi
- if test "x$enable_smart" = "xyes"; then
- enable_smart=1
- else
- enable_smart=0
- fi
- if test "x$enable_clear_err" = "xyes"; then
- enable_clear_err=1
- else
- enable_clear_err=0
- fi
- if test "x$enable_dev_dax" = "xyes"; then
- enable_dev_dax=1
- else
- enable_dev_dax=0
- fi
- sed -e s/HAVE_NDCTL_ARS/$enable_ars/ \
- -e s/HAVE_NDCTL_SMART/$enable_smart/ \
- -e s/HAVE_NDCTL_CLEAR_ERROR/$enable_clear_err/ \
- -e s/HAVE_NDCTL_DEV_DAX/$enable_dev_dax/ \
- < ndctl/libndctl.h.in > ndctl/libndctl.h
- ]],
- [[
- enable_ars=$enable_ars
- enable_smart=$enable_smart
- enable_clear_err=$enable_clear_err
- enable_dev_dax=$enable_dev_dax
- ]])
-
AC_CHECK_HEADERS_ONCE([linux/version.h])
AC_CHECK_FUNCS([ \
diff --git a/ndctl.spec.in b/ndctl.spec.in
index fa60518e43a9..3a5edc37ca7c 100644
--- a/ndctl.spec.in
+++ b/ndctl.spec.in
@@ -94,9 +94,9 @@ control API for these devices.
echo %{version} > version
./autogen.sh
%ifarch x86_64
-%configure --disable-static --enable-local --disable-silent-rules --with-libpmem
+%configure --disable-static --disable-silent-rules --with-libpmem
%else
-%configure --disable-static --enable-local --disable-silent-rules
+%configure --disable-static --disable-silent-rules
%endif
make %{?_smp_mflags}
diff --git a/ndctl/Makefile.am b/ndctl/Makefile.am
index a0cf500ac87c..6677607ba6b3 100644
--- a/ndctl/Makefile.am
+++ b/ndctl/Makefile.am
@@ -12,12 +12,9 @@ ndctl_SOURCES = ndctl.c \
list.c \
test.c \
../util/json.c \
+ util/json-smart.c \
inject-error.c
-if ENABLE_SMART
-ndctl_SOURCES += util/json-smart.c
-endif
-
if ENABLE_DESTRUCTIVE
ndctl_SOURCES += ../test/blk_namespaces.c \
../test/pmem_namespaces.c
diff --git a/ndctl/check.c b/ndctl/check.c
index 3d58f8930fcf..bb60dffe8308 100644
--- a/ndctl/check.c
+++ b/ndctl/check.c
@@ -18,6 +18,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
+#include <ndctl.h>
#include <limits.h>
#include <stdbool.h>
#include <sys/mman.h>
@@ -36,12 +37,6 @@
#include <ccan/array_size/array_size.h>
#include <ccan/short_types/short_types.h>
-#ifdef HAVE_NDCTL_H
-#include <linux/ndctl.h>
-#else
-#include <ndctl.h>
-#endif
-
struct check_opts {
bool verbose;
bool force;
diff --git a/ndctl/inject-error.c b/ndctl/inject-error.c
index 4c4590229df4..374ae0bde4ce 100644
--- a/ndctl/inject-error.c
+++ b/ndctl/inject-error.c
@@ -22,6 +22,7 @@
#include <sys/types.h>
#include <sys/ioctl.h>
+#include <ndctl.h>
#include <util/log.h>
#include <util/size.h>
#include <util/json.h>
@@ -31,11 +32,6 @@
#include <util/parse-options.h>
#include <ccan/array_size/array_size.h>
#include <ccan/short_types/short_types.h>
-#ifdef HAVE_NDCTL_H
-#include <linux/ndctl.h>
-#else
-#include <ndctl.h>
-#endif
#include "private.h"
#include <builtin.h>
diff --git a/ndctl/lib/Makefile.am b/ndctl/lib/Makefile.am
index 3a51e799afa1..5e10fde53a51 100644
--- a/ndctl/lib/Makefile.am
+++ b/ndctl/lib/Makefile.am
@@ -1,9 +1,5 @@
include $(top_srcdir)/Makefile.am.in
-BUILT_SOURCES = ../libndctl.h
-../libndctl.h: ../libndctl.h.in
- touch $(top_srcdir)/version.m4
-
%.pc: %.pc.in Makefile
$(SED_PROCESS)
@@ -19,6 +15,12 @@ libndctl_la_SOURCES =\
../../util/sysfs.h \
dimm.c \
inject.c \
+ nfit.c \
+ smart.c \
+ intel.c \
+ hpe1.c \
+ msft.c \
+ ars.c \
libndctl.c
libndctl_la_LIBADD =\
@@ -27,19 +29,6 @@ libndctl_la_LIBADD =\
$(UUID_LIBS) \
$(KMOD_LIBS)
-if ENABLE_ARS
-libndctl_la_SOURCES += ars.c
-endif
-
-if ENABLE_SMART
-libndctl_la_SOURCES += smart.c
-libndctl_la_SOURCES += intel.c
-libndctl_la_SOURCES += hpe1.c
-libndctl_la_SOURCES += msft.c
-endif
-
-libndctl_la_SOURCES += nfit.c
-
EXTRA_DIST += libndctl.sym
libndctl_la_LDFLAGS = $(AM_LDFLAGS) \
diff --git a/ndctl/lib/ars.c b/ndctl/lib/ars.c
index 735c1457a3ec..d53d89857bce 100644
--- a/ndctl/lib/ars.c
+++ b/ndctl/lib/ars.c
@@ -43,7 +43,6 @@ NDCTL_EXPORT struct ndctl_cmd *ndctl_bus_cmd_new_ars_cap(struct ndctl_bus *bus,
return cmd;
}
-#ifdef HAVE_NDCTL_CLEAR_ERROR
static bool is_power_of_2(unsigned int v)
{
return v && ((v & (v - 1)) == 0);
@@ -55,12 +54,6 @@ static bool validate_clear_error(struct ndctl_cmd *ars_cap)
return false;
return true;
}
-#else
-static bool validate_clear_error(struct ndctl_cmd *ars_cap)
-{
- return true;
-}
-#endif
static bool __validate_ars_cap(struct ndctl_cmd *ars_cap)
{
@@ -253,7 +246,6 @@ NDCTL_EXPORT unsigned long long ndctl_cmd_ars_get_record_len(
return 0;
}
-#ifdef HAVE_NDCTL_CLEAR_ERROR
NDCTL_EXPORT struct ndctl_cmd *ndctl_bus_cmd_new_clear_error(
unsigned long long address, unsigned long long len,
struct ndctl_cmd *ars_cap)
@@ -314,4 +306,3 @@ NDCTL_EXPORT unsigned long long ndctl_cmd_clear_error_get_cleared(
dbg(ctx, "invalid clear_err\n");
return 0;
}
-#endif
diff --git a/ndctl/lib/intel.c b/ndctl/lib/intel.c
index 5aad8c24f00c..478f379324f5 100644
--- a/ndctl/lib/intel.c
+++ b/ndctl/lib/intel.c
@@ -107,9 +107,15 @@ static unsigned int intel_cmd_smart_get_flags(struct ndctl_cmd *cmd)
if (intel_flags & ND_INTEL_SMART_USED_VALID)
flags |= ND_SMART_USED_VALID;
if (intel_flags & ND_INTEL_SMART_MTEMP_VALID)
- flags |= ND_SMART_TEMP_VALID;
+ flags |= ND_SMART_MTEMP_VALID;
+ if (intel_flags & ND_INTEL_SMART_CTEMP_VALID)
+ flags |= ND_SMART_CTEMP_VALID;
if (intel_flags & ND_INTEL_SMART_SHUTDOWN_COUNT_VALID)
flags |= ND_SMART_SHUTDOWN_COUNT_VALID;
+ if (intel_flags & ND_INTEL_SMART_AIT_STATUS_VALID)
+ flags |= ND_SMART_AIT_STATUS_VALID;
+ if (intel_flags & ND_INTEL_SMART_PTEMP_VALID)
+ flags |= ND_SMART_PTEMP_VALID;
if (intel_flags & ND_INTEL_SMART_ALARM_VALID)
flags |= ND_SMART_ALARM_VALID;
if (intel_flags & ND_INTEL_SMART_SHUTDOWN_VALID)
diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c
index 26d1a1705397..47ba2807495e 100644
--- a/ndctl/lib/libndctl.c
+++ b/ndctl/lib/libndctl.c
@@ -30,12 +30,7 @@
#include <ccan/array_size/array_size.h>
#include <ccan/build_assert/build_assert.h>
-#ifdef HAVE_NDCTL_H
-#include <linux/ndctl.h>
-#else
#include <ndctl.h>
-#endif
-
#include <util/sysfs.h>
#include <ndctl/libndctl.h>
#include <ndctl/namespace.h>
@@ -631,9 +626,9 @@ static int to_cmd_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_CLEAR_ERROR;
if (!end_cmd)
- end_cmd = nd_cmd_ars_status;
+ end_cmd = ND_CMD_ARS_STATUS;
cmd_name_fn = nvdimm_bus_cmd_name;
}
@@ -1944,9 +1939,7 @@ static const char *ndctl_device_type_name(int type)
case ND_DEVICE_NAMESPACE_IO: return "namespace_io";
case ND_DEVICE_NAMESPACE_PMEM: return "namespace_pmem";
case ND_DEVICE_NAMESPACE_BLK: return "namespace_blk";
-#ifdef HAVE_NDCTL_DEVICE_DAX
case ND_DEVICE_DAX_PMEM: return "dax_pmem";
-#endif
default: return "unknown";
}
}
@@ -2360,23 +2353,17 @@ static int to_ioctl_cmd(int cmd, int dimm)
{
if (!dimm) {
switch (cmd) {
-#ifdef HAVE_NDCTL_ARS
case ND_CMD_ARS_CAP: return ND_IOCTL_ARS_CAP;
case ND_CMD_ARS_START: return ND_IOCTL_ARS_START;
case ND_CMD_ARS_STATUS: return ND_IOCTL_ARS_STATUS;
-#endif
-#ifdef HAVE_NDCTL_CLEAR_ERROR
case ND_CMD_CLEAR_ERROR: return ND_IOCTL_CLEAR_ERROR;
-#endif
case ND_CMD_CALL: return ND_IOCTL_CALL;
default:
- return 0;
+ return 0;
};
}
switch (cmd) {
- case ND_CMD_SMART: return ND_IOCTL_SMART;
- case ND_CMD_SMART_THRESHOLD: return ND_IOCTL_SMART_THRESHOLD;
case ND_CMD_DIMM_FLAGS: return ND_IOCTL_DIMM_FLAGS;
case ND_CMD_GET_CONFIG_SIZE: return ND_IOCTL_GET_CONFIG_SIZE;
case ND_CMD_GET_CONFIG_DATA: return ND_IOCTL_GET_CONFIG_DATA;
@@ -2386,7 +2373,7 @@ static int to_ioctl_cmd(int cmd, int dimm)
case ND_CMD_VENDOR_EFFECT_LOG_SIZE:
case ND_CMD_VENDOR_EFFECT_LOG:
default:
- return 0;
+ return 0;
}
}
diff --git a/ndctl/lib/private.h b/ndctl/lib/private.h
index 08e60af95e9e..1b365ae96bfc 100644
--- a/ndctl/lib/private.h
+++ b/ndctl/lib/private.h
@@ -23,11 +23,8 @@
#include <uuid/uuid.h>
#include <ccan/list/list.h>
#include <ccan/array_size/array_size.h>
-#ifdef HAVE_NDCTL_H
-#include <linux/ndctl.h>
-#else
+
#include <ndctl.h>
-#endif
#include <ndctl/libndctl.h>
#include <ccan/endian/endian.h>
#include <ccan/short_types/short_types.h>
@@ -259,14 +256,10 @@ struct ndctl_cmd {
} iter;
struct ndctl_cmd *source;
union {
-#ifdef HAVE_NDCTL_ARS
struct nd_cmd_ars_cap ars_cap[0];
struct nd_cmd_ars_start ars_start[0];
struct nd_cmd_ars_status ars_status[0];
-#endif
-#ifdef HAVE_NDCTL_CLEAR_ERROR
struct nd_cmd_clear_error clear_err[0];
-#endif
struct ndn_pkg_hpe1 hpe1[0];
struct ndn_pkg_msft msft[0];
struct nd_pkg_intel intel[0];
@@ -302,30 +295,9 @@ struct ndctl_smart_ops {
unsigned int (*smart_threshold_get_spares)(struct ndctl_cmd *);
};
-#if HAS_SMART == 1
struct ndctl_smart_ops * const intel_smart_ops;
struct ndctl_smart_ops * const hpe1_smart_ops;
struct ndctl_smart_ops * const msft_smart_ops;
-#else
-static struct ndctl_smart_ops * const intel_smart_ops = NULL;
-static struct ndctl_smart_ops * const hpe1_smart_ops = NULL;
-static struct ndctl_smart_ops * const msft_smart_ops = NULL;
-#endif
-
-/* internal library helpers for conditionally defined command numbers */
-#ifdef HAVE_NDCTL_ARS
-static const int nd_cmd_ars_status = ND_CMD_ARS_STATUS;
-static const int nd_cmd_ars_cap = ND_CMD_ARS_CAP;
-#else
-static const int nd_cmd_ars_status;
-static const int nd_cmd_ars_cap;
-#endif
-
-#ifdef HAVE_NDCTL_CLEAR_ERROR
-static const int nd_cmd_clear_error = ND_CMD_CLEAR_ERROR;
-#else
-static const int nd_cmd_clear_error;
-#endif
static inline struct ndctl_bus *cmd_to_bus(struct ndctl_cmd *cmd)
{
diff --git a/ndctl/libndctl.h.in b/ndctl/libndctl.h
similarity index 88%
rename from ndctl/libndctl.h.in
rename to ndctl/libndctl.h
index 298adff476c7..a2b3148dbb27 100644
--- a/ndctl/libndctl.h.in
+++ b/ndctl/libndctl.h
@@ -174,8 +174,6 @@ int ndctl_dimm_disable(struct ndctl_dimm *dimm);
int ndctl_dimm_enable(struct ndctl_dimm *dimm);
struct ndctl_cmd;
-#define HAS_ARS HAVE_NDCTL_ARS
-#if HAS_ARS == 1
struct ndctl_cmd *ndctl_bus_cmd_new_ars_cap(struct ndctl_bus *bus,
unsigned long long address, unsigned long long len);
struct ndctl_cmd *ndctl_bus_cmd_new_ars_start(struct ndctl_cmd *ars_cap, int type);
@@ -193,95 +191,40 @@ unsigned long long ndctl_cmd_ars_get_record_addr(struct ndctl_cmd *ars_stat,
unsigned int rec_index);
unsigned long long ndctl_cmd_ars_get_record_len(struct ndctl_cmd *ars_stat,
unsigned int rec_index);
-
-#define HAS_CLEAR_ERROR HAVE_NDCTL_CLEAR_ERROR
-#if HAS_CLEAR_ERROR == 1
-/*
- * clear_error requires ars_cap, so we require HAS_CLEAR_ERROR to export
- * the clear_error capability
- */
struct ndctl_cmd *ndctl_bus_cmd_new_clear_error(unsigned long long address,
unsigned long long len, struct ndctl_cmd *ars_cap);
unsigned long long ndctl_cmd_clear_error_get_cleared(
struct ndctl_cmd *clear_err);
-#endif
-#else /* HAS_ARS == 0 */
-static inline struct ndctl_cmd *ndctl_bus_cmd_new_ars_cap(struct ndctl_bus *bus,
- unsigned long long address, unsigned long long len)
-{
- return NULL;
-}
-
-static inline struct ndctl_cmd *ndctl_bus_cmd_new_ars_start(
- struct ndctl_cmd *ars_cap, int type)
-{
- return NULL;
-}
-
-static inline struct ndctl_cmd *ndctl_bus_cmd_new_ars_status(
- struct ndctl_cmd *ars_cap)
-{
- return NULL;
-}
-
-static inline unsigned int ndctl_cmd_ars_cap_get_size(struct ndctl_cmd *ars_cap)
-{
- return 0;
-}
-
-struct ndctl_range;
-static inline int ndctl_cmd_ars_cap_get_range(struct ndctl_cmd *ars_cap,
- struct ndctl_range *range)
-{
- return -ENXIO;
-}
-
-static inline unsigned int ndctl_cmd_ars_in_progress(struct ndctl_cmd *ars_status)
-{
- return 0;
-}
-
-static inline unsigned int ndctl_cmd_ars_num_records(struct ndctl_cmd *ars_stat)
-{
- return 0;
-}
-
-static inline unsigned long long ndctl_cmd_ars_get_record_addr(
- struct ndctl_cmd *ars_stat, unsigned int rec_index)
-{
- return 0;
-}
-
-static inline unsigned long long ndctl_cmd_ars_get_record_len(
- struct ndctl_cmd *ars_stat, unsigned int rec_index)
-{
- return 0;
-}
-#define HAS_CLEAR_ERROR 0
-#endif /* HAS_ARS */
-
-#if HAS_CLEAR_ERROR == 0
-static inline struct ndctl_cmd *ndctl_bus_cmd_new_clear_error(
- unsigned long long address, unsigned long long len,
- struct ndctl_cmd *ars_cap)
-{
- return NULL;
-}
-
-static inline unsigned long long ndctl_cmd_clear_error_get_cleared(
- struct ndctl_cmd *clear_err)
-{
- return 0;
-}
-#endif
/*
* Note: ndctl_cmd_smart_get_temperature is an alias for
* ndctl_cmd_smart_get_temperature
*/
-#define HAS_SMART HAVE_NDCTL_SMART
-#if HAS_SMART == 1
+/*
+ * the ndctl.h definition of these are deprecated, libndctl.h is the
+ * authoritative defintion.
+ */
+#define ND_SMART_HEALTH_VALID (1 << 0)
+#define ND_SMART_SPARES_VALID (1 << 1)
+#define ND_SMART_USED_VALID (1 << 2)
+#define ND_SMART_MTEMP_VALID (1 << 3)
+#define ND_SMART_TEMP_VALID ND_SMART_MTEMP_VALID
+#define ND_SMART_CTEMP_VALID (1 << 4)
+#define ND_SMART_SHUTDOWN_COUNT_VALID (1 << 5)
+#define ND_SMART_AIT_STATUS_VALID (1 << 6)
+#define ND_SMART_PTEMP_VALID (1 << 7)
+#define ND_SMART_ALARM_VALID (1 << 9)
+#define ND_SMART_SHUTDOWN_VALID (1 << 10)
+#define ND_SMART_VENDOR_VALID (1 << 11)
+#define ND_SMART_SPARE_TRIP (1 << 0)
+#define ND_SMART_MTEMP_TRIP (1 << 1)
+#define ND_SMART_TEMP_TRIP ND_SMART_MTEMP_TRIP
+#define ND_SMART_CTEMP_TRIP (1 << 2)
+#define ND_SMART_NON_CRITICAL_HEALTH (1 << 0)
+#define ND_SMART_CRITICAL_HEALTH (1 << 1)
+#define ND_SMART_FATAL_HEALTH (1 << 2)
+
struct ndctl_cmd *ndctl_dimm_cmd_new_smart(struct ndctl_dimm *dimm);
unsigned int ndctl_cmd_smart_get_flags(struct ndctl_cmd *cmd);
unsigned int ndctl_cmd_smart_get_health(struct ndctl_cmd *cmd);
@@ -299,82 +242,6 @@ unsigned int ndctl_cmd_smart_threshold_get_alarm_control(struct ndctl_cmd *cmd);
unsigned int ndctl_cmd_smart_threshold_get_temperature(struct ndctl_cmd *cmd);
unsigned int ndctl_cmd_smart_threshold_get_media_temperature(struct ndctl_cmd *cmd);
unsigned int ndctl_cmd_smart_threshold_get_spares(struct ndctl_cmd *cmd);
-#else
-static inline struct ndctl_cmd *ndctl_dimm_cmd_new_smart(struct ndctl_dimm *dimm)
-{
- return NULL;
-}
-static inline unsigned int ndctl_cmd_smart_get_flags(struct ndctl_cmd *cmd)
-{
- return 0;
-}
-static inline unsigned int ndctl_cmd_smart_get_health(struct ndctl_cmd *cmd)
-{
- return 0;
-}
-static inline unsigned int ndctl_cmd_smart_get_temperature(struct ndctl_cmd *cmd)
-{
- return 0;
-}
-static inline unsigned int ndctl_cmd_smart_get_media_temperature(
- struct ndctl_cmd *cmd)
-{
- return 0;
-}
-static inline unsigned int ndctl_cmd_smart_get_spares(struct ndctl_cmd *cmd)
-{
- return 0;
-}
-static inline unsigned int ndctl_cmd_smart_get_alarm_flags(struct ndctl_cmd *cmd)
-{
- return 0;
-}
-static inline unsigned int ndctl_cmd_smart_get_life_used(struct ndctl_cmd *cmd)
-{
- return 0;
-}
-static inline unsigned int ndctl_cmd_smart_get_shutdown_state(struct ndctl_cmd *cmd)
-{
- return 0;
-}
-static inline unsigned int ndctl_cmd_smart_get_shutdown_count(struct ndctl_cmd *cmd)
-{
- return 0;
-}
-static inline unsigned int ndctl_cmd_smart_get_vendor_size(struct ndctl_cmd *cmd)
-{
- return 0;
-}
-static inline unsigned char *ndctl_cmd_smart_get_vendor_data(struct ndctl_cmd *cmd)
-{
- return NULL;
-}
-static inline struct ndctl_cmd *ndctl_dimm_cmd_new_smart_threshold(
- struct ndctl_dimm *dimm)
-{
- return NULL;
-}
-static inline unsigned int ndctl_cmd_smart_threshold_get_alarm_control(
- struct ndctl_cmd *cmd)
-{
- return 0;
-}
-static inline unsigned int ndctl_cmd_smart_threshold_get_temperature(
- struct ndctl_cmd *cmd)
-{
- return 0;
-}
-static inline unsigned int ndctl_cmd_smart_threshold_get_media_temperature(
- struct ndctl_cmd *cmd)
-{
- return 0;
-}
-static inline unsigned int ndctl_cmd_smart_threshold_get_spares(
- struct ndctl_cmd *cmd)
-{
- 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);
diff --git a/ndctl/list.c b/ndctl/list.c
index 1960e9f8d7b5..d6e49b03a265 100644
--- a/ndctl/list.c
+++ b/ndctl/list.c
@@ -15,6 +15,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
+
#include <util/json.h>
#include <util/filter.h>
#include <json-c/json.h>
@@ -22,11 +23,7 @@
#include <util/parse-options.h>
#include <ccan/array_size/array_size.h>
-#ifdef HAVE_NDCTL_H
-#include <linux/ndctl.h>
-#else
#include <ndctl.h>
-#endif
static struct {
bool buses;
diff --git a/ndctl/namespace.c b/ndctl/namespace.c
index d31244b71c37..c47867d38a0c 100644
--- a/ndctl/namespace.c
+++ b/ndctl/namespace.c
@@ -17,6 +17,8 @@
#include <unistd.h>
#include <limits.h>
#include <syslog.h>
+
+#include <ndctl.h>
#include "action.h"
#include <sys/stat.h>
#include <uuid/uuid.h>
@@ -28,13 +30,6 @@
#include <ndctl/libndctl.h>
#include <util/parse-options.h>
#include <ccan/minmax/minmax.h>
-#include <ccan/array_size/array_size.h>
-
-#ifdef HAVE_NDCTL_H
-#include <linux/ndctl.h>
-#else
-#include <ndctl.h>
-#endif
static bool verbose;
static bool force;
diff --git a/ndctl/ndctl.h b/ndctl/ndctl.h
index 7f5b120492cf..4cf373b2a5d4 100644
--- a/ndctl/ndctl.h
+++ b/ndctl/ndctl.h
@@ -13,60 +13,9 @@
#ifndef __NDCTL_H__
#define __NDCTL_H__
+#include <ccan/array_size/array_size.h>
#include <linux/types.h>
-struct nd_cmd_smart {
- __u32 status;
- __u8 data[128];
-} __attribute__((packed));
-
-#define ND_SMART_HEALTH_VALID (1 << 0)
-#define ND_SMART_SPARES_VALID (1 << 1)
-#define ND_SMART_USED_VALID (1 << 2)
-#define ND_SMART_TEMP_VALID (1 << 3)
-#define ND_SMART_CTEMP_VALID (1 << 4)
-#define ND_SMART_SHUTDOWN_COUNT_VALID (1 << 5)
-#define ND_SMART_ALARM_VALID (1 << 9)
-#define ND_SMART_SHUTDOWN_VALID (1 << 10)
-#define ND_SMART_VENDOR_VALID (1 << 11)
-#define ND_SMART_SPARE_TRIP (1 << 0)
-#define ND_SMART_TEMP_TRIP (1 << 1)
-#define ND_SMART_CTEMP_TRIP (1 << 2)
-#define ND_SMART_NON_CRITICAL_HEALTH (1 << 0)
-#define ND_SMART_CRITICAL_HEALTH (1 << 1)
-#define ND_SMART_FATAL_HEALTH (1 << 2)
-
-struct nd_smart_payload {
- __u32 flags;
- __u8 reserved0[4];
- __u8 health;
- __u8 spares;
- __u8 life_used;
- __u8 alarm_flags;
- __u16 temperature;
- __u16 ctrl_temperature;
- __u32 shutdown_count;
- __u8 ait_status;
- __u16 pmic_temperature;
- __u8 reserved1[8];
- __u8 shutdown_state;
- __u32 vendor_size;
- __u8 vendor_data[92];
-} __attribute__((packed));
-
-struct nd_cmd_smart_threshold {
- __u32 status;
- __u8 data[8];
-} __attribute__((packed));
-
-struct nd_smart_threshold_payload {
- __u8 alarm_control;
- __u8 reserved0;
- __u16 temperature;
- __u8 spares;
- __u8 reserved[3];
-} __attribute__((packed));
-
struct nd_cmd_dimm_flags {
__u32 status;
__u32 flags;
@@ -215,12 +164,6 @@ static __inline__ const char *nvdimm_cmd_name(unsigned cmd)
#define ND_IOCTL 'N'
-#define ND_IOCTL_SMART _IOWR(ND_IOCTL, ND_CMD_SMART,\
- struct nd_cmd_smart)
-
-#define ND_IOCTL_SMART_THRESHOLD _IOWR(ND_IOCTL, ND_CMD_SMART_THRESHOLD,\
- struct nd_cmd_smart_threshold)
-
#define ND_IOCTL_DIMM_FLAGS _IOWR(ND_IOCTL, ND_CMD_DIMM_FLAGS,\
struct nd_cmd_dimm_flags)
diff --git a/ndctl/util/json-smart.c b/ndctl/util/json-smart.c
index b2bd3ae885fb..7aabf4f3aebe 100644
--- a/ndctl/util/json-smart.c
+++ b/ndctl/util/json-smart.c
@@ -16,12 +16,7 @@
#include <json-c/json.h>
#include <ndctl/libndctl.h>
#include <ccan/array_size/array_size.h>
-
-#ifdef HAVE_NDCTL_H
-#include <linux/ndctl.h>
-#else
#include <ndctl.h>
-#endif
static double parse_smart_temperature(unsigned int temp)
{
@@ -96,8 +91,6 @@ struct json_object *util_dimm_health_to_json(struct ndctl_dimm *dimm)
rc = ndctl_cmd_submit(cmd);
if (rc || ndctl_cmd_get_firmware_status(cmd)) {
- if (!ndctl_dimm_is_cmd_supported(dimm, ND_CMD_SMART))
- goto err;
jobj = json_object_new_string("unknown");
if (jobj)
json_object_object_add(jhealth, "health_state", jobj);
diff --git a/test/blk_namespaces.c b/test/blk_namespaces.c
index 178f73cacb16..7b33bfd0528b 100644
--- a/test/blk_namespaces.c
+++ b/test/blk_namespaces.c
@@ -23,6 +23,7 @@
#include <syslog.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <ndctl.h>
#include <unistd.h>
#include <uuid/uuid.h>
#include <linux/version.h>
@@ -30,12 +31,6 @@
#include <libkmod.h>
#include <ccan/array_size/array_size.h>
-#ifdef HAVE_NDCTL_H
-#include <linux/ndctl.h>
-#else
-#include <ndctl.h>
-#endif
-
/* The purpose of this test is to verify that we can successfully do I/O to
* multiple nd_blk namespaces that have discontiguous segments. It first
* sets up two namespaces, each 1/2 the total size of the NVDIMM and each with
diff --git a/test/daxdev-errors.c b/test/daxdev-errors.c
index ba89b0c047a7..94fbebec4e33 100644
--- a/test/daxdev-errors.c
+++ b/test/daxdev-errors.c
@@ -30,14 +30,10 @@
#include <util/log.h>
#include <util/sysfs.h>
+#include <daxctl/libdaxctl.h>
#include <ccan/array_size/array_size.h>
#include <ndctl/libndctl.h>
-#include <daxctl/libdaxctl.h>
-#ifdef HAVE_NDCTL_H
-#include <linux/ndctl.h>
-#else
#include <ndctl.h>
-#endif
#define fail() fprintf(stderr, "%s: failed at: %d\n", __func__, __LINE__)
diff --git a/test/dpa-alloc.c b/test/dpa-alloc.c
index d13cf5dde66f..9ab10f90293a 100644
--- a/test/dpa-alloc.c
+++ b/test/dpa-alloc.c
@@ -24,16 +24,11 @@
#include <uuid/uuid.h>
#include <test.h>
+#include <ndctl.h>
#include <linux/version.h>
#include <ndctl/libndctl.h>
#include <ccan/array_size/array_size.h>
-#ifdef HAVE_NDCTL_H
-#include <linux/ndctl.h>
-#else
-#include <ndctl.h>
-#endif
-
static const char *NFIT_PROVIDER0 = "nfit_test.0";
static const char *NFIT_PROVIDER1 = "nfit_test.1";
#define SZ_4K 0x1000UL
diff --git a/test/dsm-fail.c b/test/dsm-fail.c
index 22ec94451146..b363decc29c8 100644
--- a/test/dsm-fail.c
+++ b/test/dsm-fail.c
@@ -24,11 +24,7 @@
#include <ccan/array_size/array_size.h>
#include <ndctl/libndctl.h>
-#ifdef HAVE_NDCTL_H
-#include <linux/ndctl.h>
-#else
#include <ndctl.h>
-#endif
#include <test.h>
#define DIMM_PATH "/sys/devices/platform/nfit_test.0/nfit_test_dimm/test_dimm0"
diff --git a/test/libndctl.c b/test/libndctl.c
index 770171919b6c..5189f7886481 100644
--- a/test/libndctl.c
+++ b/test/libndctl.c
@@ -31,11 +31,7 @@
#include <ccan/array_size/array_size.h>
#include <ndctl/libndctl.h>
#include <daxctl/libdaxctl.h>
-#ifdef HAVE_NDCTL_H
-#include <linux/ndctl.h>
-#else
#include <ndctl.h>
-#endif
#include <test.h>
#define BLKROGET _IO(0x12,94) /* get read-only status (0 = read_write) */
@@ -409,18 +405,10 @@ static unsigned long dimm_commands0 = 1UL << ND_CMD_GET_CONFIG_SIZE
| 1UL << ND_CMD_SET_CONFIG_DATA | 1UL << ND_CMD_SMART
| 1UL << ND_CMD_SMART_THRESHOLD;
-#ifdef HAVE_NDCTL_CLEAR_ERROR
#define CLEAR_ERROR_CMDS (1UL << ND_CMD_CLEAR_ERROR)
-#else
-#define CLEAR_ERROR_CMDS 0
-#endif
-#ifdef HAVE_NDCTL_ARS
#define ARS_CMDS (1UL << ND_CMD_ARS_CAP | 1UL << ND_CMD_ARS_START \
| 1UL << ND_CMD_ARS_STATUS)
-#else
-#define ARS_CMDS 0
-#endif
static unsigned long bus_commands0 = CLEAR_ERROR_CMDS | ARS_CMDS;
@@ -2132,7 +2120,6 @@ static int check_set_config_data(struct ndctl_bus *bus, struct ndctl_dimm *dimm,
return 0;
}
-#ifdef HAVE_NDCTL_SMART
#define __check_smart(dimm, cmd, field) ({ \
if (ndctl_cmd_smart_get_##field(cmd) != smart_data.field) { \
fprintf(stderr, "%s dimm: %#x expected field %#x got: %#x\n", \
@@ -2144,10 +2131,19 @@ static int check_set_config_data(struct ndctl_bus *bus, struct ndctl_dimm *dimm,
} \
})
+/*
+ * Note, this is not a command payload, this is just a namespace for
+ * smart parameters.
+ */
+struct smart {
+ unsigned int flags, health, temperature, spares, alarm_flags,
+ life_used, shutdown_state, vendor_size;
+};
+
static int check_smart(struct ndctl_bus *bus, struct ndctl_dimm *dimm,
struct check_cmd *check)
{
- static const struct nd_smart_payload smart_data = {
+ static const struct smart smart_data = {
.flags = ND_SMART_HEALTH_VALID | ND_SMART_TEMP_VALID
| ND_SMART_SPARES_VALID | ND_SMART_ALARM_VALID
| ND_SMART_USED_VALID | ND_SMART_SHUTDOWN_VALID,
@@ -2200,10 +2196,18 @@ static int check_smart(struct ndctl_bus *bus, struct ndctl_dimm *dimm,
} \
})
+/*
+ * Note, this is not a command payload, this is just a namespace for
+ * smart_threshold parameters.
+ */
+struct smart_threshold {
+ unsigned int alarm_control, temperature, spares;
+};
+
static int check_smart_threshold(struct ndctl_bus *bus, struct ndctl_dimm *dimm,
struct check_cmd *check)
{
- static const struct nd_smart_threshold_payload smart_t_data = {
+ static const struct smart_threshold smart_t_data = {
.alarm_control = ND_SMART_SPARE_TRIP | ND_SMART_TEMP_TRIP,
.temperature = 40 * 16,
.spares = 5,
@@ -2277,21 +2281,6 @@ static int check_smart_threshold(struct ndctl_bus *bus, struct ndctl_dimm *dimm,
ndctl_cmd_unref(cmd);
return 0;
}
-#else
-static int check_smart(struct ndctl_bus *bus, struct ndctl_dimm *dimm,
- struct check_cmd *check)
-{
- fprintf(stderr, "%s: HAVE_NDCTL_SMART disabled, skipping\n", __func__);
- return 0;
-}
-
-static int check_smart_threshold(struct ndctl_bus *bus, struct ndctl_dimm *dimm,
- struct check_cmd *check)
-{
- fprintf(stderr, "%s: HAVE_NDCTL_SMART disabled, skipping\n", __func__);
- return 0;
-}
-#endif
#define BITS_PER_LONG 32
static int check_commands(struct ndctl_bus *bus, struct ndctl_dimm *dimm,
diff --git a/test/multi-pmem.c b/test/multi-pmem.c
index 3e3c1037e016..b3054f44b5dd 100644
--- a/test/multi-pmem.c
+++ b/test/multi-pmem.c
@@ -28,12 +28,7 @@
#include <ndctl/libndctl.h>
#include <ccan/array_size/array_size.h>
-#ifdef HAVE_NDCTL_H
-#include <linux/ndctl.h>
-#else
#include <ndctl.h>
-#endif
-
#include <builtin.h>
#include <test.h>
diff --git a/test/pmem_namespaces.c b/test/pmem_namespaces.c
index 94a5986955b3..69e87abc592f 100644
--- a/test/pmem_namespaces.c
+++ b/test/pmem_namespaces.c
@@ -30,12 +30,7 @@
#include <test.h>
#include <ccan/array_size/array_size.h>
-
-#ifdef HAVE_NDCTL_H
-#include <linux/ndctl.h>
-#else
#include <ndctl.h>
-#endif
#define err(msg)\
fprintf(stderr, "%s:%d: %s (%s)\n", __func__, __LINE__, msg, strerror(errno))
diff --git a/util/json.c b/util/json.c
index f49921236823..95beaa2efd38 100644
--- a/util/json.c
+++ b/util/json.c
@@ -21,12 +21,7 @@
#include <daxctl/libdaxctl.h>
#include <ccan/array_size/array_size.h>
#include <ccan/short_types/short_types.h>
-
-#ifdef HAVE_NDCTL_H
-#include <linux/ndctl.h>
-#else
#include <ndctl.h>
-#endif
/* adapted from mdadm::human_size_brief() */
static int display_size(struct json_object *jobj, struct printbuf *pbuf,
diff --git a/util/json.h b/util/json.h
index de55127168c9..96634756c19f 100644
--- a/util/json.h
+++ b/util/json.h
@@ -51,13 +51,5 @@ struct json_object *util_json_object_size(unsigned long long size,
unsigned long flags);
struct json_object *util_json_object_hex(unsigned long long val,
unsigned long flags);
-#ifdef HAVE_NDCTL_SMART
struct json_object *util_dimm_health_to_json(struct ndctl_dimm *dimm);
-#else
-static inline struct json_object *util_dimm_health_to_json(
- struct ndctl_dimm *dimm)
-{
- return NULL;
-}
-#endif
#endif /* __NDCTL_JSON_H__ */
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [ndctl PATCH 06/17] ndctl, test: emit smart field names
2017-12-01 23:24 [ndctl PATCH 00/16] ndctl: update SMART support for NVDIMM_FAMILY_INTEL Dan Williams
` (4 preceding siblings ...)
2017-12-01 23:24 ` [ndctl PATCH 05/17] ndctl: remove support for compiling against the kernel ndctl.h header Dan Williams
@ 2017-12-01 23:25 ` Dan Williams
2017-12-01 23:25 ` [ndctl PATCH 07/17] ndctl, smart: cleanup smart_cmd_op() macro Dan Williams
` (11 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Dan Williams @ 2017-12-01 23:25 UTC (permalink / raw)
To: linux-nvdimm
Make the SMART tests easier to debug by emitting the field name.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
test/libndctl.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/test/libndctl.c b/test/libndctl.c
index 5189f7886481..b534b640cb8d 100644
--- a/test/libndctl.c
+++ b/test/libndctl.c
@@ -2122,8 +2122,9 @@ static int check_set_config_data(struct ndctl_bus *bus, struct ndctl_dimm *dimm,
#define __check_smart(dimm, cmd, field) ({ \
if (ndctl_cmd_smart_get_##field(cmd) != smart_data.field) { \
- fprintf(stderr, "%s dimm: %#x expected field %#x got: %#x\n", \
- __func__, ndctl_dimm_get_handle(dimm), \
+ fprintf(stderr, "%s dimm: %#x expected \'" #field \
+ "\' %#x got: %#x\n", __func__, \
+ ndctl_dimm_get_handle(dimm), \
smart_data.field, \
ndctl_cmd_smart_get_##field(cmd)); \
ndctl_cmd_unref(cmd); \
@@ -2187,8 +2188,9 @@ static int check_smart(struct ndctl_bus *bus, struct ndctl_dimm *dimm,
#define __check_smart_threshold(dimm, cmd, field) ({ \
if (ndctl_cmd_smart_threshold_get_##field(cmd) != smart_t_data.field) { \
- fprintf(stderr, "%s dimm: %#x expected field %#x got: %#x\n", \
- __func__, ndctl_dimm_get_handle(dimm), \
+ fprintf(stderr, "%s dimm: %#x expected \'" #field \
+ "\' %#x got: %#x\n", __func__, \
+ ndctl_dimm_get_handle(dimm), \
smart_t_data.field, \
ndctl_cmd_smart_threshold_get_##field(cmd)); \
ndctl_cmd_unref(cmd); \
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [ndctl PATCH 07/17] ndctl, smart: cleanup smart_cmd_op() macro
2017-12-01 23:24 [ndctl PATCH 00/16] ndctl: update SMART support for NVDIMM_FAMILY_INTEL Dan Williams
` (5 preceding siblings ...)
2017-12-01 23:25 ` [ndctl PATCH 06/17] ndctl, test: emit smart field names Dan Williams
@ 2017-12-01 23:25 ` Dan Williams
2017-12-01 23:25 ` [ndctl PATCH 08/17] ndctl, test: reset all nfit_test data for each test/libndctl run Dan Williams
` (10 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Dan Williams @ 2017-12-01 23:25 UTC (permalink / raw)
To: linux-nvdimm
Remove the redundant information passed to the smart_cmd_op macro.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
ndctl/lib/smart.c | 32 +++++++++++++++-----------------
1 file changed, 15 insertions(+), 17 deletions(-)
diff --git a/ndctl/lib/smart.c b/ndctl/lib/smart.c
index 3eeb70e0d2b1..90c45a1a002e 100644
--- a/ndctl/lib/smart.c
+++ b/ndctl/lib/smart.c
@@ -40,8 +40,8 @@ NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_cmd_new_smart_threshold(
return NULL;
}
-#define smart_cmd_op(name, op, rettype, defretvalue) \
-NDCTL_EXPORT rettype name(struct ndctl_cmd *cmd) \
+#define smart_cmd_op(op, rettype, defretvalue) \
+NDCTL_EXPORT rettype ndctl_cmd_##op(struct ndctl_cmd *cmd) \
{ \
if (cmd->dimm) { \
struct ndctl_smart_ops *ops = ndctl_dimm_get_smart_ops(cmd->dimm); \
@@ -51,21 +51,19 @@ NDCTL_EXPORT rettype name(struct ndctl_cmd *cmd) \
return defretvalue; \
}
-smart_cmd_op(ndctl_cmd_smart_get_flags, smart_get_flags, unsigned int, 0)
-smart_cmd_op(ndctl_cmd_smart_get_health, smart_get_health, unsigned int, 0)
-smart_cmd_op(ndctl_cmd_smart_get_media_temperature, smart_get_media_temperature,
- unsigned int, 0)
-smart_cmd_op(ndctl_cmd_smart_get_spares, smart_get_spares, unsigned int, 0)
-smart_cmd_op(ndctl_cmd_smart_get_alarm_flags, smart_get_alarm_flags, unsigned int, 0)
-smart_cmd_op(ndctl_cmd_smart_get_life_used, smart_get_life_used, unsigned int, 0)
-smart_cmd_op(ndctl_cmd_smart_get_shutdown_state, smart_get_shutdown_state, unsigned int, 0)
-smart_cmd_op(ndctl_cmd_smart_get_shutdown_count, smart_get_shutdown_count, unsigned int, 0)
-smart_cmd_op(ndctl_cmd_smart_get_vendor_size, smart_get_vendor_size, unsigned int, 0)
-smart_cmd_op(ndctl_cmd_smart_get_vendor_data, smart_get_vendor_data, unsigned char *, NULL)
-smart_cmd_op(ndctl_cmd_smart_threshold_get_alarm_control, smart_threshold_get_alarm_control, unsigned int, 0)
-smart_cmd_op(ndctl_cmd_smart_threshold_get_media_temperature,
- smart_threshold_get_media_temperature, unsigned int, 0)
-smart_cmd_op(ndctl_cmd_smart_threshold_get_spares, smart_threshold_get_spares, unsigned int, 0)
+smart_cmd_op(smart_get_flags, unsigned int, 0)
+smart_cmd_op(smart_get_health, unsigned int, 0)
+smart_cmd_op(smart_get_media_temperature, unsigned int, 0)
+smart_cmd_op(smart_get_spares, unsigned int, 0)
+smart_cmd_op(smart_get_alarm_flags, unsigned int, 0)
+smart_cmd_op(smart_get_life_used, unsigned int, 0)
+smart_cmd_op(smart_get_shutdown_state, unsigned int, 0)
+smart_cmd_op(smart_get_shutdown_count, unsigned int, 0)
+smart_cmd_op(smart_get_vendor_size, unsigned int, 0)
+smart_cmd_op(smart_get_vendor_data, unsigned char *, NULL)
+smart_cmd_op(smart_threshold_get_alarm_control, unsigned int, 0)
+smart_cmd_op(smart_threshold_get_media_temperature, unsigned int, 0)
+smart_cmd_op(smart_threshold_get_spares, unsigned int, 0)
NDCTL_EXPORT unsigned int ndctl_cmd_smart_get_temperature(struct ndctl_cmd *cmd)
{
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [ndctl PATCH 08/17] ndctl, test: reset all nfit_test data for each test/libndctl run
2017-12-01 23:24 [ndctl PATCH 00/16] ndctl: update SMART support for NVDIMM_FAMILY_INTEL Dan Williams
` (6 preceding siblings ...)
2017-12-01 23:25 ` [ndctl PATCH 07/17] ndctl, smart: cleanup smart_cmd_op() macro Dan Williams
@ 2017-12-01 23:25 ` Dan Williams
2017-12-01 23:25 ` [ndctl PATCH 09/17] ndctl, region: cleanup error message Dan Williams
` (9 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Dan Williams @ 2017-12-01 23:25 UTC (permalink / raw)
To: linux-nvdimm
In preparation for tests that write smart threshold and injected-smart
values arrange for nfit_test to be completely reloaded for each test
run. I.e. it is no longer sufficient to just clear label data and reset
regions.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
test.h | 3 ++-
test/blk_namespaces.c | 2 +-
test/core.c | 25 ++++++++++++++++++++++++-
test/dpa-alloc.c | 2 +-
test/dsm-fail.c | 2 +-
test/libndctl.c | 2 +-
test/multi-pmem.c | 2 +-
test/parent-uuid.c | 2 +-
test/pmem_namespaces.c | 2 +-
9 files changed, 33 insertions(+), 9 deletions(-)
diff --git a/test.h b/test.h
index 1ff350a9c1ba..5f2d6293c104 100644
--- a/test.h
+++ b/test.h
@@ -29,7 +29,8 @@ void builtin_xaction_namespace_reset(void);
struct kmod_ctx;
struct kmod_module;
int nfit_test_init(struct kmod_ctx **ctx, struct kmod_module **mod,
- int log_level, struct ndctl_test *test);
+ struct ndctl_ctx *nd_ctx, int log_level,
+ struct ndctl_test *test);
struct ndctl_ctx;
int test_parent_uuid(int loglevel, struct ndctl_test *test, struct ndctl_ctx *ctx);
diff --git a/test/blk_namespaces.c b/test/blk_namespaces.c
index 7b33bfd0528b..b587ab93fbb8 100644
--- a/test/blk_namespaces.c
+++ b/test/blk_namespaces.c
@@ -239,7 +239,7 @@ int test_blk_namespaces(int log_level, struct ndctl_test *test,
if (!bus) {
fprintf(stderr, "ACPI.NFIT unavailable falling back to nfit_test\n");
- rc = nfit_test_init(&kmod_ctx, &mod, log_level, test);
+ rc = nfit_test_init(&kmod_ctx, &mod, NULL, log_level, test);
ndctl_invalidate(ctx);
bus = ndctl_bus_get_by_provider(ctx, "nfit_test.0");
if (rc < 0 || !bus) {
diff --git a/test/core.c b/test/core.c
index e0806ed24058..ca983e4913f7 100644
--- a/test/core.c
+++ b/test/core.c
@@ -20,6 +20,7 @@
#include <util/log.h>
#include <util/sysfs.h>
+#include <ndctl/libndctl.h>
#include <ccan/array_size/array_size.h>
#define KVER_STRLEN 20
@@ -116,11 +117,13 @@ int ndctl_test_get_skipped(struct ndctl_test *test)
}
int nfit_test_init(struct kmod_ctx **ctx, struct kmod_module **mod,
- int log_level, struct ndctl_test *test)
+ struct ndctl_ctx *nd_ctx, int log_level,
+ struct ndctl_test *test)
{
int rc;
unsigned int i;
const char *name;
+ struct ndctl_bus *bus;
struct log_ctx log_ctx;
const char *list[] = {
"nfit",
@@ -219,6 +222,26 @@ retry:
return rc;
}
+ if (nd_ctx) {
+ /* caller wants a full nfit_test reset */
+ ndctl_bus_foreach(nd_ctx, bus) {
+ struct ndctl_region *region;
+
+ if (strncmp(ndctl_bus_get_provider(bus),
+ "nfit_test", 9) != 0)
+ continue;
+ ndctl_region_foreach(bus, region)
+ ndctl_region_disable_invalidate(region);
+ }
+
+ rc = kmod_module_remove_module(*mod, 0);
+ if (rc < 0 && rc != -ENOENT) {
+ kmod_unref(*ctx);
+ return rc;
+ }
+ ndctl_invalidate(nd_ctx);
+ }
+
rc = kmod_module_probe_insert_module(*mod, KMOD_PROBE_APPLY_BLACKLIST,
NULL, NULL, NULL, NULL);
if (rc)
diff --git a/test/dpa-alloc.c b/test/dpa-alloc.c
index 9ab10f90293a..7793650699da 100644
--- a/test/dpa-alloc.c
+++ b/test/dpa-alloc.c
@@ -287,7 +287,7 @@ int test_dpa_alloc(int loglevel, struct ndctl_test *test, struct ndctl_ctx *ctx)
return 77;
ndctl_set_log_priority(ctx, loglevel);
- err = nfit_test_init(&kmod_ctx, &mod, loglevel, test);
+ err = nfit_test_init(&kmod_ctx, &mod, NULL, loglevel, test);
if (err < 0) {
ndctl_test_skip(test);
fprintf(stderr, "nfit_test unavailable skipping tests\n");
diff --git a/test/dsm-fail.c b/test/dsm-fail.c
index b363decc29c8..90d3e074f12b 100644
--- a/test/dsm-fail.c
+++ b/test/dsm-fail.c
@@ -167,7 +167,7 @@ int test_dsm_fail(int loglevel, struct ndctl_test *test, struct ndctl_ctx *ctx)
int result = EXIT_FAILURE, err;
ndctl_set_log_priority(ctx, loglevel);
- err = nfit_test_init(&kmod_ctx, &mod, loglevel, test);
+ err = nfit_test_init(&kmod_ctx, &mod, NULL, loglevel, test);
if (err < 0) {
result = 77;
ndctl_test_skip(test);
diff --git a/test/libndctl.c b/test/libndctl.c
index b534b640cb8d..b10142ebdee4 100644
--- a/test/libndctl.c
+++ b/test/libndctl.c
@@ -2567,7 +2567,7 @@ int test_libndctl(int loglevel, struct ndctl_test *test, struct ndctl_ctx *ctx)
daxctl_set_log_priority(daxctl_ctx, loglevel);
ndctl_set_private_data(ctx, test);
- err = nfit_test_init(&kmod_ctx, &mod, loglevel, test);
+ err = nfit_test_init(&kmod_ctx, &mod, ctx, loglevel, test);
if (err < 0) {
ndctl_test_skip(test);
fprintf(stderr, "nfit_test unavailable skipping tests\n");
diff --git a/test/multi-pmem.c b/test/multi-pmem.c
index b3054f44b5dd..668662cded25 100644
--- a/test/multi-pmem.c
+++ b/test/multi-pmem.c
@@ -260,7 +260,7 @@ int test_multi_pmem(int loglevel, struct ndctl_test *test, struct ndctl_ctx *ctx
ndctl_set_log_priority(ctx, loglevel);
- err = nfit_test_init(&kmod_ctx, &mod, loglevel, test);
+ err = nfit_test_init(&kmod_ctx, &mod, NULL, loglevel, test);
if (err < 0) {
result = 77;
ndctl_test_skip(test);
diff --git a/test/parent-uuid.c b/test/parent-uuid.c
index 87ea4d75b5a5..3a63f7244e21 100644
--- a/test/parent-uuid.c
+++ b/test/parent-uuid.c
@@ -229,7 +229,7 @@ int test_parent_uuid(int loglevel, struct ndctl_test *test, struct ndctl_ctx *ct
return 77;
ndctl_set_log_priority(ctx, loglevel);
- err = nfit_test_init(&kmod_ctx, &mod, loglevel, test);
+ err = nfit_test_init(&kmod_ctx, &mod, NULL, loglevel, test);
if (err < 0) {
ndctl_test_skip(test);
fprintf(stderr, "nfit_test unavailable skipping tests\n");
diff --git a/test/pmem_namespaces.c b/test/pmem_namespaces.c
index 69e87abc592f..eac56ce25d58 100644
--- a/test/pmem_namespaces.c
+++ b/test/pmem_namespaces.c
@@ -203,7 +203,7 @@ int test_pmem_namespaces(int log_level, struct ndctl_test *test,
if (!bus) {
fprintf(stderr, "ACPI.NFIT unavailable falling back to nfit_test\n");
- rc = nfit_test_init(&kmod_ctx, &mod, log_level, test);
+ rc = nfit_test_init(&kmod_ctx, &mod, NULL, log_level, test);
ndctl_invalidate(ctx);
bus = ndctl_bus_get_by_provider(ctx, "nfit_test.0");
if (rc < 0 || !bus) {
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [ndctl PATCH 09/17] ndctl, region: cleanup error message
2017-12-01 23:24 [ndctl PATCH 00/16] ndctl: update SMART support for NVDIMM_FAMILY_INTEL Dan Williams
` (7 preceding siblings ...)
2017-12-01 23:25 ` [ndctl PATCH 08/17] ndctl, test: reset all nfit_test data for each test/libndctl run Dan Williams
@ 2017-12-01 23:25 ` Dan Williams
2017-12-01 23:25 ` [ndctl PATCH 10/17] ndctl: support set smart alarm/threshold Dan Williams
` (8 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Dan Williams @ 2017-12-01 23:25 UTC (permalink / raw)
To: linux-nvdimm
The general parameter parsing error message in parse_region_options()
was copied from the initial "disable-region" command implementation. Fix
it up to be more general and valid for all region commands.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
ndctl/region.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ndctl/region.c b/ndctl/region.c
index 1402a7548be8..9fc90808e338 100644
--- a/ndctl/region.c
+++ b/ndctl/region.c
@@ -44,7 +44,7 @@ static const char *parse_region_options(int argc, const char **argv,
argc = parse_options(argc, argv, region_options, u, 0);
if (argc == 0)
- error("specify a region to delete, or \"all\"\n");
+ error("specify a specific region id to act on, or \"all\"\n");
for (i = 1; i < argc; i++)
error("unknown extra parameter \"%s\"\n", argv[i]);
if (argc == 0 || argc > 1) {
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [ndctl PATCH 10/17] ndctl: support set smart alarm/threshold
2017-12-01 23:24 [ndctl PATCH 00/16] ndctl: update SMART support for NVDIMM_FAMILY_INTEL Dan Williams
` (8 preceding siblings ...)
2017-12-01 23:25 ` [ndctl PATCH 09/17] ndctl, region: cleanup error message Dan Williams
@ 2017-12-01 23:25 ` Dan Williams
2017-12-01 23:25 ` [ndctl PATCH 11/17] ndctl: refactor 'smart_ops' into generic 'dimm_ops' Dan Williams
` (7 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Dan Williams @ 2017-12-01 23:25 UTC (permalink / raw)
To: linux-nvdimm
libndctl and test support for the ND_INTEL_SMART_SET_THRESHOLD command.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
ndctl/lib/intel.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++-
ndctl/lib/intel.h | 10 ++++++
ndctl/lib/libndctl.sym | 9 +++++
ndctl/lib/private.h | 8 +++++
ndctl/lib/smart.c | 39 +++++++++++++++++++++++
ndctl/libndctl.h | 14 ++++++++
test/libndctl.c | 59 +++++++++++++++++++++++++++++-----
7 files changed, 213 insertions(+), 9 deletions(-)
diff --git a/ndctl/lib/intel.c b/ndctl/lib/intel.c
index 478f379324f5..e9da565dd57d 100644
--- a/ndctl/lib/intel.c
+++ b/ndctl/lib/intel.c
@@ -143,6 +143,7 @@ static unsigned int intel_cmd_smart_get_health(struct ndctl_cmd *cmd)
}
intel_smart_get_field(cmd, media_temperature)
+intel_smart_get_field(cmd, ctrl_temperature)
intel_smart_get_field(cmd, spares)
intel_smart_get_field(cmd, alarm_flags)
intel_smart_get_field(cmd, life_used)
@@ -198,6 +199,7 @@ static unsigned int intel_cmd_smart_threshold_get_alarm_control(
}
intel_smart_threshold_get_field(cmd, media_temperature)
+intel_smart_threshold_get_field(cmd, ctrl_temperature)
intel_smart_threshold_get_field(cmd, spares)
static struct ndctl_cmd *intel_dimm_cmd_new_smart_threshold(
@@ -216,11 +218,77 @@ static struct ndctl_cmd *intel_dimm_cmd_new_smart_threshold(
return cmd;
}
+static struct ndctl_cmd *intel_dimm_cmd_new_smart_set_threshold(
+ struct ndctl_cmd *cmd_thresh)
+{
+ struct ndctl_cmd *cmd;
+ struct nd_intel_smart_threshold *thresh;
+ struct nd_intel_smart_set_threshold *set_thresh;
+
+ BUILD_ASSERT(sizeof(struct nd_intel_smart_set_threshold) == 11);
+
+ if (intel_smart_threshold_valid(cmd_thresh) < 0)
+ return NULL;
+
+ cmd = alloc_intel_cmd(cmd_thresh->dimm, ND_INTEL_SMART_SET_THRESHOLD,
+ offsetof(typeof(*set_thresh), status), 4);
+ if (!cmd)
+ return NULL;
+
+ cmd->source = cmd_thresh;
+ ndctl_cmd_ref(cmd_thresh);
+ set_thresh = &cmd->intel->set_thresh;
+ thresh = &cmd_thresh->intel->thresh;
+ set_thresh->alarm_control = thresh->alarm_control;
+ set_thresh->spares = thresh->spares;
+ set_thresh->media_temperature = thresh->media_temperature;
+ set_thresh->ctrl_temperature = thresh->ctrl_temperature;
+ cmd->firmware_status = &set_thresh->status;
+
+ return cmd;
+}
+
+static int intel_smart_set_threshold_valid(struct ndctl_cmd *cmd)
+{
+ struct nd_pkg_intel *pkg = cmd->intel;
+
+ if (cmd->type != ND_CMD_CALL || cmd->status != 1
+ || pkg->gen.nd_family != NVDIMM_FAMILY_INTEL
+ || pkg->gen.nd_command != ND_INTEL_SMART_SET_THRESHOLD)
+ return -EINVAL;
+ return 0;
+}
+
+#define intel_smart_set_threshold_field(field) \
+static int intel_cmd_smart_threshold_set_##field( \
+ struct ndctl_cmd *cmd, unsigned int val) \
+{ \
+ if (intel_smart_set_threshold_valid(cmd) < 0) \
+ return -EINVAL; \
+ cmd->intel->set_thresh.field = val; \
+ return 0; \
+}
+
+static unsigned int intel_cmd_smart_threshold_get_supported_alarms(
+ struct ndctl_cmd *cmd)
+{
+ if (intel_smart_set_threshold_valid(cmd) < 0)
+ return 0;
+ return ND_SMART_SPARE_TRIP | ND_SMART_MTEMP_TRIP
+ | ND_SMART_CTEMP_TRIP;
+}
+
+intel_smart_set_threshold_field(alarm_control)
+intel_smart_set_threshold_field(spares)
+intel_smart_set_threshold_field(media_temperature)
+intel_smart_set_threshold_field(ctrl_temperature)
+
struct ndctl_smart_ops * const intel_smart_ops = &(struct ndctl_smart_ops) {
.new_smart = intel_dimm_cmd_new_smart,
.smart_get_flags = intel_cmd_smart_get_flags,
.smart_get_health = intel_cmd_smart_get_health,
.smart_get_media_temperature = intel_cmd_smart_get_media_temperature,
+ .smart_get_ctrl_temperature = intel_cmd_smart_get_ctrl_temperature,
.smart_get_spares = intel_cmd_smart_get_spares,
.smart_get_alarm_flags = intel_cmd_smart_get_alarm_flags,
.smart_get_life_used = intel_cmd_smart_get_life_used,
@@ -229,8 +297,21 @@ struct ndctl_smart_ops * const intel_smart_ops = &(struct ndctl_smart_ops) {
.smart_get_vendor_size = intel_cmd_smart_get_vendor_size,
.smart_get_vendor_data = intel_cmd_smart_get_vendor_data,
.new_smart_threshold = intel_dimm_cmd_new_smart_threshold,
- .smart_threshold_get_alarm_control = intel_cmd_smart_threshold_get_alarm_control,
+ .smart_threshold_get_alarm_control
+ = intel_cmd_smart_threshold_get_alarm_control,
.smart_threshold_get_media_temperature
= intel_cmd_smart_threshold_get_media_temperature,
+ .smart_threshold_get_ctrl_temperature
+ = intel_cmd_smart_threshold_get_ctrl_temperature,
.smart_threshold_get_spares = intel_cmd_smart_threshold_get_spares,
+ .new_smart_set_threshold = intel_dimm_cmd_new_smart_set_threshold,
+ .smart_threshold_get_supported_alarms
+ = intel_cmd_smart_threshold_get_supported_alarms,
+ .smart_threshold_set_alarm_control
+ = intel_cmd_smart_threshold_set_alarm_control,
+ .smart_threshold_set_media_temperature
+ = intel_cmd_smart_threshold_set_media_temperature,
+ .smart_threshold_set_ctrl_temperature
+ = intel_cmd_smart_threshold_set_ctrl_temperature,
+ .smart_threshold_set_spares = intel_cmd_smart_threshold_set_spares,
};
diff --git a/ndctl/lib/intel.h b/ndctl/lib/intel.h
index 8cecc02f9ae6..9e6398501531 100644
--- a/ndctl/lib/intel.h
+++ b/ndctl/lib/intel.h
@@ -5,6 +5,7 @@
#define __INTEL_H__
#define ND_INTEL_SMART 1
#define ND_INTEL_SMART_THRESHOLD 2
+#define ND_INTEL_SMART_SET_THRESHOLD 17
#define ND_INTEL_SMART_HEALTH_VALID (1 << 0)
#define ND_INTEL_SMART_SPARES_VALID (1 << 1)
@@ -62,11 +63,20 @@ struct nd_intel_smart_threshold {
};
} __attribute__((packed));
+struct nd_intel_smart_set_threshold {
+ __u16 alarm_control;
+ __u8 spares;
+ __u16 media_temperature;
+ __u16 ctrl_temperature;
+ __u32 status;
+} __attribute__((packed));
+
struct nd_pkg_intel {
struct nd_cmd_pkg gen;
union {
struct nd_intel_smart smart;
struct nd_intel_smart_threshold thresh;
+ struct nd_intel_smart_set_threshold set_thresh;
};
};
#endif /* __INTEL_H__ */
diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym
index b3fab6232df6..6d9a04282c7d 100644
--- a/ndctl/lib/libndctl.sym
+++ b/ndctl/lib/libndctl.sym
@@ -312,4 +312,13 @@ global:
ndctl_bb_get_count;
ndctl_cmd_smart_get_media_temperature;
ndctl_cmd_smart_threshold_get_media_temperature;
+ ndctl_cmd_smart_get_ctrl_temperature;
+ ndctl_cmd_smart_threshold_get_ctrl_temperature;
+ ndctl_dimm_cmd_new_smart_set_threshold;
+ ndctl_cmd_smart_threshold_get_supported_alarms;
+ ndctl_cmd_smart_threshold_set_alarm_control;
+ ndctl_cmd_smart_threshold_set_temperature;
+ ndctl_cmd_smart_threshold_set_media_temperature;
+ ndctl_cmd_smart_threshold_set_ctrl_temperature;
+ ndctl_cmd_smart_threshold_set_spares;
} LIBNDCTL_13;
diff --git a/ndctl/lib/private.h b/ndctl/lib/private.h
index 1b365ae96bfc..5e9f24f2b3c5 100644
--- a/ndctl/lib/private.h
+++ b/ndctl/lib/private.h
@@ -282,6 +282,7 @@ struct ndctl_smart_ops {
unsigned int (*smart_get_flags)(struct ndctl_cmd *);
unsigned int (*smart_get_health)(struct ndctl_cmd *);
unsigned int (*smart_get_media_temperature)(struct ndctl_cmd *);
+ unsigned int (*smart_get_ctrl_temperature)(struct ndctl_cmd *);
unsigned int (*smart_get_spares)(struct ndctl_cmd *);
unsigned int (*smart_get_alarm_flags)(struct ndctl_cmd *);
unsigned int (*smart_get_life_used)(struct ndctl_cmd *);
@@ -292,7 +293,14 @@ struct ndctl_smart_ops {
struct ndctl_cmd *(*new_smart_threshold)(struct ndctl_dimm *);
unsigned int (*smart_threshold_get_alarm_control)(struct ndctl_cmd *);
unsigned int (*smart_threshold_get_media_temperature)(struct ndctl_cmd *);
+ unsigned int (*smart_threshold_get_ctrl_temperature)(struct ndctl_cmd *);
unsigned int (*smart_threshold_get_spares)(struct ndctl_cmd *);
+ struct ndctl_cmd *(*new_smart_set_threshold)(struct ndctl_cmd *);
+ unsigned int (*smart_threshold_get_supported_alarms)(struct ndctl_cmd *);
+ int (*smart_threshold_set_alarm_control)(struct ndctl_cmd *, unsigned int);
+ int (*smart_threshold_set_media_temperature)(struct ndctl_cmd *, unsigned int);
+ int (*smart_threshold_set_ctrl_temperature)(struct ndctl_cmd *, unsigned int);
+ int (*smart_threshold_set_spares)(struct ndctl_cmd *, unsigned int);
};
struct ndctl_smart_ops * const intel_smart_ops;
diff --git a/ndctl/lib/smart.c b/ndctl/lib/smart.c
index 90c45a1a002e..58a6f4bb28ad 100644
--- a/ndctl/lib/smart.c
+++ b/ndctl/lib/smart.c
@@ -40,6 +40,25 @@ NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_cmd_new_smart_threshold(
return NULL;
}
+/*
+ * smart_set_threshold is a read-modify-write command it depends on a
+ * successfully completed smart_threshold command for its defaults.
+ */
+NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_cmd_new_smart_set_threshold(
+ struct ndctl_cmd *cmd)
+{
+ struct ndctl_smart_ops *ops;
+
+ if (!cmd || !cmd->dimm)
+ return NULL;
+ ops = ndctl_dimm_get_smart_ops(cmd->dimm);
+
+ if (ops && ops->new_smart_set_threshold)
+ return ops->new_smart_set_threshold(cmd);
+ else
+ return NULL;
+}
+
#define smart_cmd_op(op, rettype, defretvalue) \
NDCTL_EXPORT rettype ndctl_cmd_##op(struct ndctl_cmd *cmd) \
{ \
@@ -54,6 +73,7 @@ NDCTL_EXPORT rettype ndctl_cmd_##op(struct ndctl_cmd *cmd) \
smart_cmd_op(smart_get_flags, unsigned int, 0)
smart_cmd_op(smart_get_health, unsigned int, 0)
smart_cmd_op(smart_get_media_temperature, unsigned int, 0)
+smart_cmd_op(smart_get_ctrl_temperature, unsigned int, 0)
smart_cmd_op(smart_get_spares, unsigned int, 0)
smart_cmd_op(smart_get_alarm_flags, unsigned int, 0)
smart_cmd_op(smart_get_life_used, unsigned int, 0)
@@ -63,6 +83,7 @@ smart_cmd_op(smart_get_vendor_size, unsigned int, 0)
smart_cmd_op(smart_get_vendor_data, unsigned char *, NULL)
smart_cmd_op(smart_threshold_get_alarm_control, unsigned int, 0)
smart_cmd_op(smart_threshold_get_media_temperature, unsigned int, 0)
+smart_cmd_op(smart_threshold_get_ctrl_temperature, unsigned int, 0)
smart_cmd_op(smart_threshold_get_spares, unsigned int, 0)
NDCTL_EXPORT unsigned int ndctl_cmd_smart_get_temperature(struct ndctl_cmd *cmd)
@@ -75,3 +96,21 @@ NDCTL_EXPORT unsigned int ndctl_cmd_smart_threshold_get_temperature(
{
return ndctl_cmd_smart_threshold_get_media_temperature(cmd);
}
+
+smart_cmd_op(smart_threshold_get_supported_alarms, unsigned int, 0);
+
+#define smart_cmd_set_op(op) \
+NDCTL_EXPORT int ndctl_cmd_##op(struct ndctl_cmd *cmd, unsigned int val) \
+{ \
+ if (cmd->dimm) { \
+ struct ndctl_smart_ops *ops = ndctl_dimm_get_smart_ops(cmd->dimm); \
+ if (ops && ops->op) \
+ return ops->op(cmd, val); \
+ } \
+ return -ENXIO; \
+}
+
+smart_cmd_set_op(smart_threshold_set_alarm_control)
+smart_cmd_set_op(smart_threshold_set_media_temperature)
+smart_cmd_set_op(smart_threshold_set_ctrl_temperature)
+smart_cmd_set_op(smart_threshold_set_spares)
diff --git a/ndctl/libndctl.h b/ndctl/libndctl.h
index a2b3148dbb27..69333443ee78 100644
--- a/ndctl/libndctl.h
+++ b/ndctl/libndctl.h
@@ -230,6 +230,7 @@ unsigned int ndctl_cmd_smart_get_flags(struct ndctl_cmd *cmd);
unsigned int ndctl_cmd_smart_get_health(struct ndctl_cmd *cmd);
unsigned int ndctl_cmd_smart_get_temperature(struct ndctl_cmd *cmd);
unsigned int ndctl_cmd_smart_get_media_temperature(struct ndctl_cmd *cmd);
+unsigned int ndctl_cmd_smart_get_ctrl_temperature(struct ndctl_cmd *cmd);
unsigned int ndctl_cmd_smart_get_spares(struct ndctl_cmd *cmd);
unsigned int ndctl_cmd_smart_get_alarm_flags(struct ndctl_cmd *cmd);
unsigned int ndctl_cmd_smart_get_life_used(struct ndctl_cmd *cmd);
@@ -241,7 +242,20 @@ struct ndctl_cmd *ndctl_dimm_cmd_new_smart_threshold(struct ndctl_dimm *dimm);
unsigned int ndctl_cmd_smart_threshold_get_alarm_control(struct ndctl_cmd *cmd);
unsigned int ndctl_cmd_smart_threshold_get_temperature(struct ndctl_cmd *cmd);
unsigned int ndctl_cmd_smart_threshold_get_media_temperature(struct ndctl_cmd *cmd);
+unsigned int ndctl_cmd_smart_threshold_get_ctrl_temperature(struct ndctl_cmd *cmd);
unsigned int ndctl_cmd_smart_threshold_get_spares(struct ndctl_cmd *cmd);
+struct ndctl_cmd *ndctl_dimm_cmd_new_smart_set_threshold(struct ndctl_cmd *cmd);
+unsigned int ndctl_cmd_smart_threshold_get_supported_alarms(struct ndctl_cmd *cmd);
+int ndctl_cmd_smart_threshold_set_alarm_control(struct ndctl_cmd *cmd,
+ unsigned int val);
+int ndctl_cmd_smart_threshold_set_temperature(struct ndctl_cmd *cmd,
+ unsigned int val);
+int ndctl_cmd_smart_threshold_set_media_temperature(struct ndctl_cmd *cmd,
+ unsigned int val);
+int ndctl_cmd_smart_threshold_set_ctrl_temperature(struct ndctl_cmd *cmd,
+ unsigned int val);
+int ndctl_cmd_smart_threshold_set_spares(struct ndctl_cmd *cmd,
+ unsigned int val);
struct ndctl_cmd *ndctl_dimm_cmd_new_vendor_specific(struct ndctl_dimm *dimm,
unsigned int opcode, size_t input_size, size_t output_size);
diff --git a/test/libndctl.c b/test/libndctl.c
index b10142ebdee4..27de24baca88 100644
--- a/test/libndctl.c
+++ b/test/libndctl.c
@@ -2182,7 +2182,7 @@ static int check_smart(struct ndctl_bus *bus, struct ndctl_dimm *dimm,
__check_smart(dimm, cmd, shutdown_state);
__check_smart(dimm, cmd, vendor_size);
- ndctl_cmd_unref(cmd);
+ check->cmd = cmd;
return 0;
}
@@ -2203,7 +2203,7 @@ static int check_smart(struct ndctl_bus *bus, struct ndctl_dimm *dimm,
* smart_threshold parameters.
*/
struct smart_threshold {
- unsigned int alarm_control, temperature, spares;
+ unsigned int alarm_control, media_temperature, ctrl_temperature, spares;
};
static int check_smart_threshold(struct ndctl_bus *bus, struct ndctl_dimm *dimm,
@@ -2211,10 +2211,13 @@ static int check_smart_threshold(struct ndctl_bus *bus, struct ndctl_dimm *dimm,
{
static const struct smart_threshold smart_t_data = {
.alarm_control = ND_SMART_SPARE_TRIP | ND_SMART_TEMP_TRIP,
- .temperature = 40 * 16,
+ .media_temperature = 40 * 16,
+ .ctrl_temperature = 30 * 16,
.spares = 5,
};
struct ndctl_cmd *cmd = ndctl_dimm_cmd_new_smart_threshold(dimm);
+ struct ndctl_cmd *cmd_smart = check_cmds[ND_CMD_SMART].cmd;
+ struct ndctl_cmd *cmd_set;
struct timeval tm;
char buf[4096];
fd_set fds;
@@ -2249,7 +2252,7 @@ static int check_smart_threshold(struct ndctl_bus *bus, struct ndctl_dimm *dimm,
if (pid == 0) {
FD_ZERO(&fds);
FD_SET(fd, &fds);
- tm.tv_sec = 1;
+ tm.tv_sec = 5;
tm.tv_usec = 0;
rc = select(fd + 1, NULL, NULL, &fds, &tm);
if (rc != 1 || !FD_ISSET(fd, &fds))
@@ -2267,6 +2270,50 @@ static int check_smart_threshold(struct ndctl_bus *bus, struct ndctl_dimm *dimm,
return rc;
}
+ __check_smart_threshold(dimm, cmd, alarm_control);
+ __check_smart_threshold(dimm, cmd, media_temperature);
+ __check_smart_threshold(dimm, cmd, ctrl_temperature);
+ __check_smart_threshold(dimm, cmd, spares);
+
+ /*
+ * The same kernel change that adds nfit_test support for this
+ * command is the same change that moves notifications to
+ * require set_threshold. If we fail to get a command, but the
+ * notification fires then we are on an old kernel, otherwise
+ * whether old kernel or new kernel the notification should
+ * fire.
+ */
+ cmd_set = ndctl_dimm_cmd_new_smart_set_threshold(cmd);
+ if (cmd_set) {
+ /*
+ * Set all thresholds to match current values and set
+ * all alarms.
+ */
+ rc = ndctl_cmd_smart_threshold_set_alarm_control(cmd_set,
+ ndctl_cmd_smart_threshold_get_supported_alarms(cmd_set));
+ rc |= ndctl_cmd_smart_threshold_set_media_temperature(cmd_set,
+ ndctl_cmd_smart_get_media_temperature(cmd_smart));
+ rc |= ndctl_cmd_smart_threshold_set_ctrl_temperature(cmd_set,
+ ndctl_cmd_smart_get_ctrl_temperature(cmd_smart));
+ rc |= ndctl_cmd_smart_threshold_set_spares(cmd_set,
+ ndctl_cmd_smart_get_spares(cmd_smart));
+ if (rc) {
+ fprintf(stderr, "%s: failed set threshold parameters\n",
+ __func__);
+ ndctl_cmd_unref(cmd_set);
+ return -ENXIO;
+ }
+
+ rc = ndctl_cmd_submit(cmd_set);
+ if (rc) {
+ fprintf(stderr, "%s: dimm: %#x failed to submit cmd_set: %d\n",
+ __func__, ndctl_dimm_get_handle(dimm), rc);
+ ndctl_cmd_unref(cmd_set);
+ return rc;
+ }
+ ndctl_cmd_unref(cmd_set);
+ }
+
if (ndctl_test_attempt(check->test, KERNEL_VERSION(4, 9, 0))) {
wait(&rc);
if (WEXITSTATUS(rc) == EXIT_FAILURE) {
@@ -2276,10 +2323,6 @@ static int check_smart_threshold(struct ndctl_bus *bus, struct ndctl_dimm *dimm,
}
}
- __check_smart_threshold(dimm, cmd, alarm_control);
- __check_smart_threshold(dimm, cmd, temperature);
- __check_smart_threshold(dimm, cmd, spares);
-
ndctl_cmd_unref(cmd);
return 0;
}
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [ndctl PATCH 11/17] ndctl: refactor 'smart_ops' into generic 'dimm_ops'
2017-12-01 23:24 [ndctl PATCH 00/16] ndctl: update SMART support for NVDIMM_FAMILY_INTEL Dan Williams
` (9 preceding siblings ...)
2017-12-01 23:25 ` [ndctl PATCH 10/17] ndctl: support set smart alarm/threshold Dan Williams
@ 2017-12-01 23:25 ` Dan Williams
2017-12-01 23:25 ` [ndctl PATCH 12/17] ndctl, debug: improve do_cmd output for ND_CMD_CALL Dan Williams
` (6 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Dan Williams @ 2017-12-01 23:25 UTC (permalink / raw)
To: linux-nvdimm
There are cases beyond SMART commands where we need to generically ask
the per-family provider for more information, or take some NVDIMM-family
specific action. Rename smart_ops to dimm_ops.
This also cleans up ndctl_dimm_get_smart_ops() to be open coded
("dimm->ops"). The NDCTL_EXPORT on the previous symbol name was
invalidated by the fact that ndctl/lib/libndctl.sym never listed the
symbol.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
ndctl/lib/hpe1.c | 2 +-
ndctl/lib/intel.c | 2 +-
ndctl/lib/libndctl.c | 11 +++--------
ndctl/lib/msft.c | 2 +-
ndctl/lib/private.h | 10 +++++-----
ndctl/lib/smart.c | 16 +++++++++-------
ndctl/libndctl.h | 1 -
7 files changed, 20 insertions(+), 24 deletions(-)
diff --git a/ndctl/lib/hpe1.c b/ndctl/lib/hpe1.c
index 81f60ab27a07..dbc1ff06737e 100644
--- a/ndctl/lib/hpe1.c
+++ b/ndctl/lib/hpe1.c
@@ -296,7 +296,7 @@ static unsigned int hpe1_cmd_smart_threshold_get_spares(struct ndctl_cmd *cmd)
return CMD_HPE1_SMART_THRESH(cmd)->spare_block_threshold;
}
-struct ndctl_smart_ops * const hpe1_smart_ops = &(struct ndctl_smart_ops) {
+struct ndctl_dimm_ops * const hpe1_dimm_ops = &(struct ndctl_dimm_ops) {
.new_smart = hpe1_dimm_cmd_new_smart,
.smart_get_flags = hpe1_cmd_smart_get_flags,
.smart_get_health = hpe1_cmd_smart_get_health,
diff --git a/ndctl/lib/intel.c b/ndctl/lib/intel.c
index e9da565dd57d..af13c60d4f52 100644
--- a/ndctl/lib/intel.c
+++ b/ndctl/lib/intel.c
@@ -283,7 +283,7 @@ intel_smart_set_threshold_field(spares)
intel_smart_set_threshold_field(media_temperature)
intel_smart_set_threshold_field(ctrl_temperature)
-struct ndctl_smart_ops * const intel_smart_ops = &(struct ndctl_smart_ops) {
+struct ndctl_dimm_ops * const intel_dimm_ops = &(struct ndctl_dimm_ops) {
.new_smart = intel_dimm_cmd_new_smart,
.smart_get_flags = intel_cmd_smart_get_flags,
.smart_get_health = intel_cmd_smart_get_health,
diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c
index 47ba2807495e..d6d8a7f0c0b3 100644
--- a/ndctl/lib/libndctl.c
+++ b/ndctl/lib/libndctl.c
@@ -1301,11 +1301,11 @@ static void *add_dimm(void *parent, int id, const char *dimm_base)
if (sysfs_read_attr(ctx, path, buf) == 0)
dimm->cmd_family = strtoul(buf, NULL, 0);
if (dimm->cmd_family == NVDIMM_FAMILY_INTEL)
- dimm->smart_ops = intel_smart_ops;
+ dimm->ops = intel_dimm_ops;
if (dimm->cmd_family == NVDIMM_FAMILY_HPE1)
- dimm->smart_ops = hpe1_smart_ops;
+ dimm->ops = hpe1_dimm_ops;
if (dimm->cmd_family == NVDIMM_FAMILY_MSFT)
- dimm->smart_ops = msft_smart_ops;
+ dimm->ops = msft_dimm_ops;
sprintf(path, "%s/nfit/dsm_mask", dimm_base);
if (sysfs_read_attr(ctx, path, buf) == 0)
@@ -1563,11 +1563,6 @@ NDCTL_EXPORT struct ndctl_bus *ndctl_dimm_get_bus(struct ndctl_dimm *dimm)
return dimm->bus;
}
-NDCTL_EXPORT struct ndctl_smart_ops *ndctl_dimm_get_smart_ops(struct ndctl_dimm *dimm)
-{
- return dimm->smart_ops;
-}
-
NDCTL_EXPORT struct ndctl_ctx *ndctl_dimm_get_ctx(struct ndctl_dimm *dimm)
{
return dimm->bus->ctx;
diff --git a/ndctl/lib/msft.c b/ndctl/lib/msft.c
index d61c065e752d..e15bc076a6c2 100644
--- a/ndctl/lib/msft.c
+++ b/ndctl/lib/msft.c
@@ -136,7 +136,7 @@ static unsigned int msft_cmd_smart_get_life_used(struct ndctl_cmd *cmd)
return 100 - CMD_MSFT_SMART(cmd)->nvm_lifetime;
}
-struct ndctl_smart_ops * const msft_smart_ops = &(struct ndctl_smart_ops) {
+struct ndctl_dimm_ops * const msft_dimm_ops = &(struct ndctl_dimm_ops) {
.new_smart = msft_dimm_cmd_new_smart,
.smart_get_flags = msft_cmd_smart_get_flags,
.smart_get_health = msft_cmd_smart_get_health,
diff --git a/ndctl/lib/private.h b/ndctl/lib/private.h
index 5e9f24f2b3c5..490de96f6ce6 100644
--- a/ndctl/lib/private.h
+++ b/ndctl/lib/private.h
@@ -61,7 +61,7 @@ struct nvdimm_data {
struct ndctl_dimm {
struct kmod_module *module;
struct ndctl_bus *bus;
- struct ndctl_smart_ops *smart_ops;
+ struct ndctl_dimm_ops *ops;
struct nvdimm_data ndd;
unsigned int handle, major, minor, serial;
unsigned short phys_id;
@@ -277,7 +277,7 @@ struct ndctl_bb {
struct list_node list;
};
-struct ndctl_smart_ops {
+struct ndctl_dimm_ops {
struct ndctl_cmd *(*new_smart)(struct ndctl_dimm *);
unsigned int (*smart_get_flags)(struct ndctl_cmd *);
unsigned int (*smart_get_health)(struct ndctl_cmd *);
@@ -303,9 +303,9 @@ struct ndctl_smart_ops {
int (*smart_threshold_set_spares)(struct ndctl_cmd *, unsigned int);
};
-struct ndctl_smart_ops * const intel_smart_ops;
-struct ndctl_smart_ops * const hpe1_smart_ops;
-struct ndctl_smart_ops * const msft_smart_ops;
+struct ndctl_dimm_ops * const intel_dimm_ops;
+struct ndctl_dimm_ops * const hpe1_dimm_ops;
+struct ndctl_dimm_ops * const msft_dimm_ops;
static inline struct ndctl_bus *cmd_to_bus(struct ndctl_cmd *cmd)
{
diff --git a/ndctl/lib/smart.c b/ndctl/lib/smart.c
index 58a6f4bb28ad..846030e70e92 100644
--- a/ndctl/lib/smart.c
+++ b/ndctl/lib/smart.c
@@ -17,13 +17,14 @@
#include "private.h"
/*
- * Define the wrappers around the ndctl_smart_ops:
+ * Define the wrappers around the ndctl_dimm_ops:
*/
NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_cmd_new_smart(
struct ndctl_dimm *dimm)
{
- struct ndctl_smart_ops *ops = ndctl_dimm_get_smart_ops(dimm);
+ struct ndctl_dimm_ops *ops = dimm->ops;
+
if (ops && ops->new_smart)
return ops->new_smart(dimm);
else
@@ -33,7 +34,8 @@ NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_cmd_new_smart(
NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_cmd_new_smart_threshold(
struct ndctl_dimm *dimm)
{
- struct ndctl_smart_ops *ops = ndctl_dimm_get_smart_ops(dimm);
+ struct ndctl_dimm_ops *ops = dimm->ops;
+
if (ops && ops->new_smart_threshold)
return ops->new_smart_threshold(dimm);
else
@@ -47,11 +49,11 @@ NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_cmd_new_smart_threshold(
NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_cmd_new_smart_set_threshold(
struct ndctl_cmd *cmd)
{
- struct ndctl_smart_ops *ops;
+ struct ndctl_dimm_ops *ops;
if (!cmd || !cmd->dimm)
return NULL;
- ops = ndctl_dimm_get_smart_ops(cmd->dimm);
+ ops = cmd->dimm->ops;
if (ops && ops->new_smart_set_threshold)
return ops->new_smart_set_threshold(cmd);
@@ -63,7 +65,7 @@ NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_cmd_new_smart_set_threshold(
NDCTL_EXPORT rettype ndctl_cmd_##op(struct ndctl_cmd *cmd) \
{ \
if (cmd->dimm) { \
- struct ndctl_smart_ops *ops = ndctl_dimm_get_smart_ops(cmd->dimm); \
+ struct ndctl_dimm_ops *ops = cmd->dimm->ops; \
if (ops && ops->op) \
return ops->op(cmd); \
} \
@@ -103,7 +105,7 @@ smart_cmd_op(smart_threshold_get_supported_alarms, unsigned int, 0);
NDCTL_EXPORT int ndctl_cmd_##op(struct ndctl_cmd *cmd, unsigned int val) \
{ \
if (cmd->dimm) { \
- struct ndctl_smart_ops *ops = ndctl_dimm_get_smart_ops(cmd->dimm); \
+ struct ndctl_dimm_ops *ops = cmd->dimm->ops; \
if (ops && ops->op) \
return ops->op(cmd, val); \
} \
diff --git a/ndctl/libndctl.h b/ndctl/libndctl.h
index 69333443ee78..0dfd373e7897 100644
--- a/ndctl/libndctl.h
+++ b/ndctl/libndctl.h
@@ -162,7 +162,6 @@ unsigned int ndctl_dimm_handle_get_channel(struct ndctl_dimm *dimm);
unsigned int ndctl_dimm_handle_get_dimm(struct ndctl_dimm *dimm);
const char *ndctl_dimm_get_devname(struct ndctl_dimm *dimm);
struct ndctl_bus *ndctl_dimm_get_bus(struct ndctl_dimm *dimm);
-struct ndctl_smart_ops *ndctl_dimm_get_smart_ops(struct ndctl_dimm *dimm);
struct ndctl_ctx *ndctl_dimm_get_ctx(struct ndctl_dimm *dimm);
struct ndctl_dimm *ndctl_dimm_get_by_handle(struct ndctl_bus *bus,
unsigned int handle);
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [ndctl PATCH 12/17] ndctl, debug: improve do_cmd output for ND_CMD_CALL
2017-12-01 23:24 [ndctl PATCH 00/16] ndctl: update SMART support for NVDIMM_FAMILY_INTEL Dan Williams
` (10 preceding siblings ...)
2017-12-01 23:25 ` [ndctl PATCH 11/17] ndctl: refactor 'smart_ops' into generic 'dimm_ops' Dan Williams
@ 2017-12-01 23:25 ` Dan Williams
2017-12-01 23:25 ` [ndctl PATCH 13/17] ndctl, list: teach the list command about the 'fsdax' and 'devdax' modes Dan Williams
` (5 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Dan Williams @ 2017-12-01 23:25 UTC (permalink / raw)
To: linux-nvdimm
Call back to a per-dimm-family operation that can provide a text
description for the function number passed in ND_CMD_CALL invocations.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
ndctl/lib/intel.c | 17 +++++++++++++++++
ndctl/lib/libndctl.c | 37 +++++++++++++++++++++++++------------
ndctl/lib/private.h | 2 ++
3 files changed, 44 insertions(+), 12 deletions(-)
diff --git a/ndctl/lib/intel.c b/ndctl/lib/intel.c
index af13c60d4f52..3e4260f9dbd1 100644
--- a/ndctl/lib/intel.c
+++ b/ndctl/lib/intel.c
@@ -283,7 +283,24 @@ intel_smart_set_threshold_field(spares)
intel_smart_set_threshold_field(media_temperature)
intel_smart_set_threshold_field(ctrl_temperature)
+static const char *intel_cmd_desc(int fn)
+{
+ static const char *descs[] = {
+ [ND_INTEL_SMART] = "smart",
+ [ND_INTEL_SMART_THRESHOLD] = "smart_thresh",
+ [ND_INTEL_SMART_SET_THRESHOLD] = "smart_set_thresh",
+ };
+ const char *desc = descs[fn];
+
+ if (fn >= (int) ARRAY_SIZE(descs))
+ return "unknown";
+ if (!desc)
+ return "unknown";
+ return desc;
+}
+
struct ndctl_dimm_ops * const intel_dimm_ops = &(struct ndctl_dimm_ops) {
+ .cmd_desc = intel_cmd_desc,
.new_smart = intel_dimm_cmd_new_smart,
.smart_get_flags = intel_cmd_smart_get_flags,
.smart_get_health = intel_cmd_smart_get_health,
diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c
index d6d8a7f0c0b3..8471dd8c4f89 100644
--- a/ndctl/lib/libndctl.c
+++ b/ndctl/lib/libndctl.c
@@ -2372,26 +2372,39 @@ static int to_ioctl_cmd(int cmd, int dimm)
}
}
+static const char *ndctl_dimm_get_cmd_subname(struct ndctl_cmd *cmd)
+{
+ struct ndctl_dimm *dimm = cmd->dimm;
+ struct ndctl_dimm_ops *ops = dimm ? dimm->ops : NULL;
+
+ if (!dimm || cmd->type != ND_CMD_CALL || !ops || !ops->cmd_desc)
+ return NULL;
+ return ops->cmd_desc(cmd->pkg->nd_command);
+}
+
static int do_cmd(int fd, int ioctl_cmd, struct ndctl_cmd *cmd)
{
int rc;
u32 offset;
- const char *name;
+ const char *name, *sub_name = NULL;
+ struct ndctl_dimm *dimm = cmd->dimm;
struct ndctl_bus *bus = cmd_to_bus(cmd);
struct ndctl_cmd_iter *iter = &cmd->iter;
struct ndctl_ctx *ctx = ndctl_bus_get_ctx(bus);
- if (cmd->dimm)
- name = ndctl_dimm_get_cmd_name(cmd->dimm, cmd->type);
- else
+ if (dimm) {
+ name = ndctl_dimm_get_cmd_name(dimm, cmd->type);
+ sub_name = ndctl_dimm_get_cmd_subname(cmd);
+ } else
name = ndctl_bus_get_cmd_name(cmd->bus, cmd->type);
+
if (iter->total_xfer == 0) {
rc = ioctl(fd, ioctl_cmd, cmd->cmd_buf);
- dbg(ctx, "bus: %d dimm: %#x cmd: %s status: %d fw: %d (%s)\n",
- bus->id, cmd->dimm
- ? ndctl_dimm_get_handle(cmd->dimm) : 0,
- name, rc, *(cmd->firmware_status), rc < 0 ?
+ dbg(ctx, "bus: %d dimm: %#x cmd: %s%s%s status: %d fw: %d (%s)\n",
+ bus->id, dimm ? ndctl_dimm_get_handle(dimm) : 0,
+ name, sub_name ? ":" : "", sub_name ? sub_name : "",
+ rc, *(cmd->firmware_status), rc < 0 ?
strerror(errno) : "success");
if (rc < 0)
return -errno;
@@ -2421,10 +2434,10 @@ static int do_cmd(int fd, int ioctl_cmd, struct ndctl_cmd *cmd)
}
}
- dbg(ctx, "bus: %d dimm: %#x cmd: %s total: %d max_xfer: %d status: %d fw: %d (%s)\n",
- bus->id,
- cmd->dimm ? ndctl_dimm_get_handle(cmd->dimm) : 0,
- name, iter->total_xfer, iter->max_xfer, rc,
+ dbg(ctx, "bus: %d dimm: %#x cmd: %s%s%s total: %d max_xfer: %d status: %d fw: %d (%s)\n",
+ bus->id, dimm ? ndctl_dimm_get_handle(dimm) : 0,
+ name, sub_name ? ":" : "", sub_name ? sub_name : "",
+ iter->total_xfer, iter->max_xfer, rc,
*(cmd->firmware_status),
rc < 0 ? strerror(errno) : "success");
diff --git a/ndctl/lib/private.h b/ndctl/lib/private.h
index 490de96f6ce6..67260970bfb2 100644
--- a/ndctl/lib/private.h
+++ b/ndctl/lib/private.h
@@ -260,6 +260,7 @@ struct ndctl_cmd {
struct nd_cmd_ars_start ars_start[0];
struct nd_cmd_ars_status ars_status[0];
struct nd_cmd_clear_error clear_err[0];
+ struct nd_cmd_pkg pkg[0];
struct ndn_pkg_hpe1 hpe1[0];
struct ndn_pkg_msft msft[0];
struct nd_pkg_intel intel[0];
@@ -278,6 +279,7 @@ struct ndctl_bb {
};
struct ndctl_dimm_ops {
+ const char *(*cmd_desc)(int);
struct ndctl_cmd *(*new_smart)(struct ndctl_dimm *);
unsigned int (*smart_get_flags)(struct ndctl_cmd *);
unsigned int (*smart_get_health)(struct ndctl_cmd *);
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [ndctl PATCH 13/17] ndctl, list: teach the list command about the 'fsdax' and 'devdax' modes
2017-12-01 23:24 [ndctl PATCH 00/16] ndctl: update SMART support for NVDIMM_FAMILY_INTEL Dan Williams
` (11 preceding siblings ...)
2017-12-01 23:25 ` [ndctl PATCH 12/17] ndctl, debug: improve do_cmd output for ND_CMD_CALL Dan Williams
@ 2017-12-01 23:25 ` Dan Williams
2017-12-01 23:25 ` [ndctl PATCH 14/17] ndctl, smart: move smart temperature parsing to a library routine Dan Williams
` (4 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Dan Williams @ 2017-12-01 23:25 UTC (permalink / raw)
To: linux-nvdimm
Allow filtering namespaces by the same mode names used for
create-namespace.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
Documentation/ndctl/ndctl-list.txt | 2 +-
ndctl/list.c | 4 ++++
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/Documentation/ndctl/ndctl-list.txt b/Documentation/ndctl/ndctl-list.txt
index e19ded8a3ec2..fc07a71ff640 100644
--- a/Documentation/ndctl/ndctl-list.txt
+++ b/Documentation/ndctl/ndctl-list.txt
@@ -80,7 +80,7 @@ include::xable-region-options.txt[]
-m::
--mode=::
- Filter listing by the mode ('raw', 'memory', 'sector' or 'dax')
+ Filter listing by the mode ('raw', 'fsdax', 'sector' or 'devdax')
of the namespace(s).
-B::
diff --git a/ndctl/list.c b/ndctl/list.c
index d6e49b03a265..37a224a666ca 100644
--- a/ndctl/list.c
+++ b/ndctl/list.c
@@ -78,12 +78,16 @@ static enum ndctl_namespace_mode mode_to_type(const char *mode)
if (strcasecmp(param.mode, "memory") == 0)
return NDCTL_NS_MODE_MEMORY;
+ else if (strcasecmp(param.mode, "fsdax") == 0)
+ return NDCTL_NS_MODE_MEMORY;
else if (strcasecmp(param.mode, "sector") == 0)
return NDCTL_NS_MODE_SAFE;
else if (strcasecmp(param.mode, "safe") == 0)
return NDCTL_NS_MODE_SAFE;
else if (strcasecmp(param.mode, "dax") == 0)
return NDCTL_NS_MODE_DAX;
+ else if (strcasecmp(param.mode, "devdax") == 0)
+ return NDCTL_NS_MODE_DAX;
else if (strcasecmp(param.mode, "raw") == 0)
return NDCTL_NS_MODE_RAW;
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [ndctl PATCH 14/17] ndctl, smart: move smart temperature parsing to a library routine
2017-12-01 23:24 [ndctl PATCH 00/16] ndctl: update SMART support for NVDIMM_FAMILY_INTEL Dan Williams
` (12 preceding siblings ...)
2017-12-01 23:25 ` [ndctl PATCH 13/17] ndctl, list: teach the list command about the 'fsdax' and 'devdax' modes Dan Williams
@ 2017-12-01 23:25 ` Dan Williams
2017-12-01 23:25 ` [ndctl PATCH 15/17] ndctl, test: trigger notifications Dan Williams
` (3 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Dan Williams @ 2017-12-01 23:25 UTC (permalink / raw)
To: linux-nvdimm
Similar to the 'ndctl list' command, consumers of the smart apis need to
be able to convert the encoded smart temperature to a number.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
ndctl/lib/libndctl.c | 13 +++++++++++++
ndctl/lib/libndctl.sym | 1 +
ndctl/libndctl.h | 1 +
ndctl/util/json-smart.c | 17 ++---------------
4 files changed, 17 insertions(+), 15 deletions(-)
diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c
index 8471dd8c4f89..01788f47fbd0 100644
--- a/ndctl/lib/libndctl.c
+++ b/ndctl/lib/libndctl.c
@@ -74,6 +74,19 @@ NDCTL_EXPORT size_t ndctl_sizeof_namespace_label(void)
return offsetof(struct namespace_label, type_guid);
}
+NDCTL_EXPORT double ndctl_decode_smart_temperature(unsigned int temp)
+{
+ bool negative = !!(temp & (1 << 15));
+ double t;
+
+ temp &= ~(1 << 15);
+ t = temp;
+ t /= 16;
+ if (negative)
+ t *= -1;
+ return t;
+}
+
struct ndctl_ctx;
/**
diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym
index 6d9a04282c7d..2ace9420b158 100644
--- a/ndctl/lib/libndctl.sym
+++ b/ndctl/lib/libndctl.sym
@@ -321,4 +321,5 @@ global:
ndctl_cmd_smart_threshold_set_media_temperature;
ndctl_cmd_smart_threshold_set_ctrl_temperature;
ndctl_cmd_smart_threshold_set_spares;
+ ndctl_decode_smart_temperature;
} LIBNDCTL_13;
diff --git a/ndctl/libndctl.h b/ndctl/libndctl.h
index 0dfd373e7897..e9da20e57f32 100644
--- a/ndctl/libndctl.h
+++ b/ndctl/libndctl.h
@@ -74,6 +74,7 @@ extern "C" {
size_t ndctl_min_namespace_size(void);
size_t ndctl_sizeof_namespace_index(void);
size_t ndctl_sizeof_namespace_label(void);
+double ndctl_decode_smart_temperature(unsigned int temp);
struct ndctl_ctx;
struct ndctl_ctx *ndctl_ref(struct ndctl_ctx *ctx);
diff --git a/ndctl/util/json-smart.c b/ndctl/util/json-smart.c
index 7aabf4f3aebe..4020423bb8c8 100644
--- a/ndctl/util/json-smart.c
+++ b/ndctl/util/json-smart.c
@@ -18,19 +18,6 @@
#include <ccan/array_size/array_size.h>
#include <ndctl.h>
-static double parse_smart_temperature(unsigned int temp)
-{
- bool negative = !!(temp & (1 << 15));
- double t;
-
- temp &= ~(1 << 15);
- t = temp;
- t /= 16;
- if (negative)
- t *= -1;
- return t;
-}
-
static void smart_threshold_to_json(struct ndctl_dimm *dimm,
struct json_object *jhealth)
{
@@ -53,7 +40,7 @@ static void smart_threshold_to_json(struct ndctl_dimm *dimm,
double t;
temp = ndctl_cmd_smart_threshold_get_temperature(cmd);
- t = parse_smart_temperature(temp);
+ t = ndctl_decode_smart_temperature(temp);
jobj = json_object_new_double(t);
if (jobj)
json_object_object_add(jhealth,
@@ -115,7 +102,7 @@ struct json_object *util_dimm_health_to_json(struct ndctl_dimm *dimm)
if (flags & ND_SMART_TEMP_VALID) {
unsigned int temp = ndctl_cmd_smart_get_temperature(cmd);
- double t = parse_smart_temperature(temp);
+ double t = ndctl_decode_smart_temperature(temp);
jobj = json_object_new_double(t);
if (jobj)
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [ndctl PATCH 15/17] ndctl, test: trigger notifications
2017-12-01 23:24 [ndctl PATCH 00/16] ndctl: update SMART support for NVDIMM_FAMILY_INTEL Dan Williams
` (13 preceding siblings ...)
2017-12-01 23:25 ` [ndctl PATCH 14/17] ndctl, smart: move smart temperature parsing to a library routine Dan Williams
@ 2017-12-01 23:25 ` Dan Williams
2017-12-01 23:25 ` [ndctl PATCH 16/17] ndctl, test: listen for smart notifications Dan Williams
` (2 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Dan Williams @ 2017-12-01 23:25 UTC (permalink / raw)
To: linux-nvdimm
Provide a standalone test that can be run against any nvdimm bus to try
to trigger SMART notifications.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
test/Makefile.am | 4 +
test/smart-notify.c | 220 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 224 insertions(+)
create mode 100644 test/smart-notify.c
diff --git a/test/Makefile.am b/test/Makefile.am
index 6698d6cfbab5..85736c3cce09 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -25,6 +25,7 @@ check_PROGRAMS =\
parent-uuid \
multi-pmem \
dax-errors \
+ smart-notify \
daxdev-errors
if ENABLE_DESTRUCTIVE
@@ -100,6 +101,9 @@ device_dax_LDADD = \
$(JSON_LIBS) \
../libutil.a
+smart_notify_SOURCES = smart-notify.c
+smart_notify_LDADD = $(LIBNDCTL_LIB)
+
multi_pmem_SOURCES = \
multi-pmem.c \
$(testcore) \
diff --git a/test/smart-notify.c b/test/smart-notify.c
new file mode 100644
index 000000000000..24e9a213836b
--- /dev/null
+++ b/test/smart-notify.c
@@ -0,0 +1,220 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2017 Intel Corporation. All rights reserved. */
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <stdlib.h>
+#include <ndctl/libndctl.h>
+
+static void do_notify(struct ndctl_dimm *dimm)
+{
+ struct ndctl_cmd *s_cmd = ndctl_dimm_cmd_new_smart(dimm);
+ struct ndctl_cmd *st_cmd = NULL, *sst_cmd = NULL;
+ unsigned int orig_mtemp, orig_ctemp, orig_spare;
+ const char *name = ndctl_dimm_get_devname(dimm);
+ unsigned int alarm, mtemp, ctemp, spare, valid;
+ int rc, i;
+
+ if (!s_cmd) {
+ fprintf(stderr, "%s: no smart command support\n", name);
+ goto out;
+ }
+
+ rc = ndctl_cmd_submit(s_cmd);
+ if (rc) {
+ fprintf(stderr, "%s: smart command failed: %d %s\n", name,
+ rc, strerror(errno));
+ goto out;
+ }
+
+ valid = ndctl_cmd_smart_get_flags(s_cmd);
+ alarm = ndctl_cmd_smart_get_alarm_flags(s_cmd);
+ mtemp = ndctl_cmd_smart_get_media_temperature(s_cmd);
+ ctemp = ndctl_cmd_smart_get_ctrl_temperature(s_cmd);
+ spare = ndctl_cmd_smart_get_spares(s_cmd);
+ fprintf(stderr, "%s: (smart) alarm%s: %#x mtemp%s: %.2f ctemp%s: %.2f spares%s: %d\n",
+ name,
+ valid & ND_SMART_ALARM_VALID ? "" : "(invalid)", alarm,
+ valid & ND_SMART_MTEMP_VALID ? "" : "(invalid)",
+ ndctl_decode_smart_temperature(mtemp),
+ valid & ND_SMART_CTEMP_VALID ? "" : "(invalid)",
+ ndctl_decode_smart_temperature(ctemp),
+ valid & ND_SMART_SPARES_VALID ? "" : "(invalid)", spare);
+
+ st_cmd = ndctl_dimm_cmd_new_smart_threshold(dimm);
+ if (!st_cmd) {
+ fprintf(stderr, "%s: no smart threshold command support\n", name);
+ goto out;
+ }
+
+ rc = ndctl_cmd_submit(st_cmd);
+ if (rc) {
+ fprintf(stderr, "%s: smart threshold command failed: %d %s\n",
+ name, rc, strerror(errno));
+ goto out;
+ }
+
+ alarm = ndctl_cmd_smart_threshold_get_alarm_control(st_cmd);
+ mtemp = ndctl_cmd_smart_threshold_get_media_temperature(st_cmd);
+ ctemp = ndctl_cmd_smart_threshold_get_ctrl_temperature(st_cmd);
+ spare = ndctl_cmd_smart_threshold_get_spares(st_cmd);
+ fprintf(stderr, "%s: (smart thresh) alarm: %#x mtemp: %.2f ctemp: %.2f spares: %d\n",
+ name, alarm, ndctl_decode_smart_temperature(mtemp),
+ ndctl_decode_smart_temperature(ctemp), spare);
+
+ orig_mtemp = mtemp;
+ orig_ctemp = ctemp;
+ orig_spare = spare;
+
+ sst_cmd = ndctl_dimm_cmd_new_smart_set_threshold(st_cmd);
+ if (!sst_cmd) {
+ fprintf(stderr, "%s: no smart set threshold command support\n", name);
+ goto out;
+ }
+
+ alarm = ndctl_cmd_smart_threshold_get_supported_alarms(sst_cmd);
+ if (!alarm) {
+ fprintf(stderr, "%s: no smart set threshold command support\n", name);
+ goto out;
+ }
+
+
+ fprintf(stderr, "%s: supported alarms: %#x\n", name, alarm);
+
+ /*
+ * free the cmd now since we only needed the alarms and will
+ * create + issue a set_threshold test for each alarm
+ */
+ ndctl_cmd_unref(sst_cmd);
+
+ for (i = 0; i < 3; i++) {
+ unsigned int set_alarm = 1 << i;
+
+ if (!(alarm & set_alarm))
+ continue;
+
+ sst_cmd = ndctl_dimm_cmd_new_smart_set_threshold(st_cmd);
+ if (!sst_cmd) {
+ fprintf(stderr, "%s: alloc failed: smart set threshold\n",
+ name);
+ goto out;
+ }
+
+ switch (set_alarm) {
+ case ND_SMART_SPARE_TRIP:
+ fprintf(stderr, "%s: set spare threshold: 99\n", name);
+ ndctl_cmd_smart_threshold_set_spares(sst_cmd, 99);
+ ndctl_cmd_smart_threshold_set_media_temperature(
+ sst_cmd, orig_mtemp);
+ ndctl_cmd_smart_threshold_set_ctrl_temperature(
+ sst_cmd, orig_ctemp);
+ break;
+ case ND_SMART_MTEMP_TRIP:
+ mtemp = ndctl_cmd_smart_get_media_temperature(s_cmd);
+ if (mtemp & (1 << 15))
+ mtemp *= 2;
+ else
+ mtemp /= 2;
+ fprintf(stderr, "%s: set mtemp threshold: %.2f\n", name,
+ ndctl_decode_smart_temperature(mtemp));
+ ndctl_cmd_smart_threshold_set_spares(
+ sst_cmd, orig_spare);
+ ndctl_cmd_smart_threshold_set_media_temperature(
+ sst_cmd, mtemp);
+ ndctl_cmd_smart_threshold_set_ctrl_temperature(
+ sst_cmd, orig_ctemp);
+ break;
+ case ND_SMART_CTEMP_TRIP:
+ ctemp = ndctl_cmd_smart_get_ctrl_temperature(s_cmd);
+ if (ctemp & (1 << 15))
+ ctemp *= 2;
+ else
+ ctemp /= 2;
+ fprintf(stderr, "%s: set ctemp threshold: %.2f\n", name,
+ ndctl_decode_smart_temperature(ctemp));
+
+ ndctl_cmd_smart_threshold_set_spares(
+ sst_cmd, orig_spare);
+ ndctl_cmd_smart_threshold_set_media_temperature(
+ sst_cmd, orig_mtemp);
+ ndctl_cmd_smart_threshold_set_ctrl_temperature(
+ sst_cmd, ctemp);
+
+ break;
+ default:
+ break;
+ }
+
+ ndctl_cmd_smart_threshold_set_alarm_control(sst_cmd, set_alarm);
+ rc = ndctl_cmd_submit(sst_cmd);
+ if (rc) {
+ fprintf(stderr, "%s: smart set threshold command failed: %d %s\n",
+ name, rc, strerror(errno));
+ goto out;
+ }
+
+ ndctl_cmd_unref(sst_cmd);
+ }
+
+ fprintf(stderr, "%s: set thresholds back to defaults\n", name);
+ sst_cmd = ndctl_dimm_cmd_new_smart_set_threshold(st_cmd);
+ if (!sst_cmd) {
+ fprintf(stderr, "%s: alloc failed: smart set threshold\n",
+ name);
+ goto out;
+ }
+
+ rc = ndctl_cmd_submit(sst_cmd);
+ if (rc) {
+ fprintf(stderr, "%s: smart set threshold defaults failed: %d %s\n",
+ name, rc, strerror(errno));
+ goto out;
+ }
+
+out:
+ ndctl_cmd_unref(sst_cmd);
+ ndctl_cmd_unref(st_cmd);
+ ndctl_cmd_unref(s_cmd);
+}
+
+static void test_dimm_notify(struct ndctl_bus *bus)
+{
+ struct ndctl_dimm *dimm;
+
+ ndctl_dimm_foreach(bus, dimm)
+ do_notify(dimm);
+}
+
+int main(int argc, char *argv[])
+{
+ struct ndctl_ctx *ctx;
+ struct ndctl_bus *bus;
+ int rc = EXIT_FAILURE;
+ const char *provider;
+
+ rc = ndctl_new(&ctx);
+ if (rc < 0)
+ return EXIT_FAILURE;
+
+ if (argc != 2) {
+ fprintf(stderr, "usage: smart-notify <nvdimm-bus-provider>\n");
+ goto out;
+ }
+
+ ndctl_set_log_priority(ctx, LOG_DEBUG);
+
+ provider = argv[1];
+ bus = ndctl_bus_get_by_provider(ctx, provider);
+ if (!bus) {
+ fprintf(stderr, "smart-notify: unable to find bus (%s)\n",
+ provider);
+ goto out;
+ }
+
+ rc = EXIT_SUCCESS;
+ test_dimm_notify(bus);
+out:
+ ndctl_unref(ctx);
+ return rc;
+}
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [ndctl PATCH 16/17] ndctl, test: listen for smart notifications
2017-12-01 23:24 [ndctl PATCH 00/16] ndctl: update SMART support for NVDIMM_FAMILY_INTEL Dan Williams
` (14 preceding siblings ...)
2017-12-01 23:25 ` [ndctl PATCH 15/17] ndctl, test: trigger notifications Dan Williams
@ 2017-12-01 23:25 ` Dan Williams
2017-12-01 23:25 ` [ndctl PATCH 17/17] ndctl, test: hugetlb fault Dan Williams
2017-12-01 23:36 ` [ndctl PATCH 00/16] ndctl: update SMART support for NVDIMM_FAMILY_INTEL Dan Williams
17 siblings, 0 replies; 19+ messages in thread
From: Dan Williams @ 2017-12-01 23:25 UTC (permalink / raw)
To: linux-nvdimm
Watch all DIMMs on a given nvdimm bus for smart events and report if
they trigger.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
test/Makefile.am | 3 +
test/smart-listen.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 112 insertions(+)
create mode 100644 test/smart-listen.c
diff --git a/test/Makefile.am b/test/Makefile.am
index 85736c3cce09..d4c2bd6b2640 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -26,6 +26,7 @@ check_PROGRAMS =\
multi-pmem \
dax-errors \
smart-notify \
+ smart-listen \
daxdev-errors
if ENABLE_DESTRUCTIVE
@@ -103,6 +104,8 @@ device_dax_LDADD = \
smart_notify_SOURCES = smart-notify.c
smart_notify_LDADD = $(LIBNDCTL_LIB)
+smart_listen_SOURCES = smart-listen.c
+smart_listen_LDADD = $(LIBNDCTL_LIB)
multi_pmem_SOURCES = \
multi-pmem.c \
diff --git a/test/smart-listen.c b/test/smart-listen.c
new file mode 100644
index 000000000000..e365ce54c7bd
--- /dev/null
+++ b/test/smart-listen.c
@@ -0,0 +1,109 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2017 Intel Corporation. All rights reserved. */
+#include <poll.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <ndctl/libndctl.h>
+
+static void dimm_listen(struct ndctl_bus *bus)
+{
+ struct ndctl_dimm *dimm, **dimms;
+ int count = 0, maxfd = -1, i, rc;
+ struct pollfd *poll_ents, *p;
+ char buf;
+
+ ndctl_dimm_foreach(bus, dimm) {
+ int fd = ndctl_dimm_get_health_eventfd(dimm);
+
+ if (fd > maxfd)
+ maxfd = fd;
+ count++;
+ }
+
+ if (!count) {
+ fprintf(stderr, "no dimms on bus: %s\n",
+ ndctl_bus_get_provider(bus));
+ return;
+ }
+
+ poll_ents = calloc(count, sizeof(struct pollfd));
+ dimms = calloc(maxfd + 1, sizeof(struct ndctl_dimm *));
+
+ if (!poll_ents)
+ goto out;
+ if (!dimms)
+ goto out;
+
+ i = 0;
+ ndctl_dimm_foreach(bus, dimm) {
+ int fd = ndctl_dimm_get_health_eventfd(dimm);
+
+ p = &poll_ents[i++];
+ p->fd = fd;
+ dimms[fd] = dimm;
+ if (i > count) {
+ fprintf(stderr, "dimm count changed!?\n");
+ goto out;
+ }
+ }
+
+retry:
+ for (i = 0; i < count; i++) {
+ p = &poll_ents[i];
+ dimm = dimms[p->fd];
+ if (pread(p->fd, &buf, 1, 0) != 1) {
+ fprintf(stderr, "%s: failed to read\n",
+ ndctl_dimm_get_devname(dimm));
+ goto out;
+ }
+ if (p->revents)
+ fprintf(stderr, "%s: smart event: %d\n",
+ ndctl_dimm_get_devname(dimm),
+ p->revents);
+ p->revents = 0;
+ }
+
+ rc = poll(poll_ents, count, -1);
+ if (rc <= 0) {
+ fprintf(stderr, "failed to poll\n");
+ goto out;
+ }
+ goto retry;
+
+out:
+ free(poll_ents);
+ free(dimms);
+}
+
+int main(int argc, char *argv[])
+{
+ struct ndctl_ctx *ctx;
+ struct ndctl_bus *bus;
+ int rc = EXIT_FAILURE;
+ const char *provider;
+
+ rc = ndctl_new(&ctx);
+ if (rc < 0)
+ return EXIT_FAILURE;
+
+ if (argc != 2) {
+ fprintf(stderr, "usage: smart-notify <nvdimm-bus-provider>\n");
+ goto out;
+ }
+
+ provider = argv[1];
+ bus = ndctl_bus_get_by_provider(ctx, provider);
+ if (!bus) {
+ fprintf(stderr, "smart-notify: unable to find bus (%s)\n",
+ provider);
+ goto out;
+ }
+
+ rc = EXIT_SUCCESS;
+ dimm_listen(bus);
+out:
+ ndctl_unref(ctx);
+ return rc;
+}
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [ndctl PATCH 17/17] ndctl, test: hugetlb fault
2017-12-01 23:24 [ndctl PATCH 00/16] ndctl: update SMART support for NVDIMM_FAMILY_INTEL Dan Williams
` (15 preceding siblings ...)
2017-12-01 23:25 ` [ndctl PATCH 16/17] ndctl, test: listen for smart notifications Dan Williams
@ 2017-12-01 23:25 ` Dan Williams
2017-12-01 23:36 ` [ndctl PATCH 00/16] ndctl: update SMART support for NVDIMM_FAMILY_INTEL Dan Williams
17 siblings, 0 replies; 19+ messages in thread
From: Dan Williams @ 2017-12-01 23:25 UTC (permalink / raw)
To: linux-nvdimm
Compliment the fsdax and devdax huge page tests with hugetlbfs tests
since they share some of the same code paths.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
test/Makefile.am | 4 ++++
test/dax-pmd.c | 45 ++++++++++++++++++++++++++++++++++++++++++---
test/hugetlb.c | 29 +++++++++++++++++++++++++++++
3 files changed, 75 insertions(+), 3 deletions(-)
create mode 100644 test/hugetlb.c
diff --git a/test/Makefile.am b/test/Makefile.am
index d4c2bd6b2640..a8e047bfd36c 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -16,6 +16,7 @@ TESTS =\
blk-exhaust.sh \
sector-mode.sh \
inject-error.sh \
+ hugetlb \
btt-errors.sh
check_PROGRAMS =\
@@ -27,6 +28,7 @@ check_PROGRAMS =\
dax-errors \
smart-notify \
smart-listen \
+ hugetlb \
daxdev-errors
if ENABLE_DESTRUCTIVE
@@ -82,6 +84,8 @@ dax_dev_SOURCES = dax-dev.c $(testcore)
dax_dev_LDADD = $(LIBNDCTL_LIB) $(KMOD_LIBS)
dax_pmd_SOURCES = dax-pmd.c
+hugetlb_SOURCES = hugetlb.c \
+ dax-pmd.c
mmap_SOURCES = mmap.c
dax_errors_SOURCES = dax-errors.c
daxdev_errors_SOURCES = daxdev-errors.c \
diff --git a/test/dax-pmd.c b/test/dax-pmd.c
index 1a296aff32ea..06fe52200e4f 100644
--- a/test/dax-pmd.c
+++ b/test/dax-pmd.c
@@ -13,6 +13,7 @@
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
+#include <linux/mman.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
@@ -42,12 +43,50 @@ int test_dax_directio(int dax_fd, unsigned long align, void *dax_addr, off_t off
return -ENOMEM;
for (i = 0; i < 5; i++) {
- void *addr = mmap(dax_addr, 2*align,
- PROT_READ|PROT_WRITE, MAP_SHARED, dax_fd,
- offset);
+ unsigned long flags;
+ void *addr;
int fd2;
+ if (dax_fd >= 0)
+ flags = MAP_SHARED;
+ else {
+ /* hugetlbfs instead of device-dax */
+ const char *base = "/sys/kernel/mm/hugepages";
+ FILE *f_nrhuge;
+ char path[256];
+
+ flags = MAP_SHARED | MAP_ANONYMOUS;
+ if (align >= SZ_2M) {
+ char setting[] = { "2\n" };
+
+ sprintf(path, "%s/hugepages-%ldkB/nr_hugepages",
+ base, align / 1024);
+ f_nrhuge = fopen(path, "r+");
+ if (!f_nrhuge) {
+ rc = -errno;
+ faili(i);
+ return rc;
+ }
+ if (fwrite(setting, sizeof(setting), 1, f_nrhuge) != 1) {
+ rc = -errno;
+ faili(i);
+ fclose(f_nrhuge);
+ return rc;
+ }
+ fclose(f_nrhuge);
+
+ /* FIXME: support non-x86 page sizes */
+ if (align > SZ_2M)
+ flags |= MAP_HUGETLB | MAP_HUGE_1GB;
+ else
+ flags |= MAP_HUGETLB | MAP_HUGE_2MB;
+ }
+ }
+ addr = mmap(dax_addr, 2*align,
+ PROT_READ|PROT_WRITE, flags, dax_fd, offset);
+
if (addr == MAP_FAILED) {
+ rc = -errno;
faili(i);
break;
}
diff --git a/test/hugetlb.c b/test/hugetlb.c
new file mode 100644
index 000000000000..a08a93ad40f3
--- /dev/null
+++ b/test/hugetlb.c
@@ -0,0 +1,29 @@
+#include <stdio.h>
+#include <errno.h>
+
+#include <ccan/array_size/array_size.h>
+#include <util/size.h>
+#include <test.h>
+
+static int test_hugetlb(void)
+{
+ int rc, i;
+ unsigned long aligns[] = { SZ_4K, SZ_2M, SZ_1G };
+
+ for (i = 0; i < (int) ARRAY_SIZE(aligns); i++) {
+ fprintf(stderr, "%s: page_size: %#lx\n", __func__, aligns[i]);
+ rc = test_dax_directio(-1, aligns[i], NULL, 0);
+ if (rc == -ENOMEM || rc == -EACCES)
+ return 77;
+ else if (rc == -ENOENT && aligns[i] == SZ_1G)
+ continue; /* system not configured for 1G pages */
+ else if (rc)
+ return rc;
+ }
+ return 0;
+}
+
+int __attribute__((weak)) main(int argc, char *argv[])
+{
+ return test_hugetlb();
+}
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [ndctl PATCH 00/16] ndctl: update SMART support for NVDIMM_FAMILY_INTEL
2017-12-01 23:24 [ndctl PATCH 00/16] ndctl: update SMART support for NVDIMM_FAMILY_INTEL Dan Williams
` (16 preceding siblings ...)
2017-12-01 23:25 ` [ndctl PATCH 17/17] ndctl, test: hugetlb fault Dan Williams
@ 2017-12-01 23:36 ` Dan Williams
17 siblings, 0 replies; 19+ messages in thread
From: Dan Williams @ 2017-12-01 23:36 UTC (permalink / raw)
To: linux-nvdimm; +Cc: Lijun Pan
On Fri, Dec 1, 2017 at 3:24 PM, Dan Williams <dan.j.williams@intel.com> wrote:
>
> The v1.6 release of the NVDIMM_FAMILY_INTEL DSM specification [1]
> updates the format of the 'SMART Threshold Command' payload and
> introduces the 'SMART Set Threshold Command'. Given that the new SMART
> Threshold format is broken with respect to the initial / generic
> ND_IOCTL_SMART_THRESHOLD format the generic SMART commands are now
> deprecated. The NVDIMM_FAMILY_INTEL SMART support is updated to use
> the ND_IOCTL_CALL path similar to how libndctl abstracts the per vendor
> differences of the NVDIMM_FAMILY_{HPE1,MSFT} SMART implementations.
>
> Included in this overhaul is better infrastructure for supporting the
> rest of the v1.6 DSMs that need to go through the ND_IOCTL_CALL
> interface.
>
> Note, the v1.6 specification also includes a 'SMART Error Injection'
> facility, but that enabling is deferred for a later update and will be
> integrated with the 'ndctl inject-error' command.
>
> [1]: http://pmem.io/documents/NVDIMM_DSM_Interface-V1.6.pdf
>
> ---
>
> Dan Williams (16):
> libndctl: rename dimm dsm_mask to cmd_mask
> libndctl: add nfit_dsm_mask as a private dimm property
> ndctl, smart: rename 'temperature' helpers to 'media_temperature'
> ndctl, intel: switch to ND_CMD_CALL passthrough for SMART commands
> ndctl: remove support for compiling against the kernel ndctl.h header
> ndctl, test: emit smart field names
> ndctl, smart: cleanup smart_cmd_op() macro
> ndctl, test: reset all nfit_test data for each test/libndctl run
> ndctl, region: cleanup error message
> ndctl: support set smart alarm/threshold
> ndctl: refactor 'smart_ops' into generic 'dimm_ops'
> ndctl, debug: improve do_cmd output for ND_CMD_CALL
> ndctl, list: teach the list command about the 'fsdax' and 'devdax' modes
> ndctl, smart: move smart temperature parsing to a library routine
> ndctl, test: trigger notifications
> ndctl, test: listen for smart notifications
Note, I accidentally included a hugetlb-unit-test patch when sending
this out, which is why cover letter says 00/16 but there are 17
patches in this posting.
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2017-12-01 23:32 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-01 23:24 [ndctl PATCH 00/16] ndctl: update SMART support for NVDIMM_FAMILY_INTEL Dan Williams
2017-12-01 23:24 ` [ndctl PATCH 01/17] libndctl: rename dimm dsm_mask to cmd_mask Dan Williams
2017-12-01 23:24 ` [ndctl PATCH 02/17] libndctl: add nfit_dsm_mask as a private dimm property Dan Williams
2017-12-01 23:24 ` [ndctl PATCH 03/17] ndctl, smart: rename 'temperature' helpers to 'media_temperature' Dan Williams
2017-12-01 23:24 ` [ndctl PATCH 04/17] ndctl, intel: switch to ND_CMD_CALL passthrough for SMART commands Dan Williams
2017-12-01 23:24 ` [ndctl PATCH 05/17] ndctl: remove support for compiling against the kernel ndctl.h header Dan Williams
2017-12-01 23:25 ` [ndctl PATCH 06/17] ndctl, test: emit smart field names Dan Williams
2017-12-01 23:25 ` [ndctl PATCH 07/17] ndctl, smart: cleanup smart_cmd_op() macro Dan Williams
2017-12-01 23:25 ` [ndctl PATCH 08/17] ndctl, test: reset all nfit_test data for each test/libndctl run Dan Williams
2017-12-01 23:25 ` [ndctl PATCH 09/17] ndctl, region: cleanup error message Dan Williams
2017-12-01 23:25 ` [ndctl PATCH 10/17] ndctl: support set smart alarm/threshold Dan Williams
2017-12-01 23:25 ` [ndctl PATCH 11/17] ndctl: refactor 'smart_ops' into generic 'dimm_ops' Dan Williams
2017-12-01 23:25 ` [ndctl PATCH 12/17] ndctl, debug: improve do_cmd output for ND_CMD_CALL Dan Williams
2017-12-01 23:25 ` [ndctl PATCH 13/17] ndctl, list: teach the list command about the 'fsdax' and 'devdax' modes Dan Williams
2017-12-01 23:25 ` [ndctl PATCH 14/17] ndctl, smart: move smart temperature parsing to a library routine Dan Williams
2017-12-01 23:25 ` [ndctl PATCH 15/17] ndctl, test: trigger notifications Dan Williams
2017-12-01 23:25 ` [ndctl PATCH 16/17] ndctl, test: listen for smart notifications Dan Williams
2017-12-01 23:25 ` [ndctl PATCH 17/17] ndctl, test: hugetlb fault Dan Williams
2017-12-01 23:36 ` [ndctl PATCH 00/16] ndctl: update SMART support for NVDIMM_FAMILY_INTEL Dan Williams
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).