linux-nvdimm.lists.01.org archive mirror
 help / color / mirror / Atom feed
* [ndctl PATCH 0/3] device-dax test for recent kernel bugs
@ 2016-09-10  1:41 Dan Williams
  2016-09-10  1:41 ` [ndctl PATCH 1/3] test, device-dax: /proc/self/smaps Dan Williams
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Dan Williams @ 2016-09-10  1:41 UTC (permalink / raw)
  To: linux-nvdimm

These tests trigger the kernel bugs fixed by the following commits:

d0e5845561c2 dax: fix device-dax region base
9049771f7d54 mm: fix cache mode of dax pmd mappings
ca120cf68887 mm: fix show_smap() for zone_device-pmd ranges

---

Dan Williams (3):
      test, device-dax: /proc/self/smaps
      test, device-dax: fix 'skip' reporting when test device not found
      test, device-dax: address translation


 test/device-dax.c |  165 ++++++++++++++++++++++++++++++++++++++++++++++++-----
 util/size.h       |    1 
 2 files changed, 149 insertions(+), 17 deletions(-)
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [ndctl PATCH 1/3] test, device-dax: /proc/self/smaps
  2016-09-10  1:41 [ndctl PATCH 0/3] device-dax test for recent kernel bugs Dan Williams
@ 2016-09-10  1:41 ` Dan Williams
  2016-09-10  1:41 ` [ndctl PATCH 2/3] test, device-dax: fix 'skip' reporting when test device not found Dan Williams
  2016-09-10  1:41 ` [ndctl PATCH 3/3] test, device-dax: address translation Dan Williams
  2 siblings, 0 replies; 4+ messages in thread
From: Dan Williams @ 2016-09-10  1:41 UTC (permalink / raw)
  To: linux-nvdimm

