Message ID | 20230406175556.452442-1-jane.chu@oracle.com (mailing list archive) |
---|---|
State | Mainlined, archived |
Headers | show |
Series | dax: enable dax fault handler to report VM_FAULT_HWPOISON | expand |
On Thu, Apr 06, 2023 at 11:55:56AM -0600, Jane Chu wrote: > static vm_fault_t dax_fault_return(int error) > { > if (error == 0) > return VM_FAULT_NOPAGE; > - return vmf_error(error); > + else if (error == -ENOMEM) > + return VM_FAULT_OOM; > + else if (error == -EHWPOISON) > + return VM_FAULT_HWPOISON; > + return VM_FAULT_SIGBUS; > } Why would we want to handle it here instead of changing vmf_error()?
On 4/6/2023 12:32 PM, Matthew Wilcox wrote: > On Thu, Apr 06, 2023 at 11:55:56AM -0600, Jane Chu wrote: >> static vm_fault_t dax_fault_return(int error) >> { >> if (error == 0) >> return VM_FAULT_NOPAGE; >> - return vmf_error(error); >> + else if (error == -ENOMEM) >> + return VM_FAULT_OOM; >> + else if (error == -EHWPOISON) >> + return VM_FAULT_HWPOISON; >> + return VM_FAULT_SIGBUS; >> } > > Why would we want to handle it here instead of changing vmf_error()? I think it's related to the comment about the the corrupted range of a hwpoison caused fault - something no need to worry about now. I will move the change to vmf_error() in a respin. Thanks! -jane
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index ceea55f621cc..46e094e56159 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -260,7 +260,7 @@ __weak long __pmem_direct_access(struct pmem_device *pmem, pgoff_t pgoff, long actual_nr; if (mode != DAX_RECOVERY_WRITE) - return -EIO; + return -EHWPOISON; /* * Set the recovery stride is set to kernel page size because diff --git a/fs/dax.c b/fs/dax.c index 3e457a16c7d1..3f22686abc88 100644 --- a/fs/dax.c +++ b/fs/dax.c @@ -1456,7 +1456,7 @@ static loff_t dax_iomap_iter(const struct iomap_iter *iomi, map_len = dax_direct_access(dax_dev, pgoff, PHYS_PFN(size), DAX_ACCESS, &kaddr, NULL); - if (map_len == -EIO && iov_iter_rw(iter) == WRITE) { + if (map_len == -EHWPOISON && iov_iter_rw(iter) == WRITE) { map_len = dax_direct_access(dax_dev, pgoff, PHYS_PFN(size), DAX_RECOVERY_WRITE, &kaddr, NULL); @@ -1550,11 +1550,21 @@ dax_iomap_rw(struct kiocb *iocb, struct iov_iter *iter, } EXPORT_SYMBOL_GPL(dax_iomap_rw); +/* + * Concerning hwpoison triggered page fault: dax is THP, a pmd + * level fault handler will fallback (VM_FAULT_FALLBACK) before + * give up, hence return VM_FAULT_HWPOISON which implies + * corrupted range is PAGE_SIZE. + */ static vm_fault_t dax_fault_return(int error) { if (error == 0) return VM_FAULT_NOPAGE; - return vmf_error(error); + else if (error == -ENOMEM) + return VM_FAULT_OOM; + else if (error == -EHWPOISON) + return VM_FAULT_HWPOISON; + return VM_FAULT_SIGBUS; } /*
When dax fault handler fails to provision the fault page due to hwpoison, it returns VM_FAULT_SIGBUS which lead to a sigbus delivered to userspace with .si_code BUS_ADRERR. Channel dax backend driver's detection on hwpoison to the filesystem to provide the precise reason for the fault. Signed-off-by: Jane Chu <jane.chu@oracle.com> --- drivers/nvdimm/pmem.c | 2 +- fs/dax.c | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-)