提交 3115bb02 编写于 作者: T Toshi Kani 提交者: Dan Williams

pmem: report error on clear poison failure

ACPI Clear Uncorrectable Error DSM function may fail or may be
unsupported on a platform.  pmem_clear_poison() returns without clearing
badblocks in such cases.  This failure is detected at the next read
(-EIO).

This behavior can lead to an issue when user keeps writing but does not
read immediately.  For instance, flight recorder file may be only read
when it is necessary for troubleshooting.

Change pmem_do_bvec() and pmem_clear_poison() to return -EIO so that
filesystem can log an error message on a write error.

Cc: Vishal Verma <vishal.l.verma@intel.com>
Signed-off-by: NToshi Kani <toshi.kani@hpe.com>
Signed-off-by: NDan Williams <dan.j.williams@intel.com>
上级 75d29713
...@@ -47,7 +47,7 @@ static struct nd_region *to_region(struct pmem_device *pmem) ...@@ -47,7 +47,7 @@ static struct nd_region *to_region(struct pmem_device *pmem)
return to_nd_region(to_dev(pmem)->parent); return to_nd_region(to_dev(pmem)->parent);
} }
static void pmem_clear_poison(struct pmem_device *pmem, phys_addr_t offset, static int pmem_clear_poison(struct pmem_device *pmem, phys_addr_t offset,
unsigned int len) unsigned int len)
{ {
struct device *dev = to_dev(pmem); struct device *dev = to_dev(pmem);
...@@ -62,8 +62,12 @@ static void pmem_clear_poison(struct pmem_device *pmem, phys_addr_t offset, ...@@ -62,8 +62,12 @@ static void pmem_clear_poison(struct pmem_device *pmem, phys_addr_t offset,
__func__, (unsigned long long) sector, __func__, (unsigned long long) sector,
cleared / 512, cleared / 512 > 1 ? "s" : ""); cleared / 512, cleared / 512 > 1 ? "s" : "");
badblocks_clear(&pmem->bb, sector, cleared / 512); badblocks_clear(&pmem->bb, sector, cleared / 512);
} else {
return -EIO;
} }
invalidate_pmem(pmem->virt_addr + offset, len); invalidate_pmem(pmem->virt_addr + offset, len);
return 0;
} }
static void write_pmem(void *pmem_addr, struct page *page, static void write_pmem(void *pmem_addr, struct page *page,
...@@ -123,7 +127,7 @@ static int pmem_do_bvec(struct pmem_device *pmem, struct page *page, ...@@ -123,7 +127,7 @@ static int pmem_do_bvec(struct pmem_device *pmem, struct page *page,
flush_dcache_page(page); flush_dcache_page(page);
write_pmem(pmem_addr, page, off, len); write_pmem(pmem_addr, page, off, len);
if (unlikely(bad_pmem)) { if (unlikely(bad_pmem)) {
pmem_clear_poison(pmem, pmem_off, len); rc = pmem_clear_poison(pmem, pmem_off, len);
write_pmem(pmem_addr, page, off, len); write_pmem(pmem_addr, page, off, len);
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册