aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-04-15 15:34:27 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2016-04-15 15:34:27 -0700
commitf3c9a1abbe9d4c9565fdb0755e2c7814f32d4f62 (patch)
tree14e3ad5ade1e2f1b806fc466f30c1854866e85c4 /drivers
parentMerge tag 'for-linus-20160415' of git://git.infradead.org/linux-mtd (diff)
parentlibnvdimm, pmem: clarify the write+clear_poison+write flow (diff)
downloadlinux-dev-f3c9a1abbe9d4c9565fdb0755e2c7814f32d4f62.tar.xz
linux-dev-f3c9a1abbe9d4c9565fdb0755e2c7814f32d4f62.zip
Merge branch 'libnvdimm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm
Pull libnvdimm fixes from Ross Zwisler: "Two fixes: - Fix memcpy_from_pmem() to fallback to memcpy() for architectures where CONFIG_ARCH_HAS_PMEM_API=n. - Add a comment explaining why we write data twice when clearing poison in pmem_do_bvec(). This has passed a boot test on an X86_32 config, which was the architecture where issue #1 above was first noticed" Dan Williams adds: "We're giving this multi-maintainer setup a shot, so expect libnvdimm pull requests from either Ross or I going forward" * 'libnvdimm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm: libnvdimm, pmem: clarify the write+clear_poison+write flow pmem: fix BUG() error in pmem.h:48 on X86_32
Diffstat (limited to 'drivers')
-rw-r--r--drivers/nvdimm/pmem.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
index 8e09c544d892..f798899338ed 100644
--- a/drivers/nvdimm/pmem.c
+++ b/drivers/nvdimm/pmem.c
@@ -103,6 +103,20 @@ static int pmem_do_bvec(struct pmem_device *pmem, struct page *page,
flush_dcache_page(page);
}
} else {
+ /*
+ * Note that we write the data both before and after
+ * clearing poison. The write before clear poison
+ * handles situations where the latest written data is
+ * preserved and the clear poison operation simply marks
+ * the address range as valid without changing the data.
+ * In this case application software can assume that an
+ * interrupted write will either return the new good
+ * data or an error.
+ *
+ * However, if pmem_clear_poison() leaves the data in an
+ * indeterminate state we need to perform the write
+ * after clear poison.
+ */
flush_dcache_page(page);
memcpy_to_pmem(pmem_addr, mem + off, len);
if (unlikely(bad_pmem)) {