diff options
author | Andrea Arcangeli <aarcange@redhat.com> | 2011-01-13 18:47:20 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-13 20:32:48 -0500 |
commit | 22e5c47ee238abe636655c3862ed28d6eb084ad4 (patch) | |
tree | 4a4e7d330cbef6c99a8914de482eb0e8daba2485 /mm/ksm.c | |
parent | 29ad768cfc08611a4c1070d0f13f82eeea2bac7b (diff) |
thp: add compound_trans_head() helper
Cleanup some code with common compound_trans_head helper.
Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Johannes Weiner <jweiner@redhat.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Avi Kivity <avi@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/ksm.c')
-rw-r--r-- | mm/ksm.c | 15 |
1 files changed, 3 insertions, 12 deletions
@@ -415,20 +415,11 @@ out: | |||
415 | static struct page *page_trans_compound_anon(struct page *page) | 415 | static struct page *page_trans_compound_anon(struct page *page) |
416 | { | 416 | { |
417 | if (PageTransCompound(page)) { | 417 | if (PageTransCompound(page)) { |
418 | struct page *head; | 418 | struct page *head = compound_trans_head(page); |
419 | head = compound_head(page); | ||
420 | /* | 419 | /* |
421 | * head may be a dangling pointer. | 420 | * head may actually be splitted and freed from under |
422 | * __split_huge_page_refcount clears PageTail | 421 | * us but it's ok here. |
423 | * before overwriting first_page, so if | ||
424 | * PageTail is still there it means the head | ||
425 | * pointer isn't dangling. | ||
426 | */ | 422 | */ |
427 | if (head != page) { | ||
428 | smp_rmb(); | ||
429 | if (!PageTransCompound(page)) | ||
430 | return NULL; | ||
431 | } | ||
432 | if (PageAnon(head)) | 423 | if (PageAnon(head)) |
433 | return head; | 424 | return head; |
434 | } | 425 | } |