The kernel is converting nfit_test resources to vmalloc() instead of
DMA_CMA.  DMA_CMA collides with other common options enabled in
distribution kernels which makes nfit_test unusable without intrusive
kernel configuration changes.  The vmalloc conversion precludes higher
than PAGE_SIZE alignment configurations for pfn + dax devices.  Instead,
move these tests to run against an memmap=ss!nn range.

Signed-off-by: Dan Williams <[email protected]>
---
 test/Makefile.am   |    3 ++
 test/dax-dev.c     |   22 +++++++++----
 test/dax.sh        |    5 ++-
 test/device-dax.c  |   32 ++++++++++++++++++
 test/device-dax.sh |   30 +++++++++++++++++
 test/libndctl.c    |   91 +++++++++++++++++++++-------------------------------
 test/mmap.sh       |    7 +++-
 7 files changed, 125 insertions(+), 65 deletions(-)
 create mode 100644 test/device-dax.c
 create mode 100755 test/device-dax.sh

diff --git a/test/Makefile.am b/test/Makefile.am
index ed9981583331..ab566148e1f4 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -20,6 +20,7 @@ TESTS +=\
        pmem-ns \
        dax-dev \
        dax.sh \
+       device-dax.sh \
        mmap.sh
 
 check_PROGRAMS +=\
@@ -27,6 +28,7 @@ check_PROGRAMS +=\
        pmem-ns \
        dax-dev \
        dax-pmd \
+       device-dax \
        mmap
 endif
 
@@ -55,3 +57,4 @@ dax_dev_LDADD = $(LIBNDCTL_LIB)
 dax_pmd_SOURCES = dax-pmd.c
 mmap_SOURCES = mmap.c
 dax_errors_SOURCES = dax-errors.c
+device_dax_SOURCES = device-dax.c
diff --git a/test/dax-dev.c b/test/dax-dev.c
index 3209eb148ed9..519df324fdc8 100755
--- a/test/dax-dev.c
+++ b/test/dax-dev.c
@@ -32,6 +32,7 @@ static int emit_e820_device(int loglevel, struct ndctl_test 
*test)
        const char *bdev;
        struct ndctl_ctx *ctx;
        struct ndctl_bus *bus;
+       struct ndctl_dax *dax;
        struct ndctl_pfn *pfn;
        struct ndctl_region *region;
        struct ndctl_namespace *ndns;
@@ -62,11 +63,14 @@ static int emit_e820_device(int loglevel, struct ndctl_test 
*test)
        if (mode >= 0 && mode != NDCTL_NS_MODE_MEMORY)
                goto out;
 
+       /* if device-dax mode already established it might contain user data */
        pfn = ndctl_namespace_get_pfn(ndns);
-       if (pfn)
-               bdev = ndctl_pfn_get_block_device(pfn);
-       else
-               bdev = ndctl_namespace_get_block_device(ndns);
+       dax = ndctl_namespace_get_dax(ndns);
+       if (dax || pfn)
+               goto out;
+
+       /* device is unconfigured, assume that was on purpose */
+       bdev = ndctl_namespace_get_block_device(ndns);
        if (!bdev)
                goto out;
 
@@ -75,18 +79,22 @@ static int emit_e820_device(int loglevel, struct ndctl_test 
*test)
 
        /*
         * Note, if the bdev goes active after this check we'll still
-        * clobber it in the following tests, see test/dax.sh.
+        * clobber it in the following tests, see test/dax.sh and
+        * test/device-dax.sh.
         */
        fd = open(path, O_RDWR | O_EXCL);
        if (fd < 0)
                goto out;
        err = 0;
-       fprintf(stdout, "%s\n", path);
 
  out:
-       if (err)
+       if (err) {
                fprintf(stderr, "%s: failed to find usable victim device\n",
                                __func__);
+               ndctl_test_skip(test);
+               err = 77;
+       } else
+               fprintf(stdout, "%s\n", ndctl_namespace_get_devname(ndns));
        ndctl_unref(ctx);
        return err;
 }
diff --git a/test/dax.sh b/test/dax.sh
index 8db436a869b5..ae63f89b8e6b 100755
--- a/test/dax.sh
+++ b/test/dax.sh
@@ -21,8 +21,9 @@ set -e
 mkdir -p $MNT
 trap 'err $LINENO' ERR
 
-blockdev=$(basename $(./dax-dev))
-dev=$(basename $(readlink -f /sys/block/$(basename $blockdev)/device))
+dev=$(./dax-dev)
+json=$($NDCTL list -N -n $dev)
+eval $(echo $json | sed -e "$json2var")
 
 mkfs.ext4 /dev/$blockdev
 mount /dev/$blockdev $MNT -o dax
