diff options
author | Hugh Dickins <hugh@veritas.com> | 2005-10-29 21:16:31 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-10-30 00:40:41 -0400 |
commit | c0718806cf955d5eb51ea77bffb5b21d9bba4972 (patch) | |
tree | bd29659bbff68604127439ec8144230a40772621 /mm/filemap_xip.c | |
parent | 67b02f119df50ffad5a4e9e53ea4c896535862cd (diff) |
[PATCH] mm: rmap with inner ptlock
rmap's page_check_address descend without page_table_lock. First just
pte_offset_map in case there's no pte present worth locking for, then take
page_table_lock for the full check, and pass ptl back to caller in the same
style as pte_offset_map_lock. __xip_unmap, page_referenced_one and
try_to_unmap_one use pte_unmap_unlock. try_to_unmap_cluster also.
page_check_address reformatted to avoid progressive indentation. No use is
made of its one error code, return NULL when it fails.
Signed-off-by: Hugh Dickins <hugh@veritas.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'mm/filemap_xip.c')
-rw-r--r-- | mm/filemap_xip.c | 12 |
1 files changed, 4 insertions, 8 deletions
diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c index 4e74ad60339a..9cf687e4a29a 100644 --- a/mm/filemap_xip.c +++ b/mm/filemap_xip.c | |||
@@ -174,6 +174,7 @@ __xip_unmap (struct address_space * mapping, | |||
174 | unsigned long address; | 174 | unsigned long address; |
175 | pte_t *pte; | 175 | pte_t *pte; |
176 | pte_t pteval; | 176 | pte_t pteval; |
177 | spinlock_t *ptl; | ||
177 | struct page *page; | 178 | struct page *page; |
178 | 179 | ||
179 | spin_lock(&mapping->i_mmap_lock); | 180 | spin_lock(&mapping->i_mmap_lock); |
@@ -183,20 +184,15 @@ __xip_unmap (struct address_space * mapping, | |||
183 | ((pgoff - vma->vm_pgoff) << PAGE_SHIFT); | 184 | ((pgoff - vma->vm_pgoff) << PAGE_SHIFT); |
184 | BUG_ON(address < vma->vm_start || address >= vma->vm_end); | 185 | BUG_ON(address < vma->vm_start || address >= vma->vm_end); |
185 | page = ZERO_PAGE(address); | 186 | page = ZERO_PAGE(address); |
186 | /* | 187 | pte = page_check_address(page, mm, address, &ptl); |
187 | * We need the page_table_lock to protect us from page faults, | 188 | if (pte) { |
188 | * munmap, fork, etc... | ||
189 | */ | ||
190 | pte = page_check_address(page, mm, address); | ||
191 | if (!IS_ERR(pte)) { | ||
192 | /* Nuke the page table entry. */ | 189 | /* Nuke the page table entry. */ |
193 | flush_cache_page(vma, address, pte_pfn(*pte)); | 190 | flush_cache_page(vma, address, pte_pfn(*pte)); |
194 | pteval = ptep_clear_flush(vma, address, pte); | 191 | pteval = ptep_clear_flush(vma, address, pte); |
195 | page_remove_rmap(page); | 192 | page_remove_rmap(page); |
196 | dec_mm_counter(mm, file_rss); | 193 | dec_mm_counter(mm, file_rss); |
197 | BUG_ON(pte_dirty(pteval)); | 194 | BUG_ON(pte_dirty(pteval)); |
198 | pte_unmap(pte); | 195 | pte_unmap_unlock(pte, ptl); |
199 | spin_unlock(&mm->page_table_lock); | ||
200 | page_cache_release(page); | 196 | page_cache_release(page); |
201 | } | 197 | } |
202 | } | 198 | } |