On Thu, Jan 27, 2022 at 4:41 AM Shiyang Ruan <ruansy.fnst@xxxxxxxxxxx> wrote: > > This function is called at the end of RMAP routine, i.e. filesystem > recovery function, to collect and kill processes using a shared page of > DAX file. The difference with mf_generic_kill_procs() is, it accepts > file's (mapping,offset) instead of struct page because different files' > mappings and offsets may share the same page in fsdax mode. > It will be called when filesystem's RMAP results are found. > > Signed-off-by: Shiyang Ruan <ruansy.fnst@xxxxxxxxxxx> > --- > include/linux/mm.h | 4 ++ > mm/memory-failure.c | 91 +++++++++++++++++++++++++++++++++++++++------ > 2 files changed, 84 insertions(+), 11 deletions(-) > > diff --git a/include/linux/mm.h b/include/linux/mm.h > index 9b1d56c5c224..0420189e4788 100644 > --- a/include/linux/mm.h > +++ b/include/linux/mm.h > @@ -3195,6 +3195,10 @@ enum mf_flags { > MF_SOFT_OFFLINE = 1 << 3, > MF_UNPOISON = 1 << 4, > }; > +#if IS_ENABLED(CONFIG_FS_DAX) > +int mf_dax_kill_procs(struct address_space *mapping, pgoff_t index, > + unsigned long count, int mf_flags); > +#endif /* CONFIG_FS_DAX */ > extern int memory_failure(unsigned long pfn, int flags); > extern void memory_failure_queue(unsigned long pfn, int flags); > extern void memory_failure_queue_kick(int cpu); > diff --git a/mm/memory-failure.c b/mm/memory-failure.c > index b2d13eba1071..8d123cc4102e 100644 > --- a/mm/memory-failure.c > +++ b/mm/memory-failure.c > @@ -304,10 +304,9 @@ void shake_page(struct page *p) > } > EXPORT_SYMBOL_GPL(shake_page); > > -static unsigned long dev_pagemap_mapping_shift(struct page *page, > - struct vm_area_struct *vma) > +static unsigned long dev_pagemap_mapping_shift(struct vm_area_struct *vma, > + unsigned long address) > { > - unsigned long address = vma_address(page, vma); > unsigned long ret = 0; > pgd_t *pgd; > p4d_t *p4d; > @@ -347,9 +346,8 @@ static unsigned long dev_pagemap_mapping_shift(struct page *page, > * Schedule a process for later kill. > * Uses GFP_ATOMIC allocations to avoid potential recursions in the VM. > */ > -static void add_to_kill(struct task_struct *tsk, struct page *p, > - struct vm_area_struct *vma, > - struct list_head *to_kill) > +static void add_to_kill(struct task_struct *tsk, struct page *p, pgoff_t pgoff, > + struct vm_area_struct *vma, struct list_head *to_kill) > { > struct to_kill *tk; > > @@ -360,9 +358,15 @@ static void add_to_kill(struct task_struct *tsk, struct page *p, > } > > tk->addr = page_address_in_vma(p, vma); > - if (is_zone_device_page(p)) > - tk->size_shift = dev_pagemap_mapping_shift(p, vma); > - else > + if (is_zone_device_page(p)) { > + /* > + * Since page->mapping is not used for fsdax, we need > + * calculate the address based on the vma. > + */ > + if (p->pgmap->type == MEMORY_DEVICE_FS_DAX) > + tk->addr = vma_pgoff_address(vma, pgoff); > + tk->size_shift = dev_pagemap_mapping_shift(vma, tk->addr); > + } else > tk->size_shift = page_shift(compound_head(p)); > > /* > @@ -510,7 +514,7 @@ static void collect_procs_anon(struct page *page, struct list_head *to_kill, > if (!page_mapped_in_vma(page, vma)) > continue; > if (vma->vm_mm == t->mm) > - add_to_kill(t, page, vma, to_kill); > + add_to_kill(t, page, 0, vma, to_kill); Why is the @pgoff argument 0? @pgoff is available. Not that I expect dax pages will ever be anonymous, might as well not leave that land mine for future refactoring. Other than that you can add: Reviewed-by: Dan Williams <dan.j.williams@xxxxxxxxx>