Commit ac3b0460 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] Add some low-latency scheduling points

This is the first in a little batch of patches which address long-held
locks in the VFS/MM layer which are affecting our worst-case scheduling
latency, and are making CONFIG_PREEMPT not very useful.

We end up with a worst-case of 500 microseconds at 500MHz, which is
very good.  Unless you do an exit with lots of mmapped memory.
unmap_page_range() needs work.

Some of these patches also add rescheduling points for non-preemptible
kernels - where I felt that the code path could be long enough to be
perceptible.



Three places in the generic pagecache functions need manual
rescheduling points even for non-preemptible kernels:

- generic_file_read()  (Can hold the CPU for seconds)

- generic_file_write() (ditto)

- filemap_fdatawait().  This won't hold the CPU for so long, but it
  can walk many thousands of pages under the lock.  It needs a lock
  drop and scheduling point for both preemptible and non-preemptible
  kernels.  (This one's a bit ugly...)
parent 25d19d4c
...@@ -174,9 +174,11 @@ int filemap_fdatawrite(struct address_space *mapping) ...@@ -174,9 +174,11 @@ int filemap_fdatawrite(struct address_space *mapping)
int filemap_fdatawait(struct address_space * mapping) int filemap_fdatawait(struct address_space * mapping)
{ {
int ret = 0; int ret = 0;
int progress;
restart:
progress = 0;
write_lock(&mapping->page_lock); write_lock(&mapping->page_lock);
while (!list_empty(&mapping->locked_pages)) { while (!list_empty(&mapping->locked_pages)) {
struct page *page; struct page *page;
...@@ -187,9 +189,18 @@ int filemap_fdatawait(struct address_space * mapping) ...@@ -187,9 +189,18 @@ int filemap_fdatawait(struct address_space * mapping)
else else
list_add(&page->list, &mapping->clean_pages); list_add(&page->list, &mapping->clean_pages);
if (!PageWriteback(page)) if (!PageWriteback(page)) {
if (++progress > 32) {
if (need_resched()) {
write_unlock(&mapping->page_lock);
__cond_resched();
goto restart;
}
}
continue; continue;
}
progress = 0;
page_cache_get(page); page_cache_get(page);
write_unlock(&mapping->page_lock); write_unlock(&mapping->page_lock);
...@@ -559,6 +570,7 @@ void do_generic_mapping_read(struct address_space *mapping, ...@@ -559,6 +570,7 @@ void do_generic_mapping_read(struct address_space *mapping,
break; break;
} }
cond_resched();
page_cache_readahead(mapping, ra, filp, index); page_cache_readahead(mapping, ra, filp, index);
nr = nr - offset; nr = nr - offset;
...@@ -1770,6 +1782,7 @@ generic_file_write_nolock(struct file *file, const struct iovec *iov, ...@@ -1770,6 +1782,7 @@ generic_file_write_nolock(struct file *file, const struct iovec *iov,
if (status < 0) if (status < 0)
break; break;
balance_dirty_pages_ratelimited(mapping); balance_dirty_pages_ratelimited(mapping);
cond_resched();
} while (count); } while (count);
*ppos = pos; *ppos = pos;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment