All of lore.kernel.org
 help / color / mirror / Atom feed
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.