diff for duplicates of <20141006150351.GA23754@node.dhcp.inet.fi> diff --git a/a/1.txt b/N1/1.txt index 15c7be1..05356e7 100644 --- a/a/1.txt +++ b/N1/1.txt @@ -31,3 +31,145 @@ My proposal is below. Build-tested only. And I don't think this is subject for stable@: no crash or serious misbehaviour. Registering to khugepaged is postponed until first page fault. Not a big deal. + +>From 6434d87a313317bcbc98313794840c366ba39ba1 Mon Sep 17 00:00:00 2001 +From: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> +Date: Mon, 6 Oct 2014 17:52:17 +0300 +Subject: [PATCH] thp: fix registering VMA into khugepaged on + madvise(MADV_HUGEPAGE) + +hugepage_madvise() tries to register VMA into khugepaged with +khugepaged_enter_vma_merge() on madvise(MADV_HUGEPAGE). Unfortunately +it's effectevely nop, since khugepaged_enter_vma_merge() rely on +vma->vm_flags which has not yet updated by the time of +hugepage_madvise(). + +Let's create a variant of khugepaged_enter_vma_merge() which takes +external vm_flags to consider. At the moment there's only two users for +such function: hugepage_madvise() and vma_merge(). + +Reported-by: Suleiman Souhlal <suleiman@google.com> +Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> +--- + include/linux/khugepaged.h | 9 +++++++++ + mm/huge_memory.c | 27 ++++++++++++++++++++------- + mm/mmap.c | 6 +++--- + 3 files changed, 32 insertions(+), 10 deletions(-) + +diff --git a/include/linux/khugepaged.h b/include/linux/khugepaged.h +index 6b394f0b5148..bb25e323ee2d 100644 +--- a/include/linux/khugepaged.h ++++ b/include/linux/khugepaged.h +@@ -7,6 +7,8 @@ + extern int __khugepaged_enter(struct mm_struct *mm); + extern void __khugepaged_exit(struct mm_struct *mm); + extern int khugepaged_enter_vma_merge(struct vm_area_struct *vma); ++extern int __khugepaged_enter_vma_merge(struct vm_area_struct *vma, ++ vm_flags_t vm_flags); + + #define khugepaged_enabled() \ + (transparent_hugepage_flags & \ +@@ -62,6 +64,13 @@ static inline int khugepaged_enter_vma_merge(struct vm_area_struct *vma) + { + return 0; + } ++ ++static inline int __khugepaged_enter_vma_merge(struct vm_area_struct *vma, ++ vm_flags_t vm_flags) ++{ ++ return 0; ++} ++ + #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ + + #endif /* _LINUX_KHUGEPAGED_H */ +diff --git a/mm/huge_memory.c b/mm/huge_memory.c +index 017aff657ef5..4b0afc076827 100644 +--- a/mm/huge_memory.c ++++ b/mm/huge_memory.c +@@ -1944,7 +1944,7 @@ out: + #define VM_NO_THP (VM_SPECIAL | VM_HUGETLB | VM_SHARED | VM_MAYSHARE) + + int hugepage_madvise(struct vm_area_struct *vma, +- unsigned long *vm_flags, int advice) ++ vm_flags_t *vm_flags, int advice) + { + switch (advice) { + case MADV_HUGEPAGE: +@@ -1969,8 +1969,7 @@ int hugepage_madvise(struct vm_area_struct *vma, + * register it here without waiting a page fault that + * may not happen any time soon. + */ +- if (unlikely(khugepaged_enter_vma_merge(vma))) +- return -ENOMEM; ++ return __khugepaged_enter_vma_merge(vma, *vm_flags); + break; + case MADV_NOHUGEPAGE: + /* +@@ -2070,7 +2069,8 @@ int __khugepaged_enter(struct mm_struct *mm) + return 0; + } + +-int khugepaged_enter_vma_merge(struct vm_area_struct *vma) ++int __khugepaged_enter_vma_merge(struct vm_area_struct *vma, ++ vm_flags_t vm_flags) + { + unsigned long hstart, hend; + if (!vma->anon_vma) +@@ -2082,14 +2082,27 @@ int khugepaged_enter_vma_merge(struct vm_area_struct *vma) + if (vma->vm_ops) + /* khugepaged not yet working on file or special mappings */ + return 0; +- VM_BUG_ON(vma->vm_flags & VM_NO_THP); ++ VM_BUG_ON(vm_flags & VM_NO_THP); + hstart = (vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK; + hend = vma->vm_end & HPAGE_PMD_MASK; +- if (hstart < hend) +- return khugepaged_enter(vma); ++ if (hstart >= hend) ++ return 0; ++ if (test_bit(MMF_VM_HUGEPAGE, &vma->vm_mm->flags)) ++ return 0; ++ if (vm_flags & VM_NOHUGEPAGE) ++ return 0; ++ if (khugepaged_always()) ++ return __khugepaged_enter(vma->vm_mm); ++ if (khugepaged_req_madv() && vm_flags & VM_HUGEPAGE) ++ return __khugepaged_enter(vma->vm_mm); + return 0; + } + ++int khugepaged_enter_vma_merge(struct vm_area_struct *vma) ++{ ++ return __khugepaged_enter_vma_merge(vma, vma->vm_flags); ++} ++ + void __khugepaged_exit(struct mm_struct *mm) + { + struct mm_slot *mm_slot; +diff --git a/mm/mmap.c b/mm/mmap.c +index c0a3637cdb64..19fee85f0b12 100644 +--- a/mm/mmap.c ++++ b/mm/mmap.c +@@ -1009,8 +1009,8 @@ can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags, + */ + struct vm_area_struct *vma_merge(struct mm_struct *mm, + struct vm_area_struct *prev, unsigned long addr, +- unsigned long end, unsigned long vm_flags, +- struct anon_vma *anon_vma, struct file *file, ++ unsigned long end, vm_flags_t vm_flags, ++ struct anon_vma *anon_vma, struct file *file, + pgoff_t pgoff, struct mempolicy *policy) + { + pgoff_t pglen = (end - addr) >> PAGE_SHIFT; +@@ -1056,7 +1056,7 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm, + end, prev->vm_pgoff, NULL); + if (err) + return NULL; +- khugepaged_enter_vma_merge(prev); ++ __khugepaged_enter_vma_merge(prev, vm_flags); + return prev; + } + +-- + Kirill A. Shutemov diff --git a/a/content_digest b/N1/content_digest index 5d4d2b0..4522bc6 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -45,6 +45,148 @@ "\n" "And I don't think this is subject for stable@: no crash or serious\n" "misbehaviour. Registering to khugepaged is postponed until first page\n" - fault. Not a big deal. + "fault. Not a big deal.\n" + "\n" + ">From 6434d87a313317bcbc98313794840c366ba39ba1 Mon Sep 17 00:00:00 2001\n" + "From: \"Kirill A. Shutemov\" <kirill.shutemov@linux.intel.com>\n" + "Date: Mon, 6 Oct 2014 17:52:17 +0300\n" + "Subject: [PATCH] thp: fix registering VMA into khugepaged on \n" + " madvise(MADV_HUGEPAGE)\n" + "\n" + "hugepage_madvise() tries to register VMA into khugepaged with\n" + "khugepaged_enter_vma_merge() on madvise(MADV_HUGEPAGE). Unfortunately\n" + "it's effectevely nop, since khugepaged_enter_vma_merge() rely on\n" + "vma->vm_flags which has not yet updated by the time of\n" + "hugepage_madvise().\n" + "\n" + "Let's create a variant of khugepaged_enter_vma_merge() which takes\n" + "external vm_flags to consider. At the moment there's only two users for\n" + "such function: hugepage_madvise() and vma_merge().\n" + "\n" + "Reported-by: Suleiman Souhlal <suleiman@google.com>\n" + "Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>\n" + "---\n" + " include/linux/khugepaged.h | 9 +++++++++\n" + " mm/huge_memory.c | 27 ++++++++++++++++++++-------\n" + " mm/mmap.c | 6 +++---\n" + " 3 files changed, 32 insertions(+), 10 deletions(-)\n" + "\n" + "diff --git a/include/linux/khugepaged.h b/include/linux/khugepaged.h\n" + "index 6b394f0b5148..bb25e323ee2d 100644\n" + "--- a/include/linux/khugepaged.h\n" + "+++ b/include/linux/khugepaged.h\n" + "@@ -7,6 +7,8 @@\n" + " extern int __khugepaged_enter(struct mm_struct *mm);\n" + " extern void __khugepaged_exit(struct mm_struct *mm);\n" + " extern int khugepaged_enter_vma_merge(struct vm_area_struct *vma);\n" + "+extern int __khugepaged_enter_vma_merge(struct vm_area_struct *vma,\n" + "+\t\tvm_flags_t vm_flags);\n" + " \n" + " #define khugepaged_enabled()\t\t\t\t\t \\\n" + " \t(transparent_hugepage_flags &\t\t\t\t \\\n" + "@@ -62,6 +64,13 @@ static inline int khugepaged_enter_vma_merge(struct vm_area_struct *vma)\n" + " {\n" + " \treturn 0;\n" + " }\n" + "+\n" + "+static inline int __khugepaged_enter_vma_merge(struct vm_area_struct *vma,\n" + "+\t\tvm_flags_t vm_flags)\n" + "+{\n" + "+\treturn 0;\n" + "+}\n" + "+\n" + " #endif /* CONFIG_TRANSPARENT_HUGEPAGE */\n" + " \n" + " #endif /* _LINUX_KHUGEPAGED_H */\n" + "diff --git a/mm/huge_memory.c b/mm/huge_memory.c\n" + "index 017aff657ef5..4b0afc076827 100644\n" + "--- a/mm/huge_memory.c\n" + "+++ b/mm/huge_memory.c\n" + "@@ -1944,7 +1944,7 @@ out:\n" + " #define VM_NO_THP (VM_SPECIAL | VM_HUGETLB | VM_SHARED | VM_MAYSHARE)\n" + " \n" + " int hugepage_madvise(struct vm_area_struct *vma,\n" + "-\t\t unsigned long *vm_flags, int advice)\n" + "+\t\t vm_flags_t *vm_flags, int advice)\n" + " {\n" + " \tswitch (advice) {\n" + " \tcase MADV_HUGEPAGE:\n" + "@@ -1969,8 +1969,7 @@ int hugepage_madvise(struct vm_area_struct *vma,\n" + " \t\t * register it here without waiting a page fault that\n" + " \t\t * may not happen any time soon.\n" + " \t\t */\n" + "-\t\tif (unlikely(khugepaged_enter_vma_merge(vma)))\n" + "-\t\t\treturn -ENOMEM;\n" + "+\t\treturn __khugepaged_enter_vma_merge(vma, *vm_flags);\n" + " \t\tbreak;\n" + " \tcase MADV_NOHUGEPAGE:\n" + " \t\t/*\n" + "@@ -2070,7 +2069,8 @@ int __khugepaged_enter(struct mm_struct *mm)\n" + " \treturn 0;\n" + " }\n" + " \n" + "-int khugepaged_enter_vma_merge(struct vm_area_struct *vma)\n" + "+int __khugepaged_enter_vma_merge(struct vm_area_struct *vma,\n" + "+\t\tvm_flags_t vm_flags)\n" + " {\n" + " \tunsigned long hstart, hend;\n" + " \tif (!vma->anon_vma)\n" + "@@ -2082,14 +2082,27 @@ int khugepaged_enter_vma_merge(struct vm_area_struct *vma)\n" + " \tif (vma->vm_ops)\n" + " \t\t/* khugepaged not yet working on file or special mappings */\n" + " \t\treturn 0;\n" + "-\tVM_BUG_ON(vma->vm_flags & VM_NO_THP);\n" + "+\tVM_BUG_ON(vm_flags & VM_NO_THP);\n" + " \thstart = (vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK;\n" + " \thend = vma->vm_end & HPAGE_PMD_MASK;\n" + "-\tif (hstart < hend)\n" + "-\t\treturn khugepaged_enter(vma);\n" + "+\tif (hstart >= hend)\n" + "+\t\treturn 0;\n" + "+\tif (test_bit(MMF_VM_HUGEPAGE, &vma->vm_mm->flags))\n" + "+\t\treturn 0;\n" + "+\tif (vm_flags & VM_NOHUGEPAGE)\n" + "+\t\treturn 0;\n" + "+\tif (khugepaged_always())\n" + "+\t\treturn __khugepaged_enter(vma->vm_mm);\n" + "+\tif (khugepaged_req_madv() && vm_flags & VM_HUGEPAGE)\n" + "+\t\treturn __khugepaged_enter(vma->vm_mm);\n" + " \treturn 0;\n" + " }\n" + " \n" + "+int khugepaged_enter_vma_merge(struct vm_area_struct *vma)\n" + "+{\n" + "+\treturn __khugepaged_enter_vma_merge(vma, vma->vm_flags);\n" + "+}\n" + "+\n" + " void __khugepaged_exit(struct mm_struct *mm)\n" + " {\n" + " \tstruct mm_slot *mm_slot;\n" + "diff --git a/mm/mmap.c b/mm/mmap.c\n" + "index c0a3637cdb64..19fee85f0b12 100644\n" + "--- a/mm/mmap.c\n" + "+++ b/mm/mmap.c\n" + "@@ -1009,8 +1009,8 @@ can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags,\n" + " */\n" + " struct vm_area_struct *vma_merge(struct mm_struct *mm,\n" + " \t\t\tstruct vm_area_struct *prev, unsigned long addr,\n" + "-\t\t\tunsigned long end, unsigned long vm_flags,\n" + "-\t\t \tstruct anon_vma *anon_vma, struct file *file,\n" + "+\t\t\tunsigned long end, vm_flags_t vm_flags,\n" + "+\t\t\tstruct anon_vma *anon_vma, struct file *file,\n" + " \t\t\tpgoff_t pgoff, struct mempolicy *policy)\n" + " {\n" + " \tpgoff_t pglen = (end - addr) >> PAGE_SHIFT;\n" + "@@ -1056,7 +1056,7 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm,\n" + " \t\t\t\tend, prev->vm_pgoff, NULL);\n" + " \t\tif (err)\n" + " \t\t\treturn NULL;\n" + "-\t\tkhugepaged_enter_vma_merge(prev);\n" + "+\t\t__khugepaged_enter_vma_merge(prev, vm_flags);\n" + " \t\treturn prev;\n" + " \t}\n" + " \n" + "-- \n" + Kirill A. Shutemov -1b7d1b0796b5d22700f42a96362701eac76a260b0c1b3d5c2050ba2f4a9d30c5 +2e5293cc701f505b046ee9de1e723b6d4b657950e34856a65f7f924d4e8d9566
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.