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