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 /virt | |
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 'virt')
-rw-r--r-- | virt/kvm/kvm_main.c | 38 |
1 files changed, 14 insertions, 24 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 4286d4766510..f29abeb6a912 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -104,34 +104,24 @@ static pfn_t fault_pfn; | |||
104 | inline int kvm_is_mmio_pfn(pfn_t pfn) | 104 | inline int kvm_is_mmio_pfn(pfn_t pfn) |
105 | { | 105 | { |
106 | if (pfn_valid(pfn)) { | 106 | if (pfn_valid(pfn)) { |
107 | struct page *head; | 107 | int reserved; |
108 | struct page *tail = pfn_to_page(pfn); | 108 | struct page *tail = pfn_to_page(pfn); |
109 | head = compound_head(tail); | 109 | struct page *head = compound_trans_head(tail); |
110 | reserved = PageReserved(head); | ||
110 | if (head != tail) { | 111 | if (head != tail) { |
111 | smp_rmb(); | ||
112 | /* | 112 | /* |
113 | * head may be a dangling pointer. | 113 | * "head" is not a dangling pointer |
114 | * __split_huge_page_refcount clears PageTail | 114 | * (compound_trans_head takes care of that) |
115 | * before overwriting first_page, so if | 115 | * but the hugepage may have been splitted |
116 | * PageTail is still there it means the head | 116 | * from under us (and we may not hold a |
117 | * pointer isn't dangling. | 117 | * reference count on the head page so it can |
118 | * be reused before we run PageReferenced), so | ||
119 | * we've to check PageTail before returning | ||
120 | * what we just read. | ||
118 | */ | 121 | */ |
119 | if (PageTail(tail)) { | 122 | smp_rmb(); |
120 | /* | 123 | if (PageTail(tail)) |
121 | * the "head" is not a dangling | 124 | return reserved; |
122 | * pointer but the hugepage may have | ||
123 | * been splitted from under us (and we | ||
124 | * may not hold a reference count on | ||
125 | * the head page so it can be reused | ||
126 | * before we run PageReferenced), so | ||
127 | * we've to recheck PageTail before | ||
128 | * returning what we just read. | ||
129 | */ | ||
130 | int reserved = PageReserved(head); | ||
131 | smp_rmb(); | ||
132 | if (PageTail(tail)) | ||
133 | return reserved; | ||
134 | } | ||
135 | } | 125 | } |
136 | return PageReserved(tail); | 126 | return PageReserved(tail); |
137 | } | 127 | } |