diff options
author | Seth Jennings <sjenning@linux.vnet.ibm.com> | 2013-04-29 18:08:35 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-29 18:54:38 -0400 |
commit | 1eec6702a80e04416d528846a5ff2122484d95ec (patch) | |
tree | ead36835b194b3253cef6c4391489fef6a574575 /mm/page_io.c | |
parent | 2f772e6cadf8ad8fca38927b17e6be028be669f5 (diff) |
mm: allow for outstanding swap writeback accounting
To prevent flooding the swap device with writebacks, frontswap backends
need to count and limit the number of outstanding writebacks. The
incrementing of the counter can be done before the call to
__swap_writepage(). However, the caller must receive a notification
when the writeback completes in order to decrement the counter.
To achieve this functionality, this patch modifies __swap_writepage() to
take the bio completion callback function as an argument.
end_swap_bio_write(), the normal bio completion function, is also made
non-static so that code doing the accounting can call it after the
accounting is done.
There should be no behavioural change to existing code.
Signed-off-by: Seth Jennings <sjenning@linux.vnet.ibm.com>
Signed-off-by: Bob Liu <bob.liu@oracle.com>
Acked-by: Minchan Kim <minchan@kernel.org>
Reviewed-by: Dan Magenheimer <dan.magenheimer@oracle.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/page_io.c')
-rw-r--r-- | mm/page_io.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/mm/page_io.c b/mm/page_io.c index 8e6bcf176cfb..8e0e5c0e7cdb 100644 --- a/mm/page_io.c +++ b/mm/page_io.c | |||
@@ -42,7 +42,7 @@ static struct bio *get_swap_bio(gfp_t gfp_flags, | |||
42 | return bio; | 42 | return bio; |
43 | } | 43 | } |
44 | 44 | ||
45 | static void end_swap_bio_write(struct bio *bio, int err) | 45 | void end_swap_bio_write(struct bio *bio, int err) |
46 | { | 46 | { |
47 | const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); | 47 | const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); |
48 | struct page *page = bio->bi_io_vec[0].bv_page; | 48 | struct page *page = bio->bi_io_vec[0].bv_page; |
@@ -197,12 +197,13 @@ int swap_writepage(struct page *page, struct writeback_control *wbc) | |||
197 | end_page_writeback(page); | 197 | end_page_writeback(page); |
198 | goto out; | 198 | goto out; |
199 | } | 199 | } |
200 | ret = __swap_writepage(page, wbc); | 200 | ret = __swap_writepage(page, wbc, end_swap_bio_write); |
201 | out: | 201 | out: |
202 | return ret; | 202 | return ret; |
203 | } | 203 | } |
204 | 204 | ||
205 | int __swap_writepage(struct page *page, struct writeback_control *wbc) | 205 | int __swap_writepage(struct page *page, struct writeback_control *wbc, |
206 | void (*end_write_func)(struct bio *, int)) | ||
206 | { | 207 | { |
207 | struct bio *bio; | 208 | struct bio *bio; |
208 | int ret = 0, rw = WRITE; | 209 | int ret = 0, rw = WRITE; |
@@ -234,7 +235,7 @@ int __swap_writepage(struct page *page, struct writeback_control *wbc) | |||
234 | return ret; | 235 | return ret; |
235 | } | 236 | } |
236 | 237 | ||
237 | bio = get_swap_bio(GFP_NOIO, page, end_swap_bio_write); | 238 | bio = get_swap_bio(GFP_NOIO, page, end_write_func); |
238 | if (bio == NULL) { | 239 | if (bio == NULL) { |
239 | set_page_dirty(page); | 240 | set_page_dirty(page); |
240 | unlock_page(page); | 241 | unlock_page(page); |