[ndctl PATCH] ndctl, test: Update tests for capacity vs namespace-label locking
by Dan Williams
Check that namespaces can be enumerated, but are disabled if the labels
are readable while the DIMM is locked. Alternatively, if the namespace
label area is locked, validate that regions with the affected DIMM fail
to enable.
Signed-off-by: Dan Williams <dan.j.williams(a)intel.com>
---
test/Makefile.am | 10 +-
test/dsm-fail.c | 305 ++++++++++++++++++++++++++++++++++++++++++++----------
2 files changed, 257 insertions(+), 58 deletions(-)
diff --git a/test/Makefile.am b/test/Makefile.am
index 92cf29d6065e..f6483910af45 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -69,9 +69,15 @@ libndctl_LDADD = $(LIBNDCTL_LIB) $(UUID_LIBS) $(KMOD_LIBS)
dsm_fail_SOURCES =\
dsm-fail.c \
- $(testcore)
+ $(testcore) \
+ ../ndctl/namespace.c \
+ ../ndctl/check.c \
+ ../util/json.c
-dsm_fail_LDADD = $(LIBNDCTL_LIB) $(KMOD_LIBS)
+dsm_fail_LDADD = $(LIBNDCTL_LIB) \
+ $(KMOD_LIBS) \
+ $(JSON_LIBS) \
+ ../libutil.a
ack_shutdown_count_set_SOURCES =\
ack-shutdown-count-set.c \
diff --git a/test/dsm-fail.c b/test/dsm-fail.c
index 90d3e074f12b..b0df9da8ffab 100644
--- a/test/dsm-fail.c
+++ b/test/dsm-fail.c
@@ -24,6 +24,7 @@
#include <ccan/array_size/array_size.h>
#include <ndctl/libndctl.h>
+#include <builtin.h>
#include <ndctl.h>
#include <test.h>
@@ -38,20 +39,153 @@ static void reset_bus(struct ndctl_bus *bus)
ndctl_region_foreach(bus, region)
ndctl_region_disable_invalidate(region);
- ndctl_dimm_foreach(bus, dimm)
- ndctl_dimm_zero_labels(dimm);
+ ndctl_dimm_foreach(bus, dimm) {
+ struct ndctl_cmd *cmd_read = ndctl_dimm_read_labels(dimm);
+
+ ndctl_dimm_disable(dimm);
+ ndctl_dimm_init_labels(dimm, NDCTL_NS_VERSION_1_2);
+ ndctl_dimm_enable(dimm);
+ }
/* set regions back to their default state */
ndctl_region_foreach(bus, region)
ndctl_region_enable(region);
}
+static int set_dimm_response(const char *dimm_path, int cmd, int error_code,
+ struct log_ctx *log_ctx)
+{
+ char path[1024], buf[SYSFS_ATTR_SIZE];
+ int rc;
+
+ if (error_code) {
+ sprintf(path, "%s/fail_cmd", dimm_path);
+ sprintf(buf, "%#x\n", 1 << cmd);
+ rc = __sysfs_write_attr(log_ctx, path, buf);
+ if (rc)
+ goto out;
+ sprintf(path, "%s/fail_cmd_code", dimm_path);
+ sprintf(buf, "%d\n", error_code);
+ rc = __sysfs_write_attr(log_ctx, path, buf);
+ if (rc)
+ goto out;
+ } else {
+ sprintf(path, "%s/fail_cmd", dimm_path);
+ sprintf(buf, "0\n");
+ rc = __sysfs_write_attr(log_ctx, path, buf);
+ if (rc)
+ goto out;
+ }
+out:
+ if (rc < 0)
+ fprintf(stderr, "%s failed, cmd: %d code: %d\n",
+ __func__, cmd, error_code);
+ return 0;
+}
+
+static int dimms_disable(struct ndctl_bus *bus)
+{
+ struct ndctl_dimm *dimm;
+
+ ndctl_dimm_foreach(bus, dimm) {
+ int rc = ndctl_dimm_disable(dimm);
+
+ if (rc) {
+ fprintf(stderr, "dimm: %s failed to disable: %d\n",
+ ndctl_dimm_get_devname(dimm), rc);
+ return rc;
+ }
+ }
+ return 0;
+}
+
+static int test_dimms_enable(struct ndctl_bus *bus, struct ndctl_dimm *victim,
+ bool expect)
+{
+ struct ndctl_dimm *dimm;
+
+ ndctl_dimm_foreach(bus, dimm) {
+ int rc = ndctl_dimm_enable(dimm);
+
+ if (((expect != (rc == 0)) && (dimm == victim))
+ || (rc && dimm != victim)) {
+ bool __expect = true;
+
+ if (dimm == victim)
+ __expect = expect;
+ fprintf(stderr, "fail expected %s enable %s victim: %s rc: %d\n",
+ ndctl_dimm_get_devname(dimm),
+ __expect ? "success" : "failure",
+ ndctl_dimm_get_devname(victim), rc);
+ return -ENXIO;
+ }
+ }
+ return 0;
+}
+
+static int test_regions_enable(struct ndctl_bus *bus,
+ struct ndctl_dimm *victim, struct ndctl_region *victim_region,
+ bool region_expect, int namespace_count)
+{
+ struct ndctl_region *region;
+
+ ndctl_region_foreach(bus, region) {
+ struct ndctl_namespace *ndns;
+ struct ndctl_dimm *dimm;
+ bool has_victim = false;
+ int rc, count = 0;
+
+ ndctl_dimm_foreach_in_region(region, dimm) {
+ if (dimm == victim) {
+ has_victim = true;
+ break;
+ }
+ }
+
+ rc = ndctl_region_enable(region);
+ fprintf(stderr, "region: %s enable: %d has_victim: %d\n",
+ ndctl_region_get_devname(region), rc, has_victim);
+ if (((region_expect != (rc == 0)) && has_victim)
+ || (rc && !has_victim)) {
+ bool __expect = true;
+
+ if (has_victim)
+ __expect = region_expect;
+ fprintf(stderr, "%s: fail expected enable: %s with %s\n",
+ ndctl_region_get_devname(region),
+ __expect ? "success" : "failure",
+ ndctl_dimm_get_devname(victim));
+ return -ENXIO;
+ }
+ if (region != victim_region)
+ continue;
+ ndctl_namespace_foreach(region, ndns) {
+ if (ndctl_namespace_is_enabled(ndns)) {
+ fprintf(stderr, "%s: enabled, expected disabled\n",
+ ndctl_namespace_get_devname(ndns));
+ return -ENXIO;
+ }
+ fprintf(stderr, "%s: %s: size: %lld\n", __func__,
+ ndctl_namespace_get_devname(ndns),
+ ndctl_namespace_get_size(ndns));
+ count++;
+ }
+ if (count != namespace_count) {
+ fprintf(stderr, "%s: fail expected %d namespaces got %d\n",
+ ndctl_region_get_devname(region),
+ namespace_count, count);
+ return -ENXIO;
+ }
+ }
+ return 0;
+}
+
static int do_test(struct ndctl_ctx *ctx, struct ndctl_test *test)
{
struct ndctl_bus *bus = ndctl_bus_get_by_provider(ctx, "nfit_test.0");
+ struct ndctl_region *region, *victim_region = NULL;
struct ndctl_dimm *dimm, *victim = NULL;
char path[1024], buf[SYSFS_ATTR_SIZE];
- struct ndctl_region *region;
struct log_ctx log_ctx;
unsigned int handle;
int rc, err = 0;
@@ -64,11 +198,7 @@ static int do_test(struct ndctl_ctx *ctx, struct ndctl_test *test)
log_init(&log_ctx, "test/dsm-fail", "NDCTL_TEST");
- ndctl_bus_wait_probe(bus);
-
- /* disable all regions so that we can disable a dimm */
- ndctl_region_foreach(bus, region)
- ndctl_region_disable_invalidate(region);
+ reset_bus(bus);
sprintf(path, "%s/handle", DIMM_PATH);
rc = __sysfs_read_attr(&log_ctx, path, buf);
@@ -79,16 +209,11 @@ static int do_test(struct ndctl_ctx *ctx, struct ndctl_test *test)
handle = strtoul(buf, NULL, 0);
- ndctl_dimm_foreach(bus, dimm) {
- if (ndctl_dimm_get_handle(dimm) == handle)
+ ndctl_dimm_foreach(bus, dimm)
+ if (ndctl_dimm_get_handle(dimm) == handle) {
victim = dimm;
-
- if (ndctl_dimm_disable(dimm)) {
- fprintf(stderr, "failed to disable: %s\n",
- ndctl_dimm_get_devname(dimm));
- return -ENXIO;
+ break;
}
- }
if (!victim) {
fprintf(stderr, "failed to find victim dimm\n");
@@ -96,67 +221,135 @@ static int do_test(struct ndctl_ctx *ctx, struct ndctl_test *test)
}
fprintf(stderr, "victim: %s\n", ndctl_dimm_get_devname(victim));
- sprintf(path, "%s/fail_cmd", DIMM_PATH);
- sprintf(buf, "%#x\n", 1 << ND_CMD_GET_CONFIG_SIZE);
- rc = __sysfs_write_attr(&log_ctx, path, buf);
- if (rc) {
- fprintf(stderr, "failed to set fail cmd mask\n");
- return -ENXIO;
- }
+ ndctl_region_foreach(bus, region) {
+ if (ndctl_region_get_type(region) != ND_DEVICE_REGION_PMEM)
+ continue;
+ ndctl_dimm_foreach_in_region(region, dimm) {
+ const char *argv[] = {
+ "__func__", "-v", "-r",
+ ndctl_region_get_devname(region),
+ "-s", "4M", "-m", "raw",
+ };
+ struct ndctl_namespace *ndns;
+ int count, i;
- ndctl_dimm_foreach(bus, dimm) {
- rc = ndctl_dimm_enable(dimm);
- fprintf(stderr, "dimm: %s enable: %d\n",
- ndctl_dimm_get_devname(dimm), rc);
- if ((rc == 0) == (dimm == victim)) {
- fprintf(stderr, "fail expected %s enable %s victim: %s\n",
- ndctl_dimm_get_devname(dimm),
- (dimm == victim) ? "failure" : "success",
- ndctl_dimm_get_devname(victim));
- err = -ENXIO;
- goto out;
+ if (dimm != victim)
+ continue;
+ /*
+ * Validate that we only have the one seed
+ * namespace, and then create one so that we can
+ * verify namespace enumeration while locked.
+ */
+ count = 0;
+ ndctl_namespace_foreach(region, ndns)
+ count++;
+ if (count != 1) {
+ fprintf(stderr, "%s: found %d namespaces expected 1\n",
+ ndctl_region_get_devname(region),
+ count);
+ rc = -ENXIO;
+ goto out;
+ }
+ if (ndctl_region_get_size(region)
+ != ndctl_region_get_available_size(region)) {
+ fprintf(stderr, "%s: expected empty region\n",
+ ndctl_region_get_devname(region));
+ rc = -ENXIO;
+ goto out;
+ }
+ for (i = 0; i < 2; i++) {
+ builtin_xaction_namespace_reset();
+ rc = cmd_create_namespace(ARRAY_SIZE(argv), argv,
+ ndctl_region_get_ctx(region));
+ if (rc) {
+ fprintf(stderr, "%s: failed to create namespace\n",
+ ndctl_region_get_devname(region));
+ rc = -ENXIO;
+ goto out;
+ }
+ }
+ victim_region = region;
}
+ if (victim_region)
+ break;
}
- ndctl_region_foreach(bus, region) {
- bool has_victim = false;
+ /* disable all regions so that we can disable a dimm */
+ ndctl_region_foreach(bus, region)
+ ndctl_region_disable_invalidate(region);
- ndctl_dimm_foreach_in_region(region, dimm) {
- if (dimm == victim) {
- has_victim = true;
- break;
- }
- }
+ rc = dimms_disable(bus);
+ if (rc)
+ goto out;
- rc = ndctl_region_enable(region);
- fprintf(stderr, "region: %s enable: %d has_victim: %d\n",
- ndctl_region_get_devname(region), rc, has_victim);
- if ((rc == 0) == has_victim) {
- fprintf(stderr, "fail expected %s enable %s with %s disabled\n",
- ndctl_region_get_devname(region),
- has_victim ? "failure" : "success",
- ndctl_dimm_get_devname(victim));
- err = -ENXIO;
- goto out;
- }
- }
+
+ rc = set_dimm_response(DIMM_PATH, ND_CMD_GET_CONFIG_SIZE, -EACCES,
+ &log_ctx);
+ if (rc)
+ goto out;
+ fprintf(stderr, "%s:%d\n", __func__, __LINE__);
+ rc = test_dimms_enable(bus, victim, true);
+ if (rc)
+ goto out;
+ fprintf(stderr, "%s:%d\n", __func__, __LINE__);
+ rc = test_regions_enable(bus, victim, victim_region, true, 2);
+ if (rc)
+ goto out;
+ fprintf(stderr, "%s:%d\n", __func__, __LINE__);
+ rc = set_dimm_response(DIMM_PATH, ND_CMD_GET_CONFIG_SIZE, 0, &log_ctx);
+ if (rc)
+ goto out;
+
+ ndctl_region_foreach(bus, region)
+ ndctl_region_disable_invalidate(region);
+ fprintf(stderr, "%s:%d\n", __func__, __LINE__);
+ rc = dimms_disable(bus);
+ if (rc)
+ goto out;
+ fprintf(stderr, "%s:%d\n", __func__, __LINE__);
+
+ rc = set_dimm_response(DIMM_PATH, ND_CMD_GET_CONFIG_DATA, -EACCES,
+ &log_ctx);
+ if (rc)
+ goto out;
+ fprintf(stderr, "%s:%d\n", __func__, __LINE__);
+ rc = test_dimms_enable(bus, victim, false);
+ if (rc)
+ goto out;
+ fprintf(stderr, "%s:%d\n", __func__, __LINE__);
+ rc = test_regions_enable(bus, victim, victim_region, false, 0);
+ if (rc)
+ goto out;
+ fprintf(stderr, "%s:%d\n", __func__, __LINE__);
+ rc = set_dimm_response(DIMM_PATH, ND_CMD_GET_CONFIG_DATA, 0, &log_ctx);
+ if (rc)
+ goto out;
+ fprintf(stderr, "%s:%d\n", __func__, __LINE__);
+ rc = dimms_disable(bus);
+ if (rc)
+ goto out;
+ fprintf(stderr, "%s:%d\n", __func__, __LINE__);
out:
+ err = rc;
+ sprintf(path, "%s/fail_cmd", DIMM_PATH);
sprintf(buf, "0\n");
rc = __sysfs_write_attr(&log_ctx, path, buf);
if (rc) {
fprintf(stderr, "%s: failed to clear fail_cmd mask\n",
ndctl_dimm_get_devname(victim));
- err = -ENXIO;
+ rc = -ENXIO;
}
rc = ndctl_dimm_enable(victim);
if (rc) {
fprintf(stderr, "failed to enable victim: %s after clearing error\n",
ndctl_dimm_get_devname(victim));
- err = -ENXIO;
+ rc = -ENXIO;
}
reset_bus(bus);
+ if (rc)
+ err = rc;
return err;
}
2 years, 8 months
[PATCH v3 0/2] Support ACPI 6.1 update in NFIT Control Region Structure
by Toshi Kani
ACPI 6.1, Table 5-133, updates NVDIMM Control Region Structure as
follows.
- Valid Fields, Manufacturing Location, and Manufacturing Date
are added from reserved range. No change in the structure size.
- IDs (SPD values) are stored as arrays of bytes (i.e. big-endian
format). The spec clarifies that they need to be represented
as arrays of bytes as well.
Patch 1 changes the NFIT driver to comply with ACPI 6.1.
Patch 2 adds a new sysfs file "id" to show NVDIMM ID defined in ACPI 6.1.
The patch-set applies on linux-pm.git acpica.
link: http://www.uefi.org/sites/default/files/resources/ACPI_6_1.pdf
---
v3:
- Need to coordinate with ACPICA update (Bob Moore, Dan Williams)
- Integrate with ACPICA changes in struct acpi_nfit_control_region.
(commit 138a95547ab0)
v2:
- Remove 'mfg_location' and 'mfg_date'. (Dan Williams)
- Rename 'unique_id' to 'id' and make this change as a separate patch.
(Dan Williams)
---
Toshi Kani (3):
1/2 acpi/nfit: Update nfit driver to comply with ACPI 6.1
2/3 acpi/nfit: Add sysfs "id" for NVDIMM ID
---
drivers/acpi/nfit.c | 29 ++++++++++++++++++++++++-----
1 file changed, 24 insertions(+), 5 deletions(-)
2 years, 8 months
[PATCH] ndctl: add a test file to .gitignore
by Masayoshi Mizuma
From: Masayoshi Mizuma <m.mizuma(a)jp.fujitsu.com>
Add test/ack-shutdown-count-set to .gitignore.
Signed-off-by: Masayoshi Mizuma <m.mizuma(a)jp.fujitsu.com>
---
.gitignore | 1 +
1 file changed, 1 insertion(+)
diff --git a/.gitignore b/.gitignore
index c7d11d9..1016b3b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -55,3 +55,4 @@ test/smart-listen
test/smart-notify
test/fio.job
test/local-write-0-verify.state
+test/ack-shutdown-count-set
--
2.18.0.rc1
2 years, 8 months
[PATCH v3 0/2] ndctl, test: Add some global variables and functions to cleanup.
by Masayoshi Mizuma
This is additional cleanup patches for test scripts.
Add following global variable and functions to test/common file.
Then, cleanup test script to use them.
- NFIT_TEST_BUS[01] (global variable)
Buses are created when nfit_test module is loaded.
- NDCTL (global variable)
ndctl command path (renamed).
- _cleanup
Helper function cleans up nfit_test module.
- json2var
Helper function (filter) converts json to var.
Changelog:
- Fix missing '-b' before $NFIT_TEST_BUS*.
- Fix the subject to "ndctl, test:...".
Masayoshi Mizuma (2):
nfit, test: Add NFIT_TEST_BUS[01] variable and some helper funtions to common
nfit, test: cleanup test scripts
test/blk-exhaust.sh | 21 ++++++----------
test/btt-check.sh | 52 ++++++++++++++++++---------------------
test/btt-errors.sh | 30 +++++++++++-----------
test/btt-pad-compat.sh | 36 ++++++++++++---------------
test/clear.sh | 25 +++++++------------
test/common | 29 +++++++++++++++++++---
test/create.sh | 26 +++++++++-----------
test/daxdev-errors.sh | 29 ++++++++--------------
test/firmware-update.sh | 25 +++++--------------
test/inject-error.sh | 24 ++++++++----------
test/label-compat.sh | 17 +++++--------
test/multi-dax.sh | 23 ++++++-----------
test/pmem-errors.sh | 19 +++++---------
test/rescan-partitions.sh | 22 ++++++++---------
test/sector-mode.sh | 22 ++++++-----------
15 files changed, 172 insertions(+), 228 deletions(-)
--
2.18.0.rc1
2 years, 8 months
[PATCH v2 0/2] nfit, test: Add some global variables and functions to cleanup.
by Masayoshi Mizuma
This is additional cleanup patches for test scripts.
Add following global variable and functions to test/common file.
Then, cleanup test script to use them.
- NFIT_TEST_BUS[01] (global variable)
Buses are created when nfit_test module is loaded.
- NDCTL (global variable)
ndctl command path (renamed).
- _cleanup
Helper function cleans up nfit_test module.
- json2var
Helper function (filter) converts json to var.
Changelog:
- Fix missing '-b' before $NFIT_TEST_BUS*.
Masayoshi Mizuma (2):
nfit, test: Add NFIT_TEST_BUS[01] variable and some helper funtions to common
nfit, test: cleanup test scripts
test/blk-exhaust.sh | 21 ++++++----------
test/btt-check.sh | 52 ++++++++++++++++++---------------------
test/btt-errors.sh | 30 +++++++++++-----------
test/btt-pad-compat.sh | 36 ++++++++++++---------------
test/clear.sh | 25 +++++++------------
test/common | 29 +++++++++++++++++++---
test/create.sh | 26 +++++++++-----------
test/daxdev-errors.sh | 29 ++++++++--------------
test/firmware-update.sh | 25 +++++--------------
test/inject-error.sh | 24 ++++++++----------
test/label-compat.sh | 17 +++++--------
test/multi-dax.sh | 23 ++++++-----------
test/pmem-errors.sh | 19 +++++---------
test/rescan-partitions.sh | 22 ++++++++---------
test/sector-mode.sh | 22 ++++++-----------
15 files changed, 172 insertions(+), 228 deletions(-)
--
2.18.0.rc1
2 years, 8 months
[PATCH 0/2] nfit, test: Add some global variables and functions to cleanup.
by Masayoshi Mizuma
This is additional cleanup patches for test scripts.
Add following global variable and functions to test/common file.
Then, cleanup test script to use them.
- NFIT_TEST_BUS[01] (global variable)
Buses are created when nfit_test module is loaded.
- NDCTL (global variable)
ndctl command path (renamed).
- _cleanup
Helper function cleans up nfit_test module.
- json2var
Helper function (filter) converts json to var.
Masayoshi Mizuma (2):
nfit, test: Add NFIT_TEST_BUS[01] variable and some helper funtions to common
nfit, test: cleanup test scripts
test/blk-exhaust.sh | 21 ++++++----------
test/btt-check.sh | 52 ++++++++++++++++++---------------------
test/btt-errors.sh | 7 +++---
test/btt-pad-compat.sh | 36 ++++++++++++---------------
test/clear.sh | 25 +++++++------------
test/common | 29 +++++++++++++++++++---
test/create.sh | 26 +++++++++-----------
test/daxdev-errors.sh | 29 ++++++++--------------
test/firmware-update.sh | 25 +++++--------------
test/inject-error.sh | 24 ++++++++----------
test/label-compat.sh | 17 +++++--------
test/multi-dax.sh | 23 ++++++-----------
test/pmem-errors.sh | 19 +++++---------
test/rescan-partitions.sh | 22 ++++++++---------
test/sector-mode.sh | 22 ++++++-----------
15 files changed, 161 insertions(+), 216 deletions(-)
--
2.18.0.rc1
2 years, 8 months
[PATCH] tools/testing/nvdimm: advertise a write cache for nfit_test
by Vishal Verma
Commit 546eb0317cfa "libnvdimm, pmem: Do not flush power-fail protected CPU caches"
fixed the write_cache detection to correctly show the lack of a write
cache based on the platform capabilities described in the ACPI NFIT. The
nfit_test unit tests expected a write cache to be present, so change the
nfit test namespaces to only advertise a persistence domain limited to
the memory controller. This allows the kernel to show a write_cache
attribute, and the test behaviour remains unchanged.
Cc: Ross Zwisler <ross.zwisler(a)linux.intel.com>
Cc: Dan Williams <dan.j.williams(a)intel.com>
Signed-off-by: Vishal Verma <vishal.l.verma(a)intel.com>
---
tools/testing/nvdimm/test/nfit.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c
index 18157b0c0d0d..a012ab765083 100644
--- a/tools/testing/nvdimm/test/nfit.c
+++ b/tools/testing/nvdimm/test/nfit.c
@@ -2007,8 +2007,7 @@ static void nfit_test0_setup(struct nfit_test *t)
pcap->header.type = ACPI_NFIT_TYPE_CAPABILITIES;
pcap->header.length = sizeof(*pcap);
pcap->highest_capability = 1;
- pcap->capabilities = ACPI_NFIT_CAPABILITY_CACHE_FLUSH |
- ACPI_NFIT_CAPABILITY_MEM_FLUSH;
+ pcap->capabilities = ACPI_NFIT_CAPABILITY_MEM_FLUSH;
offset += pcap->header.length;
if (t->setup_hotplug) {
--
2.17.0
2 years, 8 months