Until recently the kernel would crash when walking smaps with
pmd_devmap() entries in the page table.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 test/device-dax.c |   26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/test/device-dax.c b/test/device-dax.c
index a14e2a95db7e..04d53da544cd 100644
--- a/test/device-dax.c
+++ b/test/device-dax.c
@@ -60,12 +60,12 @@ static int test_device_dax(int loglevel, struct ndctl_test *test,
 		struct ndctl_ctx *ctx)
 {
 	int fd, rc, *p;
-	char *buf, path[100];
 	struct sigaction act;
 	struct ndctl_dax *dax;
 	struct daxctl_dev *dev;
 	struct ndctl_namespace *ndns;
 	struct daxctl_region *dax_region;
+	char *buf, path[100], data[4096];
 
 	memset (&act, 0, sizeof(act));
 	act.sa_sigaction = sigbus;
@@ -123,14 +123,36 @@ static int test_device_dax(int loglevel, struct ndctl_test *test,
 	p = (int *) (buf + (1UL << 20));
 	*p = 0;
 
+	/*
+	 * Prior to 4.8-final these tests cause crashes, or are
+	 * otherwise not supported.
+	 */
 	if (ndctl_test_attempt(test, KERNEL_VERSION(4, 9, 0))) {
-		/* prior to 4.8-final this crashes */
+		int fd2;
+
 		rc = test_dax_directio(fd, NULL, 0);
 		if (rc) {
 			fprintf(stderr, "%s: failed dax direct-i/o\n",
 					ndctl_namespace_get_devname(ndns));
 			return rc;
 		}
+
+		fd2 = open("/proc/self/smaps", O_RDONLY);
+		if (fd2 < 0) {
+			fprintf(stderr, "%s: failed smaps open\n",
+					ndctl_namespace_get_devname(ndns));
+			return -ENXIO;
+		}
+
+		do {
+			rc = read(fd2, data, sizeof(data));
+		} while (rc > 0);
+
+		if (rc) {
+			fprintf(stderr, "%s: failed smaps retrieval\n",
+					ndctl_namespace_get_devname(ndns));
+			return -ENXIO;
+		}
 	}
 
 	rc = reset_device_dax(ndns);

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

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [ndctl PATCH 2/3] test, device-dax: fix 'skip' reporting when test device not found
  2016-09-10  1:41 [ndctl PATCH 0/3] device-dax test for recent kernel bugs Dan Williams
  2016-09-10  1:41 ` [ndctl PATCH 1/3] test, device-dax: /proc/self/smaps Dan Williams
@ 2016-09-10  1:41 ` Dan Williams
  2016-09-10  1:41 ` [ndctl PATCH 3/3] test, device-dax: address translation Dan Williams
  2 siblings, 0 replies; 4+ messages in thread
From: Dan Williams @ 2016-09-10  1:41 UTC (permalink / raw)
  To: linux-nvdimm

If we are unable to find a test device, then the test should report
skipped.  However if any ndctl_test_attempt() succeeds prior to this
discovery ndctl_test_result() will return success (0) instead of skip
(77).  Re-arrange the 4.7 kernel version check to be after the device
availability check.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 test/device-dax.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/test/device-dax.c b/test/device-dax.c
index 04d53da544cd..c1409ac8b8b8 100644
--- a/test/device-dax.c
+++ b/test/device-dax.c
@@ -76,9 +76,6 @@ static int test_device_dax(int loglevel, struct ndctl_test *test,
 		return 1;
 	}
 
-	if (!ndctl_test_attempt(test, KERNEL_VERSION(4, 7, 0)))
-		return 77;
-
 	ndctl_set_log_priority(ctx, loglevel);
 
 	ndns = ndctl_get_test_dev(ctx);
@@ -88,6 +85,9 @@ static int test_device_dax(int loglevel, struct ndctl_test *test,
 		return 77;
 	}
 
+	if (!ndctl_test_attempt(test, KERNEL_VERSION(4, 7, 0)))
+		return 77;
+
 	rc = setup_device_dax(ndns);
 	if (rc < 0) {
 		fprintf(stderr, "%s: failed device-dax setup\n",

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

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [ndctl PATCH 3/3] test, device-dax: address translation
  2016-09-10  1:41 [ndctl PATCH 0/3] device-dax test for recent kernel bugs Dan Williams
  2016-09-10  1:41 ` [ndctl PATCH 1/3] test, device-dax: /proc/self/smaps Dan Williams
  2016-09-10  1:41 ` [ndctl PATCH 2/3] test, device-dax: fix 'skip' reporting when test device not found Dan Williams
@ 2016-09-10  1:41 ` Dan Williams
  2 siblings, 0 replies; 4+ messages in thread
From: Dan Williams @ 2016-09-10  1:41 UTC (permalink / raw)
  To: linux-nvdimm

Validate that data written through /dev/pmemX is retrievable intact
through /dev/daxX.  This tests that pmem and device-dax have the same
device-to-physical address translation.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 test/device-dax.c |  139 +++++++++++++++++++++++++++++++++++++++++++++++------
 util/size.h       |    1 
 2 files changed, 125 insertions(+), 15 deletions(-)

diff --git a/test/device-dax.c b/test/device-dax.c
index c1409ac8b8b8..82154d5c1fff 100644
--- a/test/device-dax.c
+++ b/test/device-dax.c
@@ -9,7 +9,9 @@
 #include <setjmp.h>
 #include <sys/stat.h>
 #include <sys/mman.h>
+#include <sys/time.h>
 #include <sys/types.h>
+#include <util/size.h>
 #include <linux/falloc.h>
 #include <linux/version.h>
 #include <ndctl/libndctl.h>
@@ -51,21 +53,79 @@ static int setup_device_dax(struct ndctl_namespace *ndns)
 	return create_namespace(argc, argv, ctx);
 }
 
+static int setup_pmem_memory_mode(struct ndctl_namespace *ndns)
+{
+	struct ndctl_ctx *ctx = ndctl_namespace_get_ctx(ndns);
+	const char *argv[] = {
+		"__func__", "-v", "-m", "memory", "-M", "dev", "-f", "-e", "",
+	};
+	int argc = ARRAY_SIZE(argv);
+
+	argv[argc - 1] = ndctl_namespace_get_devname(ndns);
+	return create_namespace(argc, argv, ctx);
+}
+
 static void sigbus(int sig, siginfo_t *siginfo, void *d)
 {
 	siglongjmp(sj_env, 1);
 }
 
+#define VERIFY_SIZE SZ_4M
+#define VERIFY_BUF_SIZE 4096
+
+static int verify_data(struct daxctl_dev *dev, char *dax_buf, int salt,
+	struct ndctl_test *test)
+{
+	struct timeval tv1, tv2, tv_diff;
+	int i;
+
+	if (!ndctl_test_attempt(test, KERNEL_VERSION(4, 9, 0)))
+		return 0;
+
+	/* verify data and cache mode */
+	gettimeofday(&tv1, NULL);
+	for (i = 0; i < VERIFY_SIZE; i += VERIFY_BUF_SIZE) {
+		unsigned int *verify = (unsigned int *) (dax_buf + i), j;
+
+		for (j = 0; j < VERIFY_BUF_SIZE / sizeof(int); j++)
+			if (verify[j] != salt + i + j)
+				break;
+		if (j < VERIFY_BUF_SIZE / sizeof(int)) {
+			fprintf(stderr, "%s: @ %#x expected %#x got %#x\n",
+					daxctl_dev_get_devname(dev), i,
+					verify[j], salt + i + j);
+			return -ENXIO;
+		}
+	}
+	gettimeofday(&tv2, NULL);
+	timersub(&tv2, &tv1, &tv_diff);
+	tv_diff.tv_usec += tv_diff.tv_sec * 1000000;
+	if (tv_diff.tv_usec > 15000) {
+		/*
+		 * Checks whether the kernel correctly mapped the
+		 * device-dax range as cacheable.  The numbers were
+		 * derived from an Intel(R) Xeon(R) CPU E5-2690 v2 @
+		 * 3.00GHz where the loop completes in 7500us when
+		 * cached and 200ms when uncached.
+		 */
+		fprintf(stderr, "%s: verify loop took too long usecs: %ld\n",
+				daxctl_dev_get_devname(dev), tv_diff.tv_usec);
+		return -ENXIO;
+	}
+	return 0;
+}
+
 static int test_device_dax(int loglevel, struct ndctl_test *test,
 		struct ndctl_ctx *ctx)
 {
-	int fd, rc, *p;
 	struct sigaction act;
 	struct ndctl_dax *dax;
+	struct ndctl_pfn *pfn;
 	struct daxctl_dev *dev;
+	int i, fd, rc, *p, salt;
 	struct ndctl_namespace *ndns;
 	struct daxctl_region *dax_region;
-	char *buf, path[100], data[4096];
+	char *buf, path[100], data[VERIFY_BUF_SIZE];
 
 	memset (&act, 0, sizeof(act));
 	act.sa_sigaction = sigbus;
@@ -88,11 +148,46 @@ static int test_device_dax(int loglevel, struct ndctl_test *test,
 	if (!ndctl_test_attempt(test, KERNEL_VERSION(4, 7, 0)))
 		return 77;
 
+	/* setup up memory mode pmem device and seed with verification data */
+	rc = setup_pmem_memory_mode(ndns);
+	if (rc < 0 || !(pfn = ndctl_namespace_get_pfn(ndns))) {
+		fprintf(stderr, "%s: failed device-dax setup\n",
+				ndctl_namespace_get_devname(ndns));
+		goto out;
+	}
+
+	sprintf(path, "/dev/%s", ndctl_pfn_get_block_device(pfn));
+	fd = open(path, O_RDWR);
+	if (fd < 0) {
+		fprintf(stderr, "%s: failed to open pmem device\n", path);
+		rc = -ENXIO;
+		goto out;
+	}
+
+	srand(getpid());
+	salt = rand();
+	for (i = 0; i < VERIFY_SIZE; i += VERIFY_BUF_SIZE) {
+		unsigned int *verify = (unsigned int *) data, j;
+
+		for (j = 0; j < VERIFY_BUF_SIZE / sizeof(int); j++)
+			verify[j] = salt + i + j;
+
+		if (write(fd, data, sizeof(data)) != sizeof(data)) {
+			fprintf(stderr, "%s: failed data setup\n",
+					path);
+			rc = -ENXIO;
+			goto out;
+		}
+	}
+	fsync(fd);
+	close(fd);
+
+	/* switch the namespace to device-dax mode and verify data via mmap */
 	rc = setup_device_dax(ndns);
 	if (rc < 0) {
 		fprintf(stderr, "%s: failed device-dax setup\n",
 				ndctl_namespace_get_devname(ndns));
-		return rc;
+		goto out;
 	}
 
 	dax = ndctl_namespace_get_dax(ndns);
@@ -101,27 +196,35 @@ static int test_device_dax(int loglevel, struct ndctl_test *test,
 	if (!dev) {
 		fprintf(stderr, "%s: failed to find device-dax instance\n",
 				ndctl_namespace_get_devname(ndns));
-		return -ENXIO;
+		rc = -ENXIO;
+		goto out;
 	}
 
 	sprintf(path, "/dev/%s", daxctl_dev_get_devname(dev));
-
 	fd = open(path, O_RDWR);
 	if (fd < 0) {
 		fprintf(stderr, "%s: failed to open device-dax instance\n",
 				daxctl_dev_get_devname(dev));
-		return -ENXIO;
+		rc = -ENXIO;
+		goto out;
 	}
 
-	buf = mmap(NULL, 2UL << 20, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
+	buf = mmap(NULL, VERIFY_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
 	if (buf != MAP_FAILED) {
 		fprintf(stderr, "%s: expected MAP_PRIVATE failure\n", path);
+		rc = -ENXIO;
+		goto out;
+	}
+
+	buf = mmap(NULL, VERIFY_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+	if (buf == MAP_FAILED) {
+		fprintf(stderr, "%s: expected MAP_SHARED success\n", path);
 		return -ENXIO;
 	}
 
-	buf = mmap(NULL, 2UL << 20, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
-	p = (int *) (buf + (1UL << 20));
-	*p = 0;
+	rc = verify_data(dev, buf, salt, test);
+	if (rc)
+		goto out;
 
 	/*
 	 * Prior to 4.8-final these tests cause crashes, or are
@@ -134,14 +237,15 @@ static int test_device_dax(int loglevel, struct ndctl_test *test,
 		if (rc) {
 			fprintf(stderr, "%s: failed dax direct-i/o\n",
 					ndctl_namespace_get_devname(ndns));
-			return rc;
+			goto out;
 		}
 
 		fd2 = open("/proc/self/smaps", O_RDONLY);
 		if (fd2 < 0) {
 			fprintf(stderr, "%s: failed smaps open\n",
 					ndctl_namespace_get_devname(ndns));
-			return -ENXIO;
+			rc = -ENXIO;
+			goto out;
 		}
 
 		do {
@@ -151,7 +255,8 @@ static int test_device_dax(int loglevel, struct ndctl_test *test,
 		if (rc) {
 			fprintf(stderr, "%s: failed smaps retrieval\n",
 					ndctl_namespace_get_devname(ndns));
-			return -ENXIO;
+			rc = -ENXIO;
+			goto out;
 		}
 	}
 
@@ -159,17 +264,19 @@ static int test_device_dax(int loglevel, struct ndctl_test *test,
 	if (rc < 0) {
 		fprintf(stderr, "%s: failed to reset device-dax instance\n",
 				ndctl_namespace_get_devname(ndns));
-		return rc;
+		goto out;
 	}
 
 	/* test fault after device-dax instance disabled */
 	if (sigsetjmp(sj_env, 1)) {
 		/* got sigbus, success */
 		close(fd);
-		return 0;
+		rc = 0;
+		goto out;
 	}
 
 	rc = EXIT_SUCCESS;
+	p = (int *) (buf + (1UL << 20));
 	*p = 0xff;
 	if (ndctl_test_attempt(test, KERNEL_VERSION(4, 9, 0))) {
 		/* after 4.9 this test will properly get sigbus above */
@@ -178,6 +285,8 @@ static int test_device_dax(int loglevel, struct ndctl_test *test,
 				daxctl_dev_get_devname(dev));
 	}
 	close(fd);
+ out:
+	reset_device_dax(ndns);
 	return rc;
 }
 
diff --git a/util/size.h b/util/size.h
index 64c146480ef0..9befecb28b14 100644
--- a/util/size.h
+++ b/util/size.h
@@ -4,6 +4,7 @@
 #define SZ_1K     0x00000400
 #define SZ_1M     0x00100000
 #define SZ_2M     0x00200000
+#define SZ_4M     0x00400000
 #define SZ_1G     0x40000000
 #define SZ_1T 0x10000000000ULL
 

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

^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2016-09-10  1:44 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-10  1:41 [ndctl PATCH 0/3] device-dax test for recent kernel bugs Dan Williams
2016-09-10  1:41 ` [ndctl PATCH 1/3] test, device-dax: /proc/self/smaps Dan Williams
2016-09-10  1:41 ` [ndctl PATCH 2/3] test, device-dax: fix 'skip' reporting when test device not found Dan Williams
2016-09-10  1:41 ` [ndctl PATCH 3/3] test, device-dax: address translation 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).