diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/rmap.c | 17 |
1 files changed, 13 insertions, 4 deletions
@@ -183,7 +183,7 @@ void __init anon_vma_init(void) | |||
183 | */ | 183 | */ |
184 | static struct anon_vma *page_lock_anon_vma(struct page *page) | 184 | static struct anon_vma *page_lock_anon_vma(struct page *page) |
185 | { | 185 | { |
186 | struct anon_vma *anon_vma = NULL; | 186 | struct anon_vma *anon_vma; |
187 | unsigned long anon_mapping; | 187 | unsigned long anon_mapping; |
188 | 188 | ||
189 | rcu_read_lock(); | 189 | rcu_read_lock(); |
@@ -195,9 +195,16 @@ static struct anon_vma *page_lock_anon_vma(struct page *page) | |||
195 | 195 | ||
196 | anon_vma = (struct anon_vma *) (anon_mapping - PAGE_MAPPING_ANON); | 196 | anon_vma = (struct anon_vma *) (anon_mapping - PAGE_MAPPING_ANON); |
197 | spin_lock(&anon_vma->lock); | 197 | spin_lock(&anon_vma->lock); |
198 | return anon_vma; | ||
198 | out: | 199 | out: |
199 | rcu_read_unlock(); | 200 | rcu_read_unlock(); |
200 | return anon_vma; | 201 | return NULL; |
202 | } | ||
203 | |||
204 | static void page_unlock_anon_vma(struct anon_vma *anon_vma) | ||
205 | { | ||
206 | spin_unlock(&anon_vma->lock); | ||
207 | rcu_read_unlock(); | ||
201 | } | 208 | } |
202 | 209 | ||
203 | /* | 210 | /* |
@@ -333,7 +340,8 @@ static int page_referenced_anon(struct page *page) | |||
333 | if (!mapcount) | 340 | if (!mapcount) |
334 | break; | 341 | break; |
335 | } | 342 | } |
336 | spin_unlock(&anon_vma->lock); | 343 | |
344 | page_unlock_anon_vma(anon_vma); | ||
337 | return referenced; | 345 | return referenced; |
338 | } | 346 | } |
339 | 347 | ||
@@ -802,7 +810,8 @@ static int try_to_unmap_anon(struct page *page, int migration) | |||
802 | if (ret == SWAP_FAIL || !page_mapped(page)) | 810 | if (ret == SWAP_FAIL || !page_mapped(page)) |
803 | break; | 811 | break; |
804 | } | 812 | } |
805 | spin_unlock(&anon_vma->lock); | 813 | |
814 | page_unlock_anon_vma(anon_vma); | ||
806 | return ret; | 815 | return ret; |
807 | } | 816 | } |
808 | 817 | ||