]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/3.1.1/powerpc-get_hugepte-don-t-put_page-the-wrong-page.patch
5.1-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 3.1.1 / powerpc-get_hugepte-don-t-put_page-the-wrong-page.patch
CommitLineData
b9e9b117
GKH
1From 405e44f2e312dd5dd63e5a9f459bffcbcd4368ef Mon Sep 17 00:00:00 2001
2From: Andrea Arcangeli <aarcange@redhat.com>
3Date: Wed, 2 Nov 2011 13:37:08 -0700
4Subject: powerpc: get_hugepte() don't put_page() the wrong page
5
6From: Andrea Arcangeli <aarcange@redhat.com>
7
8commit 405e44f2e312dd5dd63e5a9f459bffcbcd4368ef upstream.
9
10"page" may have changed to point to the next hugepage after the loop
11completed, The references have been taken on the head page, so the
12put_page must happen there too.
13
14This is a longstanding issue pre-thp inclusion.
15
16It's totally unclear how these page_cache_add_speculative and
17pte_val(pte) != pte_val(*ptep) checks are necessary across all the
18powerpc gup_fast code, when x86 doesn't need any of that: there's no way
19the page can be freed with irq disabled so we're guaranteed the
20atomic_inc will happen on a page with page_count > 0 (so not needing the
21speculative check).
22
23The pte check is also meaningless on x86: no need to rollback on x86 if
24the pte changed, because the pte can still change a CPU tick after the
25check succeeded and it won't be rolled back in that case. The important
26thing is we got a reference on a valid page that was mapped there a CPU
27tick ago. So not knowing the soft tlb refill code of ppc64 in great
28detail I'm not removing the "speculative" page_count increase and the
29pte checks across all the code, but unless there's a strong reason for
30it they should be later cleaned up too.
31
32If a pte can change from huge to non-huge (like it could happen with
33THP) passing a pte_t *ptep to gup_hugepte() would also require to repeat
34the is_hugepd in gup_hugepte(), but that shouldn't happen with hugetlbfs
35only so I'm not altering that.
36
37Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
38Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
39Cc: Hugh Dickins <hughd@google.com>
40Cc: Johannes Weiner <jweiner@redhat.com>
41Cc: Rik van Riel <riel@redhat.com>
42Cc: Mel Gorman <mgorman@suse.de>
43Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
44Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
45Acked-by: David Gibson <david@gibson.dropbear.id.au>
46Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
47Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
48Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
49
50---
51 arch/powerpc/mm/hugetlbpage.c | 2 +-
52 1 file changed, 1 insertion(+), 1 deletion(-)
53
54--- a/arch/powerpc/mm/hugetlbpage.c
55+++ b/arch/powerpc/mm/hugetlbpage.c
56@@ -429,7 +429,7 @@ static noinline int gup_hugepte(pte_t *p
57 if (unlikely(pte_val(pte) != pte_val(*ptep))) {
58 /* Could be optimized better */
59 while (*nr) {
60- put_page(page);
61+ put_page(head);
62 (*nr)--;
63 }
64 }