diff options
author | Nick Piggin <npiggin@suse.de> | 2007-10-16 04:24:40 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-16 12:42:53 -0400 |
commit | 001281881067a5998384c6669bc8dbbbab8456c4 (patch) | |
tree | 6229d16c737782a36795354b218c74d4d2749752 | |
parent | 557ed1fa2620dc119adb86b34c614e152a629a80 (diff) |
mm: use lockless radix-tree probe
Probing pages and radix_tree_tagged are lockless operations with the lockless
radix-tree. Convert these users to RCU locking rather than using tree_lock.
Signed-off-by: Nick Piggin <npiggin@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | mm/page-writeback.c | 8 | ||||
-rw-r--r-- | mm/readahead.c | 6 |
2 files changed, 5 insertions, 9 deletions
diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 44720363374c..2adb89959885 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c | |||
@@ -1022,17 +1022,15 @@ int test_set_page_writeback(struct page *page) | |||
1022 | EXPORT_SYMBOL(test_set_page_writeback); | 1022 | EXPORT_SYMBOL(test_set_page_writeback); |
1023 | 1023 | ||
1024 | /* | 1024 | /* |
1025 | * Return true if any of the pages in the mapping are marged with the | 1025 | * Return true if any of the pages in the mapping are marked with the |
1026 | * passed tag. | 1026 | * passed tag. |
1027 | */ | 1027 | */ |
1028 | int mapping_tagged(struct address_space *mapping, int tag) | 1028 | int mapping_tagged(struct address_space *mapping, int tag) |
1029 | { | 1029 | { |
1030 | unsigned long flags; | ||
1031 | int ret; | 1030 | int ret; |
1032 | 1031 | rcu_read_lock(); | |
1033 | read_lock_irqsave(&mapping->tree_lock, flags); | ||
1034 | ret = radix_tree_tagged(&mapping->page_tree, tag); | 1032 | ret = radix_tree_tagged(&mapping->page_tree, tag); |
1035 | read_unlock_irqrestore(&mapping->tree_lock, flags); | 1033 | rcu_read_unlock(); |
1036 | return ret; | 1034 | return ret; |
1037 | } | 1035 | } |
1038 | EXPORT_SYMBOL(mapping_tagged); | 1036 | EXPORT_SYMBOL(mapping_tagged); |
diff --git a/mm/readahead.c b/mm/readahead.c index fc52f9f1b80c..c5c8981469e7 100644 --- a/mm/readahead.c +++ b/mm/readahead.c | |||
@@ -149,20 +149,19 @@ __do_page_cache_readahead(struct address_space *mapping, struct file *filp, | |||
149 | /* | 149 | /* |
150 | * Preallocate as many pages as we will need. | 150 | * Preallocate as many pages as we will need. |
151 | */ | 151 | */ |
152 | read_lock_irq(&mapping->tree_lock); | ||
153 | for (page_idx = 0; page_idx < nr_to_read; page_idx++) { | 152 | for (page_idx = 0; page_idx < nr_to_read; page_idx++) { |
154 | pgoff_t page_offset = offset + page_idx; | 153 | pgoff_t page_offset = offset + page_idx; |
155 | 154 | ||
156 | if (page_offset > end_index) | 155 | if (page_offset > end_index) |
157 | break; | 156 | break; |
158 | 157 | ||
158 | rcu_read_lock(); | ||
159 | page = radix_tree_lookup(&mapping->page_tree, page_offset); | 159 | page = radix_tree_lookup(&mapping->page_tree, page_offset); |
160 | rcu_read_unlock(); | ||
160 | if (page) | 161 | if (page) |
161 | continue; | 162 | continue; |
162 | 163 | ||
163 | read_unlock_irq(&mapping->tree_lock); | ||
164 | page = page_cache_alloc_cold(mapping); | 164 | page = page_cache_alloc_cold(mapping); |
165 | read_lock_irq(&mapping->tree_lock); | ||
166 | if (!page) | 165 | if (!page) |
167 | break; | 166 | break; |
168 | page->index = page_offset; | 167 | page->index = page_offset; |
@@ -171,7 +170,6 @@ __do_page_cache_readahead(struct address_space *mapping, struct file *filp, | |||
171 | SetPageReadahead(page); | 170 | SetPageReadahead(page); |
172 | ret++; | 171 | ret++; |
173 | } | 172 | } |
174 | read_unlock_irq(&mapping->tree_lock); | ||
175 | 173 | ||
176 | /* | 174 | /* |
177 | * Now start the IO. We ignore I/O errors - if the page is not | 175 | * Now start the IO. We ignore I/O errors - if the page is not |