From: Greg Kroah-Hartman Date: Thu, 11 Aug 2016 16:58:39 +0000 (+0200) Subject: 4.6-stable patches X-Git-Tag: v3.14.76~25 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=21e9e0c1a8a210886d6eb272542b9dee96385bf7;p=thirdparty%2Fkernel%2Fstable-queue.git 4.6-stable patches 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 --- 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 index 00000000000..fa5e4d3ef41 --- /dev/null +++ b/queue-4.6/libnvdimm-dax-record-the-specified-alignment-of-a-dax-device-instance.patch @@ -0,0 +1,72 @@ +From 45a0dac0451136fa7ae34a6fea53ef6a136287ce Mon Sep 17 00:00:00 2001 +From: Dan Williams +Date: Thu, 31 Mar 2016 15:41:18 -0700 +Subject: libnvdimm, dax: record the specified alignment of a dax-device instance + +From: Dan Williams + +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 +Signed-off-by: Greg Kroah-Hartman + + +--- + 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 index 00000000000..af5c8acea1f --- /dev/null +++ b/queue-4.6/libnvdimm-pfn-dax-fix-initialization-vs-autodetect-for-mode-alignment.patch @@ -0,0 +1,134 @@ +From 1ee6667cd8d183b2fed12f97285f184431d2caf9 Mon Sep 17 00:00:00 2001 +From: Dan Williams +Date: Thu, 23 Jun 2016 17:50:39 -0700 +Subject: libnvdimm, pfn, dax: fix initialization vs autodetect for mode + alignment + +From: Dan Williams + +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 +Cc: Toshi Kani +Signed-off-by: Dan Williams +Signed-off-by: Greg Kroah-Hartman + + +--- + 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 index 00000000000..b3708f9e5f1 --- /dev/null +++ b/queue-4.6/series @@ -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