]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.6-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 11 Aug 2016 16:58:39 +0000 (18:58 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 11 Aug 2016 16:58:39 +0000 (18:58 +0200)
added patches:
libnvdimm-dax-record-the-specified-alignment-of-a-dax-device-instance.patch
libnvdimm-pfn-dax-fix-initialization-vs-autodetect-for-mode-alignment.patch

queue-4.6/libnvdimm-dax-record-the-specified-alignment-of-a-dax-device-instance.patch [new file with mode: 0644]
queue-4.6/libnvdimm-pfn-dax-fix-initialization-vs-autodetect-for-mode-alignment.patch [new file with mode: 0644]
queue-4.6/series [new file with mode: 0644]

diff --git a/queue-4.6/libnvdimm-dax-record-the-specified-alignment-of-a-dax-device-instance.patch b/queue-4.6/libnvdimm-dax-record-the-specified-alignment-of-a-dax-device-instance.patch
new file mode 100644 (file)
index 0000000..fa5e4d3
--- /dev/null
@@ -0,0 +1,72 @@
+From 45a0dac0451136fa7ae34a6fea53ef6a136287ce Mon Sep 17 00:00:00 2001
+From: Dan Williams <dan.j.williams@intel.com>
+Date: Thu, 31 Mar 2016 15:41:18 -0700
+Subject: libnvdimm, dax: record the specified alignment of a dax-device instance
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+commit 45a0dac0451136fa7ae34a6fea53ef6a136287ce upstream.
+
+We want to use the alignment as the allocation and mapping unit.
+Previously this information was only useful for establishing the data
+offset, but now it is important to remember the granularity for the
+later use.
+
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ drivers/nvdimm/pfn.h      |    4 +++-
+ drivers/nvdimm/pfn_devs.c |    5 ++++-
+ drivers/nvdimm/pmem.c     |    3 ++-
+ 3 files changed, 9 insertions(+), 3 deletions(-)
+
+--- a/drivers/nvdimm/pfn.h
++++ b/drivers/nvdimm/pfn.h
+@@ -33,7 +33,9 @@ struct nd_pfn_sb {
+       /* minor-version-1 additions for section alignment */
+       __le32 start_pad;
+       __le32 end_trunc;
+-      u8 padding[4004];
++      /* minor-version-2 record the base alignment of the mapping */
++      __le32 align;
++      u8 padding[4000];
+       __le64 checksum;
+ };
+--- a/drivers/nvdimm/pfn_devs.c
++++ b/drivers/nvdimm/pfn_devs.c
+@@ -360,6 +360,9 @@ int nd_pfn_validate(struct nd_pfn *nd_pf
+               pfn_sb->end_trunc = 0;
+       }
++      if (__le16_to_cpu(pfn_sb->version_minor) < 2)
++              pfn_sb->align = 0;
++
+       switch (le32_to_cpu(pfn_sb->mode)) {
+       case PFN_MODE_RAM:
+       case PFN_MODE_PMEM:
+@@ -399,7 +402,7 @@ int nd_pfn_validate(struct nd_pfn *nd_pf
+               return -EBUSY;
+       }
+-      nd_pfn->align = 1UL << ilog2(offset);
++      nd_pfn->align = le32_to_cpu(pfn_sb->align);
+       if (!is_power_of_2(offset) || offset < PAGE_SIZE) {
+               dev_err(&nd_pfn->dev, "bad offset: %#llx dax disabled\n",
+                               offset);
+--- a/drivers/nvdimm/pmem.c
++++ b/drivers/nvdimm/pmem.c
+@@ -426,9 +426,10 @@ static int nd_pfn_init(struct nd_pfn *nd
+       memcpy(pfn_sb->uuid, nd_pfn->uuid, 16);
+       memcpy(pfn_sb->parent_uuid, nd_dev_to_uuid(&ndns->dev), 16);
+       pfn_sb->version_major = cpu_to_le16(1);
+-      pfn_sb->version_minor = cpu_to_le16(1);
++      pfn_sb->version_minor = cpu_to_le16(2);
+       pfn_sb->start_pad = cpu_to_le32(start_pad);
+       pfn_sb->end_trunc = cpu_to_le32(end_trunc);
++      pfn_sb->align = cpu_to_le32(nd_pfn->align);
+       checksum = nd_sb_checksum((struct nd_gen_sb *) pfn_sb);
+       pfn_sb->checksum = cpu_to_le64(checksum);
diff --git a/queue-4.6/libnvdimm-pfn-dax-fix-initialization-vs-autodetect-for-mode-alignment.patch b/queue-4.6/libnvdimm-pfn-dax-fix-initialization-vs-autodetect-for-mode-alignment.patch
new file mode 100644 (file)
index 0000000..af5c8ac
--- /dev/null
@@ -0,0 +1,134 @@
+From 1ee6667cd8d183b2fed12f97285f184431d2caf9 Mon Sep 17 00:00:00 2001
+From: Dan Williams <dan.j.williams@intel.com>
+Date: Thu, 23 Jun 2016 17:50:39 -0700
+Subject: libnvdimm, pfn, dax: fix initialization vs autodetect for mode + alignment
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+commit 1ee6667cd8d183b2fed12f97285f184431d2caf9 upstream.
+
+The updated ndctl unit tests discovered that if a pfn configuration with
+a 4K alignment is read from the namespace, that alignment will be
+ignored in favor of the default 2M alignment.  The result is that the
+configuration will fail initialization with a message like:
+
+    dax6.1: bad offset: 0x22000 dax disabled align: 0x200000
+
+Fix this by allowing the alignment read from the info block to override
+the default which is 2M not 0 in the autodetect path.  This also fixes a
+similar problem with the mode and alignment settings silently being
+overwritten by the kernel when userspace has changed it.  We now will
+either overwrite the info block if userspace changes the uuid or fail
+and warn if a live setting disagrees with the info block.
+
+Cc: Micah Parrish <micah.parrish@hpe.com>
+Cc: Toshi Kani <toshi.kani@hpe.com>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ drivers/nvdimm/pfn_devs.c |   50 +++++++++++++++++++++++++++++++++++++---------
+ drivers/nvdimm/pmem.c     |    1 
+ 2 files changed, 41 insertions(+), 10 deletions(-)
+
+--- a/drivers/nvdimm/pfn_devs.c
++++ b/drivers/nvdimm/pfn_devs.c
+@@ -329,6 +329,8 @@ struct device *nd_pfn_create(struct nd_r
+ int nd_pfn_validate(struct nd_pfn *nd_pfn)
+ {
+       u64 checksum, offset;
++      unsigned long align;
++      enum nd_pfn_mode mode;
+       struct nd_namespace_io *nsio;
+       struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb;
+       struct nd_namespace_common *ndns = nd_pfn->ndns;
+@@ -371,20 +373,50 @@ int nd_pfn_validate(struct nd_pfn *nd_pf
+               return -ENXIO;
+       }
++      align = le32_to_cpu(pfn_sb->align);
++      offset = le64_to_cpu(pfn_sb->dataoff);
++      if (align == 0)
++              align = 1UL << ilog2(offset);
++      mode = le32_to_cpu(pfn_sb->mode);
++
+       if (!nd_pfn->uuid) {
+-              /* from probe we allocate */
++              /*
++               * When probing a namepace via nd_pfn_probe() the uuid
++               * is NULL (see: nd_pfn_devinit()) we init settings from
++               * pfn_sb
++               */
+               nd_pfn->uuid = kmemdup(pfn_sb->uuid, 16, GFP_KERNEL);
+               if (!nd_pfn->uuid)
+                       return -ENOMEM;
++              nd_pfn->align = align;
++              nd_pfn->mode = mode;
+       } else {
+-              /* from init we validate */
++              /*
++               * When probing a pfn / dax instance we validate the
++               * live settings against the pfn_sb
++               */
+               if (memcmp(nd_pfn->uuid, pfn_sb->uuid, 16) != 0)
+                       return -ENODEV;
++
++              /*
++               * If the uuid validates, but other settings mismatch
++               * return EINVAL because userspace has managed to change
++               * the configuration without specifying new
++               * identification.
++               */
++              if (nd_pfn->align != align || nd_pfn->mode != mode) {
++                      dev_err(&nd_pfn->dev,
++                                      "init failed, settings mismatch\n");
++                      dev_dbg(&nd_pfn->dev, "align: %lx:%lx mode: %d:%d\n",
++                                      nd_pfn->align, align, nd_pfn->mode,
++                                      mode);
++                      return -EINVAL;
++              }
+       }
+-      if (nd_pfn->align > nvdimm_namespace_capacity(ndns)) {
++      if (align > nvdimm_namespace_capacity(ndns)) {
+               dev_err(&nd_pfn->dev, "alignment: %lx exceeds capacity %llx\n",
+-                              nd_pfn->align, nvdimm_namespace_capacity(ndns));
++                              align, nvdimm_namespace_capacity(ndns));
+               return -EINVAL;
+       }
+@@ -394,7 +426,6 @@ int nd_pfn_validate(struct nd_pfn *nd_pf
+        * namespace has changed since the pfn superblock was
+        * established.
+        */
+-      offset = le64_to_cpu(pfn_sb->dataoff);
+       nsio = to_nd_namespace_io(&ndns->dev);
+       if (offset >= resource_size(&nsio->res)) {
+               dev_err(&nd_pfn->dev, "pfn array size exceeds capacity of %s\n",
+@@ -402,10 +433,11 @@ int nd_pfn_validate(struct nd_pfn *nd_pf
+               return -EBUSY;
+       }
+-      nd_pfn->align = le32_to_cpu(pfn_sb->align);
+-      if (!is_power_of_2(offset) || offset < PAGE_SIZE) {
+-              dev_err(&nd_pfn->dev, "bad offset: %#llx dax disabled\n",
+-                              offset);
++      if ((align && !IS_ALIGNED(offset, align))
++                      || !IS_ALIGNED(offset, PAGE_SIZE)) {
++              dev_err(&nd_pfn->dev,
++                              "bad offset: %#llx dax disabled align: %#lx\n",
++                              offset, align);
+               return -ENXIO;
+       }
+--- a/drivers/nvdimm/pmem.c
++++ b/drivers/nvdimm/pmem.c
+@@ -502,7 +502,6 @@ static int __nvdimm_namespace_attach_pfn
+       pmem = dev_get_drvdata(dev);
+       pmem->data_offset = le64_to_cpu(pfn_sb->dataoff);
+       pmem->pfn_pad = start_pad + end_trunc;
+-      nd_pfn->mode = le32_to_cpu(nd_pfn->pfn_sb->mode);
+       if (nd_pfn->mode == PFN_MODE_RAM) {
+               if (pmem->data_offset < SZ_8K)
+                       return -EINVAL;
diff --git a/queue-4.6/series b/queue-4.6/series
new file mode 100644 (file)
index 0000000..b3708f9
--- /dev/null
@@ -0,0 +1,2 @@
+libnvdimm-dax-record-the-specified-alignment-of-a-dax-device-instance.patch
+libnvdimm-pfn-dax-fix-initialization-vs-autodetect-for-mode-alignment.patch