mm/gup.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/mm/gup.c b/mm/gup.c index ef29641671c7..c9d799d28de7 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -1091,6 +1091,21 @@ static int check_vma_flags(struct vm_area_struct *vma, unsigned long gup_flags) return 0; } +static void gup_stack_expansion_warning(const struct vm_area_struct *vma, + unsigned long addr) +{ + static volatile unsigned long next_warn; + unsigned long now = jiffies, next = next_warn; + + /* Let's not warn more than once an hour.. */ + if (next && time_before(now, next)) + return; + next_warn = now + 60*60*HZ; + pr_warn("GUP no longer grows the stack %lx-%lx (%lx)\n", + vma->vm_start, vma->vm_end, addr); + dump_stack(); +} + /** * __get_user_pages() - pin user pages in memory * @mm: mm_struct of target mm @@ -1170,7 +1185,8 @@ static long __get_user_pages(struct mm_struct *mm, if (!vma || start >= vma->vm_end) { vma = find_vma(mm, start); if (vma && (start < vma->vm_start)) { - WARN_ON_ONCE(vma->vm_flags & VM_GROWSDOWN); + if (unlikely(vma->vm_flags & VM_GROWSDOWN)) + gup_stack_expansion_warning(vma, start); vma = NULL; } if (!vma && in_gate_area(mm, start)) {