[GIT PULL] libnvdimm fixes for 4.3-rc2
From: Williams, Dan J
Date: Sat Sep 19 2015 - 13:11:09 EST
Hi Linus, please pull from:
git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm libnvdimm-fixes
...to receive:
1/ A boot regression (since v4.2) fix for some ARM configurations from
Tyler
2/ Regression (since v4.1) fixes for mkfs.xfs on a DAX enabled device
from Jeff. These are tagged for -stable.
3/ A pair of locking fixes from Axel that are hidden from lockdep since
they involve device_lock(). The "btt" one is tagged for -stable, the
other only applies to the new "pfn" mechanism in v4.3.
4/ A fix for the pmem ->rw_page() path to use wmb_pmem() from Ross.
Full log and diff below.
---
The following changes since commit 6ff33f3902c3b1c5d0db6b1e2c70b6d76fba357f:
Linux 4.3-rc1 (2015-09-12 16:35:56 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm libnvdimm-fixes
for you to fetch changes up to ae4f976968896f8f41b3a7aa21be6146492211e5:
mm: fix type cast in __pfn_to_phys() (2015-09-19 03:58:10 -0400)
----------------------------------------------------------------
Axel Lin (2):
libnvdimm: btt_devs: Fix locking in namespace_store
libnvdimm: pfn_devs: Fix locking in namespace_store
Jeff Moyer (2):
dax: fix O_DIRECT I/O to the last block of a blockdev
blockdev: don't set S_DAX for misaligned partitions
Ross Zwisler (1):
pmem: add proper fencing to pmem_rw_page()
Tyler Baker (1):
mm: fix type cast in __pfn_to_phys()
drivers/nvdimm/btt_devs.c | 4 ++--
drivers/nvdimm/pfn_devs.c | 4 ++--
drivers/nvdimm/pmem.c | 2 ++
fs/block_dev.c | 7 +++++++
fs/dax.c | 3 ++-
include/asm-generic/memory_model.h | 2 +-
6 files changed, 16 insertions(+), 6 deletions(-)
commit ae4f976968896f8f41b3a7aa21be6146492211e5
Author: Tyler Baker <tyler.baker@xxxxxxxxxx>
Date: Sat Sep 19 03:58:10 2015 -0400
mm: fix type cast in __pfn_to_phys()
The various definitions of __pfn_to_phys() have been consolidated to
use a generic macro in include/asm-generic/memory_model.h. This hit
mainline in the form of 012dcef3f058 "mm: move __phys_to_pfn and
__pfn_to_phys to asm/generic/memory_model.h". When the generic macro
was implemented the type cast to phys_addr_t was dropped which caused
boot regressions on ARM platforms with more than 4GB of memory and
LPAE enabled.
It was suggested to use PFN_PHYS() defined in include/linux/pfn.h
as provides the correct logic and avoids further duplication.
Reported-by: kernelci.org bot <bot@xxxxxxxxxxxx>
Suggested-by: Dan Williams <dan.j.williams@xxxxxxxxx>
Signed-off-by: Tyler Baker <tyler.baker@xxxxxxxxxx>
Signed-off-by: Dan Williams <dan.j.williams@xxxxxxxxx>
commit ba8fe0f85e15d047686caf8a42463b592c63c98c
Author: Ross Zwisler <ross.zwisler@xxxxxxxxxxxxxxx>
Date: Wed Sep 16 14:52:21 2015 -0600
pmem: add proper fencing to pmem_rw_page()
pmem_rw_page() needs to call wmb_pmem() on writes to make sure that the
newly written data is durable. This flow was added to pmem_rw_bytes()
and pmem_make_request() with this commit:
commit 61031952f4c8 ("arch, x86: pmem api for ensuring durability of
persistent memory updates")
...the pmem_rw_page() path was missed.
Cc: <stable@xxxxxxxxxxxxxxx>
Signed-off-by: Ross Zwisler <ross.zwisler@xxxxxxxxxxxxxxx>
Signed-off-by: Dan Williams <dan.j.williams@xxxxxxxxx>
commit 4ca8b57a0af145f4e791f21dbca6ad789da9ee8b
Author: Axel Lin <axel.lin@xxxxxxxxxx>
Date: Wed Sep 16 21:25:38 2015 +0800
libnvdimm: pfn_devs: Fix locking in namespace_store
Always take device_lock() before nvdimm_bus_lock() to prevent deadlock.
Signed-off-by: Axel Lin <axel.lin@xxxxxxxxxx>
Signed-off-by: Dan Williams <dan.j.williams@xxxxxxxxx>
commit 4be9c1fc3df9c3b03c9bde8aec5e44fc73996a3f
Author: Axel Lin <axel.lin@xxxxxxxxxx>
Date: Wed Sep 16 21:24:47 2015 +0800
libnvdimm: btt_devs: Fix locking in namespace_store
Always take device_lock() before nvdimm_bus_lock() to prevent deadlock.
Cc: <stable@xxxxxxxxxxxxxxx>
Signed-off-by: Axel Lin <axel.lin@xxxxxxxxxx>
Signed-off-by: Dan Williams <dan.j.williams@xxxxxxxxx>
commit f0b2e563bc419df7c1b3d2f494574c25125f6aed
Author: Jeff Moyer <jmoyer@xxxxxxxxxx>
Date: Fri Aug 14 16:15:32 2015 -0400
blockdev: don't set S_DAX for misaligned partitions
The dax code doesn't currently support misaligned partitions,
so disable O_DIRECT via dax until such time as that support
materializes.
Cc: <stable@xxxxxxxxxxxxxxx>
Suggested-by: Boaz Harrosh <boaz@xxxxxxxxxxxxx>
Signed-off-by: Jeff Moyer <jmoyer@xxxxxxxxxx>
Signed-off-by: Dan Williams <dan.j.williams@xxxxxxxxx>
commit e94f5a2285fc94202a9efb2c687481f29b64132c
Author: Jeff Moyer <jmoyer@xxxxxxxxxx>
Date: Fri Aug 14 16:15:31 2015 -0400
dax: fix O_DIRECT I/O to the last block of a blockdev
commit bbab37ddc20b (block: Add support for DAX reads/writes to
block devices) caused a regression in mkfs.xfs. That utility
sets the block size of the device to the logical block size
using the BLKBSZSET ioctl, and then issues a single sector read
from the last sector of the device. This results in the dax_io
code trying to do a page-sized read from 512 bytes from the end
of the device. The result is -ERANGE being returned to userspace.
The fix is to align the block to the page size before calling
get_block.
Thanks to willy for simplifying my original patch.
Cc: <stable@xxxxxxxxxxxxxxx>
Signed-off-by: Jeff Moyer <jmoyer@xxxxxxxxxx>
Tested-by: Linda Knippers <linda.knippers@xxxxxx>
Signed-off-by: Dan Williams <dan.j.williams@xxxxxxxxx>
diff --git a/drivers/nvdimm/btt_devs.c b/drivers/nvdimm/btt_devs.c
index 59ad54a63d9f..cb477518dd0e 100644
--- a/drivers/nvdimm/btt_devs.c
+++ b/drivers/nvdimm/btt_devs.c
@@ -128,13 +128,13 @@ static ssize_t namespace_store(struct device *dev,
struct nd_btt *nd_btt = to_nd_btt(dev);
ssize_t rc;
- nvdimm_bus_lock(dev);
device_lock(dev);
+ nvdimm_bus_lock(dev);
rc = nd_namespace_store(dev, &nd_btt->ndns, buf, len);
dev_dbg(dev, "%s: result: %zd wrote: %s%s", __func__,
rc, buf, buf[len - 1] == '\n' ? "" : "\n");
- device_unlock(dev);
nvdimm_bus_unlock(dev);
+ device_unlock(dev);
return rc;
}
diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c
index 3fd7d0d81a47..71805a1aa0f3 100644
--- a/drivers/nvdimm/pfn_devs.c
+++ b/drivers/nvdimm/pfn_devs.c
@@ -148,13 +148,13 @@ static ssize_t namespace_store(struct device *dev,
struct nd_pfn *nd_pfn = to_nd_pfn(dev);
ssize_t rc;
- nvdimm_bus_lock(dev);
device_lock(dev);
+ nvdimm_bus_lock(dev);
rc = nd_namespace_store(dev, &nd_pfn->ndns, buf, len);
dev_dbg(dev, "%s: result: %zd wrote: %s%s", __func__,
rc, buf, buf[len - 1] == '\n' ? "" : "\n");
- device_unlock(dev);
nvdimm_bus_unlock(dev);
+ device_unlock(dev);
return rc;
}
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
index b9525385c0dc..0ba6a978f227 100644
--- a/drivers/nvdimm/pmem.c
+++ b/drivers/nvdimm/pmem.c
@@ -92,6 +92,8 @@ static int pmem_rw_page(struct block_device *bdev, sector_t sector,
struct pmem_device *pmem = bdev->bd_disk->private_data;
pmem_do_bvec(pmem, page, PAGE_CACHE_SIZE, 0, rw, sector);
+ if (rw & WRITE)
+ wmb_pmem();
page_endio(page, rw & WRITE, 0);
return 0;
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 22ea424ee741..073bb57adab1 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1242,6 +1242,13 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
goto out_clear;
}
bd_set_size(bdev, (loff_t)bdev->bd_part->nr_sects << 9);
+ /*
+ * If the partition is not aligned on a page
+ * boundary, we can't do dax I/O to it.
+ */
+ if ((bdev->bd_part->start_sect % (PAGE_SIZE / 512)) ||
+ (bdev->bd_part->nr_sects % (PAGE_SIZE / 512)))
+ bdev->bd_inode->i_flags &= ~S_DAX;
}
} else {
if (bdev->bd_contains == bdev) {
diff --git a/fs/dax.c b/fs/dax.c
index 93bf2f990ace..7ae6df7ea1d2 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -119,7 +119,8 @@ static ssize_t dax_io(struct inode *inode, struct iov_iter *iter,
size_t len;
if (pos == max) {
unsigned blkbits = inode->i_blkbits;
- sector_t block = pos >> blkbits;
+ long page = pos >> PAGE_SHIFT;
+ sector_t block = page << (PAGE_SHIFT - blkbits);
unsigned first = pos - (block << blkbits);
long size;
diff --git a/include/asm-generic/memory_model.h b/include/asm-generic/memory_model.h
index f20f407ce45d..4b4b056a6eb0 100644
--- a/include/asm-generic/memory_model.h
+++ b/include/asm-generic/memory_model.h
@@ -73,7 +73,7 @@
* Convert a physical address to a Page Frame Number and back
*/
#define __phys_to_pfn(paddr) ((unsigned long)((paddr) >> PAGE_SHIFT))
-#define __pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT)
+#define __pfn_to_phys(pfn) PFN_PHYS(pfn)
#define page_to_pfn __page_to_pfn
#define pfn_to_page __pfn_to_page