diff options
author | Nick Piggin <npiggin@suse.de> | 2006-10-28 13:38:23 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-28 14:30:50 -0400 |
commit | 2ae88149a27cadf2840e0ab8155bef13be285c03 (patch) | |
tree | e6873cc050973db6f2b01568a5e1faa6c981d139 | |
parent | 858cbcdd4f7a235f609249b9ca681b7ec5d786a3 (diff) |
[PATCH] mm: clean up pagecache allocation
- Consolidate page_cache_alloc
- Fix splice: only the pagecache pages and filesystem data need to use
mapping_gfp_mask.
- Fix grab_cache_page_nowait: same as splice, also honour NUMA placement.
Signed-off-by: Nick Piggin <npiggin@suse.de>
Cc: Jens Axboe <jens.axboe@oracle.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | fs/splice.c | 9 | ||||
-rw-r--r-- | include/linux/pagemap.h | 14 | ||||
-rw-r--r-- | mm/filemap.c | 24 |
3 files changed, 19 insertions, 28 deletions
diff --git a/fs/splice.c b/fs/splice.c index 49fb9f129938..8d705954d294 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -74,7 +74,7 @@ static int page_cache_pipe_buf_steal(struct pipe_inode_info *pipe, | |||
74 | wait_on_page_writeback(page); | 74 | wait_on_page_writeback(page); |
75 | 75 | ||
76 | if (PagePrivate(page)) | 76 | if (PagePrivate(page)) |
77 | try_to_release_page(page, mapping_gfp_mask(mapping)); | 77 | try_to_release_page(page, GFP_KERNEL); |
78 | 78 | ||
79 | /* | 79 | /* |
80 | * If we succeeded in removing the mapping, set LRU flag | 80 | * If we succeeded in removing the mapping, set LRU flag |
@@ -333,7 +333,7 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, | |||
333 | break; | 333 | break; |
334 | 334 | ||
335 | error = add_to_page_cache_lru(page, mapping, index, | 335 | error = add_to_page_cache_lru(page, mapping, index, |
336 | mapping_gfp_mask(mapping)); | 336 | GFP_KERNEL); |
337 | if (unlikely(error)) { | 337 | if (unlikely(error)) { |
338 | page_cache_release(page); | 338 | page_cache_release(page); |
339 | if (error == -EEXIST) | 339 | if (error == -EEXIST) |
@@ -557,7 +557,6 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf, | |||
557 | { | 557 | { |
558 | struct file *file = sd->file; | 558 | struct file *file = sd->file; |
559 | struct address_space *mapping = file->f_mapping; | 559 | struct address_space *mapping = file->f_mapping; |
560 | gfp_t gfp_mask = mapping_gfp_mask(mapping); | ||
561 | unsigned int offset, this_len; | 560 | unsigned int offset, this_len; |
562 | struct page *page; | 561 | struct page *page; |
563 | pgoff_t index; | 562 | pgoff_t index; |
@@ -591,7 +590,7 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf, | |||
591 | goto find_page; | 590 | goto find_page; |
592 | 591 | ||
593 | page = buf->page; | 592 | page = buf->page; |
594 | if (add_to_page_cache(page, mapping, index, gfp_mask)) { | 593 | if (add_to_page_cache(page, mapping, index, GFP_KERNEL)) { |
595 | unlock_page(page); | 594 | unlock_page(page); |
596 | goto find_page; | 595 | goto find_page; |
597 | } | 596 | } |
@@ -613,7 +612,7 @@ find_page: | |||
613 | * This will also lock the page | 612 | * This will also lock the page |
614 | */ | 613 | */ |
615 | ret = add_to_page_cache_lru(page, mapping, index, | 614 | ret = add_to_page_cache_lru(page, mapping, index, |
616 | gfp_mask); | 615 | GFP_KERNEL); |
617 | if (unlikely(ret)) | 616 | if (unlikely(ret)) |
618 | goto out; | 617 | goto out; |
619 | } | 618 | } |
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 64f950925151..c3e255bf8594 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h | |||
@@ -52,19 +52,23 @@ static inline void mapping_set_gfp_mask(struct address_space *m, gfp_t mask) | |||
52 | void release_pages(struct page **pages, int nr, int cold); | 52 | void release_pages(struct page **pages, int nr, int cold); |
53 | 53 | ||
54 | #ifdef CONFIG_NUMA | 54 | #ifdef CONFIG_NUMA |
55 | extern struct page *page_cache_alloc(struct address_space *x); | 55 | extern struct page *__page_cache_alloc(gfp_t gfp); |
56 | extern struct page *page_cache_alloc_cold(struct address_space *x); | ||
57 | #else | 56 | #else |
57 | static inline struct page *__page_cache_alloc(gfp_t gfp) | ||
58 | { | ||
59 | return alloc_pages(gfp, 0); | ||
60 | } | ||
61 | #endif | ||
62 | |||
58 | static inline struct page *page_cache_alloc(struct address_space *x) | 63 | static inline struct page *page_cache_alloc(struct address_space *x) |
59 | { | 64 | { |
60 | return alloc_pages(mapping_gfp_mask(x), 0); | 65 | return __page_cache_alloc(mapping_gfp_mask(x)); |
61 | } | 66 | } |
62 | 67 | ||
63 | static inline struct page *page_cache_alloc_cold(struct address_space *x) | 68 | static inline struct page *page_cache_alloc_cold(struct address_space *x) |
64 | { | 69 | { |
65 | return alloc_pages(mapping_gfp_mask(x)|__GFP_COLD, 0); | 70 | return __page_cache_alloc(mapping_gfp_mask(x)|__GFP_COLD); |
66 | } | 71 | } |
67 | #endif | ||
68 | 72 | ||
69 | typedef int filler_t(void *, struct page *); | 73 | typedef int filler_t(void *, struct page *); |
70 | 74 | ||
diff --git a/mm/filemap.c b/mm/filemap.c index cb26e33fd0ff..7b84dc814347 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -467,25 +467,15 @@ int add_to_page_cache_lru(struct page *page, struct address_space *mapping, | |||
467 | } | 467 | } |
468 | 468 | ||
469 | #ifdef CONFIG_NUMA | 469 | #ifdef CONFIG_NUMA |
470 | struct page *page_cache_alloc(struct address_space *x) | 470 | struct page *__page_cache_alloc(gfp_t gfp) |
471 | { | 471 | { |
472 | if (cpuset_do_page_mem_spread()) { | 472 | if (cpuset_do_page_mem_spread()) { |
473 | int n = cpuset_mem_spread_node(); | 473 | int n = cpuset_mem_spread_node(); |
474 | return alloc_pages_node(n, mapping_gfp_mask(x), 0); | 474 | return alloc_pages_node(n, gfp, 0); |
475 | } | 475 | } |
476 | return alloc_pages(mapping_gfp_mask(x), 0); | 476 | return alloc_pages(gfp, 0); |
477 | } | 477 | } |
478 | EXPORT_SYMBOL(page_cache_alloc); | 478 | EXPORT_SYMBOL(__page_cache_alloc); |
479 | |||
480 | struct page *page_cache_alloc_cold(struct address_space *x) | ||
481 | { | ||
482 | if (cpuset_do_page_mem_spread()) { | ||
483 | int n = cpuset_mem_spread_node(); | ||
484 | return alloc_pages_node(n, mapping_gfp_mask(x)|__GFP_COLD, 0); | ||
485 | } | ||
486 | return alloc_pages(mapping_gfp_mask(x)|__GFP_COLD, 0); | ||
487 | } | ||
488 | EXPORT_SYMBOL(page_cache_alloc_cold); | ||
489 | #endif | 479 | #endif |
490 | 480 | ||
491 | static int __sleep_on_page_lock(void *word) | 481 | static int __sleep_on_page_lock(void *word) |
@@ -826,7 +816,6 @@ struct page * | |||
826 | grab_cache_page_nowait(struct address_space *mapping, unsigned long index) | 816 | grab_cache_page_nowait(struct address_space *mapping, unsigned long index) |
827 | { | 817 | { |
828 | struct page *page = find_get_page(mapping, index); | 818 | struct page *page = find_get_page(mapping, index); |
829 | gfp_t gfp_mask; | ||
830 | 819 | ||
831 | if (page) { | 820 | if (page) { |
832 | if (!TestSetPageLocked(page)) | 821 | if (!TestSetPageLocked(page)) |
@@ -834,9 +823,8 @@ grab_cache_page_nowait(struct address_space *mapping, unsigned long index) | |||
834 | page_cache_release(page); | 823 | page_cache_release(page); |
835 | return NULL; | 824 | return NULL; |
836 | } | 825 | } |
837 | gfp_mask = mapping_gfp_mask(mapping) & ~__GFP_FS; | 826 | page = __page_cache_alloc(mapping_gfp_mask(mapping) & ~__GFP_FS); |
838 | page = alloc_pages(gfp_mask, 0); | 827 | if (page && add_to_page_cache_lru(page, mapping, index, GFP_KERNEL)) { |
839 | if (page && add_to_page_cache_lru(page, mapping, index, gfp_mask)) { | ||
840 | page_cache_release(page); | 828 | page_cache_release(page); |
841 | page = NULL; | 829 | page = NULL; |
842 | } | 830 | } |