aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSeth Jennings <sjenning@linux.vnet.ibm.com>2013-04-29 18:08:35 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-04-29 18:54:38 -0400
commit1eec6702a80e04416d528846a5ff2122484d95ec (patch)
treeead36835b194b3253cef6c4391489fef6a574575
parent2f772e6cadf8ad8fca38927b17e6be028be669f5 (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>
-rw-r--r--include/linux/swap.h4
-rw-r--r--mm/page_io.c9
2 files changed, 8 insertions, 5 deletions
diff --git a/include/linux/swap.h b/include/linux/swap.h
index 76f6c3b31235..b5b12c71a2af 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -330,7 +330,9 @@ static inline void mem_cgroup_uncharge_swap(swp_entry_t ent)
330/* linux/mm/page_io.c */ 330/* linux/mm/page_io.c */
331extern int swap_readpage(struct page *); 331extern int swap_readpage(struct page *);
332extern int swap_writepage(struct page *page, struct writeback_control *wbc); 332extern int swap_writepage(struct page *page, struct writeback_control *wbc);
333extern int __swap_writepage(struct page *page, struct writeback_control *wbc); 333extern void end_swap_bio_write(struct bio *bio, int err);
334extern int __swap_writepage(struct page *page, struct writeback_control *wbc,
335 void (*end_write_func)(struct bio *, int));
334extern int swap_set_page_dirty(struct page *page); 336extern int swap_set_page_dirty(struct page *page);
335extern void end_swap_bio_read(struct bio *bio, int err); 337extern void end_swap_bio_read(struct bio *bio, int err);
336 338
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
45static void end_swap_bio_write(struct bio *bio, int err) 45void 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);
201out: 201out:
202 return ret; 202 return ret;
203} 203}
204 204
205int __swap_writepage(struct page *page, struct writeback_control *wbc) 205int __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);