diff options
author | Andrew Morton <akpm@linux-foundation.org> | 2007-07-16 02:38:14 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-16 12:05:36 -0400 |
commit | fc9a07e7bf1a76e710f5df017abb07628db1781d (patch) | |
tree | bf2a288f97cbf9cfd82a4306a7d9c615abc7c887 /mm/truncate.c | |
parent | 45426812d6b601430d560cb6049757b5b0bc71c4 (diff) |
invalidate_mapping_pages(): add cond_resched
invalidate_mapping_pages() can sometimes take a long time (millions of pages
to free). Long enough for the softlockup detector to trigger.
We used to have a cond_resched() in there but I took it out because the
drop_caches code calls invalidate_mapping_pages() under inode_lock.
The patch adds a nasty flag and puts the cond_resched() back.
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/truncate.c')
-rw-r--r-- | mm/truncate.c | 38 |
1 files changed, 23 insertions, 15 deletions
diff --git a/mm/truncate.c b/mm/truncate.c index af3dcf0e48e6..7c994f2d6145 100644 --- a/mm/truncate.c +++ b/mm/truncate.c | |||
@@ -253,21 +253,8 @@ void truncate_inode_pages(struct address_space *mapping, loff_t lstart) | |||
253 | } | 253 | } |
254 | EXPORT_SYMBOL(truncate_inode_pages); | 254 | EXPORT_SYMBOL(truncate_inode_pages); |
255 | 255 | ||
256 | /** | 256 | unsigned long __invalidate_mapping_pages(struct address_space *mapping, |
257 | * invalidate_mapping_pages - Invalidate all the unlocked pages of one inode | 257 | pgoff_t start, pgoff_t end, bool be_atomic) |
258 | * @mapping: the address_space which holds the pages to invalidate | ||
259 | * @start: the offset 'from' which to invalidate | ||
260 | * @end: the offset 'to' which to invalidate (inclusive) | ||
261 | * | ||
262 | * This function only removes the unlocked pages, if you want to | ||
263 | * remove all the pages of one inode, you must call truncate_inode_pages. | ||
264 | * | ||
265 | * invalidate_mapping_pages() will not block on IO activity. It will not | ||
266 | * invalidate pages which are dirty, locked, under writeback or mapped into | ||
267 | * pagetables. | ||
268 | */ | ||
269 | unsigned long invalidate_mapping_pages(struct address_space *mapping, | ||
270 | pgoff_t start, pgoff_t end) | ||
271 | { | 258 | { |
272 | struct pagevec pvec; | 259 | struct pagevec pvec; |
273 | pgoff_t next = start; | 260 | pgoff_t next = start; |
@@ -308,9 +295,30 @@ unlock: | |||
308 | break; | 295 | break; |
309 | } | 296 | } |
310 | pagevec_release(&pvec); | 297 | pagevec_release(&pvec); |
298 | if (likely(!be_atomic)) | ||
299 | cond_resched(); | ||
311 | } | 300 | } |
312 | return ret; | 301 | return ret; |
313 | } | 302 | } |
303 | |||
304 | /** | ||
305 | * invalidate_mapping_pages - Invalidate all the unlocked pages of one inode | ||
306 | * @mapping: the address_space which holds the pages to invalidate | ||
307 | * @start: the offset 'from' which to invalidate | ||
308 | * @end: the offset 'to' which to invalidate (inclusive) | ||
309 | * | ||
310 | * This function only removes the unlocked pages, if you want to | ||
311 | * remove all the pages of one inode, you must call truncate_inode_pages. | ||
312 | * | ||
313 | * invalidate_mapping_pages() will not block on IO activity. It will not | ||
314 | * invalidate pages which are dirty, locked, under writeback or mapped into | ||
315 | * pagetables. | ||
316 | */ | ||
317 | unsigned long invalidate_mapping_pages(struct address_space *mapping, | ||
318 | pgoff_t start, pgoff_t end) | ||
319 | { | ||
320 | return __invalidate_mapping_pages(mapping, start, end, false); | ||
321 | } | ||
314 | EXPORT_SYMBOL(invalidate_mapping_pages); | 322 | EXPORT_SYMBOL(invalidate_mapping_pages); |
315 | 323 | ||
316 | /* | 324 | /* |