diff --git a/test/device-dax.c b/test/device-dax.c
new file mode 100644
index 000000000000..addf93f59252
--- /dev/null
+++ b/test/device-dax.c
@@ -0,0 +1,32 @@
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <linux/falloc.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+int main(int argc, char *argv[])
+{
+       char *buf;
+       int fd;
+
+       if (argc < 2) {
+               perror("argc invalid");
+               return -EINVAL;
+       }
+
+       fd = open(argv[1], O_RDWR);
+       if (fd < 0) {
+               perror("fd");
+               return 1;
+       }
+
+       buf = mmap(NULL, 2UL << 20, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+       *((int *) (buf + (1UL << 20))) = 0;
+
+       close(fd);
+       return 0;
+}
diff --git a/test/device-dax.sh b/test/device-dax.sh
new file mode 100755
index 000000000000..f24a350b2806
--- /dev/null
+++ b/test/device-dax.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+NDCTL="../ndctl/ndctl"
+json2var="s/[{}\",]//g; s/:/=/g; s/\]//g"
+
+err() {
+       rc=$?
+       echo "device-dax: failed at line $1"
+       exit $rc
+}
+
+set -e -x
+trap 'err $LINENO' ERR
+
+dev=$(./dax-dev)
+json=$($NDCTL list -N -n $dev)
+eval $(echo $json | sed -e "$json2var")
+
+# setup a device-dax configuration
+json=$($NDCTL create-namespace -v -m dax -M dev -f -e $dev)
+eval $(echo $json | sed -e "$json2var")
+[ $mode != "dax" ] && echo "fail: $LINENO" &&  exit 1
+
+./device-dax /dev/$chardev
+
+# revert namespace to raw mode
+json=$($NDCTL create-namespace -v -m raw -f -e $dev)
+eval $(echo $json | sed -e "$json2var")
+[ $mode != "memory" ] && echo "fail: $LINENO" &&  exit 1
+
+exit 0
diff --git a/test/libndctl.c b/test/libndctl.c
index 8346108aacec..947849d7176b 100644
--- a/test/libndctl.c
+++ b/test/libndctl.c
@@ -223,8 +223,6 @@ static struct pfn pfn_settings = {
                   8, 9,  10, 11, 12, 13, 14, 15
        },
        .locs = { NDCTL_PFN_LOC_RAM, NDCTL_PFN_LOC_PMEM },
-       /* order matters, successful aligns at the end */
-       .aligns = { 1, SZ_1G, SZ_4K, SZ_2M, },
 };
 
 static struct dax dax_settings = {
@@ -233,8 +231,6 @@ static struct dax dax_settings = {
                   8, 9,  10, 11, 12, 13, 14, 15
        },
        .locs = { NDCTL_PFN_LOC_RAM, NDCTL_PFN_LOC_PMEM },
-       /* order matters, successful aligns at the end */
-       .aligns = { 1, SZ_1G, SZ_4K, SZ_2M, },
 };
 
 struct namespace {
@@ -698,7 +694,7 @@ static int validate_dax(struct ndctl_dax *dax)
 
 static int __check_dax_create(struct ndctl_region *region,
                struct ndctl_namespace *ndns, struct namespace *namespace,
-               enum ndctl_pfn_loc loc, unsigned long align, uuid_t uuid)
+               enum ndctl_pfn_loc loc, uuid_t uuid)
 {
        struct ndctl_dax *dax_seed = ndctl_region_get_dax_seed(region);
        enum ndctl_namespace_mode mode;
@@ -711,20 +707,18 @@ static int __check_dax_create(struct ndctl_region *region,
                return -ENXIO;
 
        devname = ndctl_dax_get_devname(dax);
-       fprintf(stderr, "%s: %s align: %ld\n", __func__, devname, align);
        ndctl_dax_set_uuid(dax, uuid);
        ndctl_dax_set_location(dax, loc);
-       ndctl_dax_set_align(dax, align);
+       /*
+        * nfit_test uses vmalloc()'d resources so the only feasible
+        * alignment is PAGE_SIZE
+        */
+       ndctl_dax_set_align(dax, SZ_4K);
        ndctl_dax_set_namespace(dax, ndns);
        rc = ndctl_dax_enable(dax);
-       if (align == SZ_1G) {
-               if (rc == 0) {
-                       fprintf(stderr, "%s: expected dax enable failure with 
align: %lx\n",
-                                       devname, align);
-                       return -ENXIO;
-               }
-               ndctl_dax_delete(dax);
-               return 0;
+       if (rc) {
+               fprintf(stderr, "%s: failed to enable dax\n", devname);
+               return rc;
        }
 
        mode = ndctl_namespace_get_mode(ndns);
@@ -777,28 +771,22 @@ static int check_dax_create(struct ndctl_region *region,
                struct ndctl_namespace *ndns, struct namespace *namespace)
 {
        struct dax *dax_s = namespace->dax_settings;
-       unsigned int i, j;
        void *buf = NULL;
+       unsigned int i;
        int rc = 0;
 
        if (!dax_s)
                return 0;
 
        for (i = 0; i < ARRAY_SIZE(dax_s->locs); i++) {
-               fprintf(stderr, "%s: %ld\n", __func__, 
ARRAY_SIZE(dax_s->aligns));
-               for (j = 0; j < ARRAY_SIZE(dax_s->aligns); j++) {
-                       /*
-                        * The kernel enforces invalidating the previous
-                        * info block when the current uuid is does not
-                        * validate with the contents of the info block.
-                        */
-                       dax_s->uuid[0]++;
-                       rc = __check_dax_create(region, ndns, namespace,
-                                       dax_s->locs[i], dax_s->aligns[j],
-                                       dax_s->uuid);
-                       if (rc)
-                               break;
-               }
+               /*
+                * The kernel enforces invalidating the previous info
+                * block when the current uuid is does not validate with
+                * the contents of the info block.
+                */
+               dax_s->uuid[0]++;
+               rc = __check_dax_create(region, ndns, namespace,
+                               dax_s->locs[i], dax_s->uuid);
                if (rc)
                        break;
        }
@@ -808,8 +796,7 @@ static int check_dax_create(struct ndctl_region *region,
 
 static int __check_pfn_create(struct ndctl_region *region,
                struct ndctl_namespace *ndns, struct namespace *namespace,
-               void *buf, enum ndctl_pfn_loc loc, unsigned long align,
-               uuid_t uuid)
+               void *buf, enum ndctl_pfn_loc loc, uuid_t uuid)
 {
        struct ndctl_pfn *pfn_seed = ndctl_region_get_pfn_seed(region);
        enum ndctl_namespace_mode mode;
@@ -826,17 +813,16 @@ static int __check_pfn_create(struct ndctl_region *region,
        devname = ndctl_pfn_get_devname(pfn);
        ndctl_pfn_set_uuid(pfn, uuid);
        ndctl_pfn_set_location(pfn, loc);
-       ndctl_pfn_set_align(pfn, align);
+       /*
+        * nfit_test uses vmalloc()'d resources so the only feasible
+        * alignment is PAGE_SIZE
+        */
+       ndctl_pfn_set_align(pfn, SZ_4K);
        ndctl_pfn_set_namespace(pfn, ndns);
        rc = ndctl_pfn_enable(pfn);
-       if (align == SZ_1G) {
-               if (rc == 0) {
-                       fprintf(stderr, "%s: expected pfn enable failure with 
align: %lx\n",
-                                       devname, align);
-                       return -ENXIO;
-               }
-               ndctl_pfn_delete(pfn);
-               return 0;
+       if (rc) {
+               fprintf(stderr, "%s: failed to enable pfn\n", devname);
+               return rc;
        }
 
        mode = ndctl_namespace_get_mode(ndns);
@@ -917,8 +903,8 @@ static int check_pfn_create(struct ndctl_region *region,
                struct ndctl_namespace *ndns, struct namespace *namespace)
 {
        struct pfn *pfn_s = namespace->pfn_settings;
-       unsigned int i, j;
        void *buf = NULL;
+       unsigned int i;
        int rc = 0;
 
        if (!pfn_s)
@@ -928,19 +914,14 @@ static int check_pfn_create(struct ndctl_region *region,
                return -ENXIO;
 
        for (i = 0; i < ARRAY_SIZE(pfn_s->locs); i++) {
-               for (j = 0; j < ARRAY_SIZE(pfn_s->aligns); j++) {
-                       /*
-                        * The kernel enforces invalidating the previous
-                        * info block when the current uuid is does not
-                        * validate with the contents of the info block.
-                        */
-                       pfn_s->uuid[0]++;
-                       rc = __check_pfn_create(region, ndns, namespace, buf,
-                                       pfn_s->locs[i], pfn_s->aligns[j],
-                                       pfn_s->uuid);
-                       if (rc)
-                               break;
-               }
+               /*
+                * The kernel enforces invalidating the previous info
+                * block when the current uuid is does not validate with
+                * the contents of the info block.
+                */
+               pfn_s->uuid[0]++;
+               rc = __check_pfn_create(region, ndns, namespace, buf,
+                               pfn_s->locs[i], pfn_s->uuid);
                if (rc)
                        break;
        }
diff --git a/test/mmap.sh b/test/mmap.sh
index e66fb1369434..fa2658a6c57c 100755
--- a/test/mmap.sh
+++ b/test/mmap.sh
@@ -3,6 +3,8 @@ MNT=test_mmap_mnt
 FILE=image
 DEV=""
 TEST=./mmap
+NDCTL="../ndctl/ndctl"
+json2var="s/[{}\",]//g; s/:/=/g"
 
 err() {
        rc=1
@@ -46,7 +48,10 @@ set -e
 mkdir -p $MNT
 trap 'err $LINENO' ERR
 
-DEV=$(./dax-dev)
+dev=$(./dax-dev)
+json=$($NDCTL list -N -n $dev)
+eval $(echo $json | sed -e "$json2var")
+DEV="/dev/${blockdev}"
 
 mkfs.ext4 $DEV
 mount $DEV $MNT -o dax

_______________________________________________
Linux-nvdimm mailing list
[email protected]
https://lists.01.org/mailman/listinfo/linux-nvdimm

Reply via email to