Change the page cache allocation calls to support cpuset memory spreading. See the previous patch, cpuset_mem_spread, for an explanation of cpuset memory spreading. On systems without cpusets configured in the kernel, this is no change. On systems with cpusets configured in the kernel, but the "memory_spread" cpuset option not enabled for the current tasks cpuset, this adds a call to a cpuset routine and failed bit test of the processor state flag PF_SPREAD_PAGE. On tasks in cpusets with "memory_spread" enabled, this adds a call to a cpuset routine that computes which of the tasks mems_allowed nodes should be preferred for this allocation. If memory spreading applies to a particular allocation, then any other NUMA mempolicy does not apply.
Unified · Split
| @@ -51,6 +51,10 @@ static inline void mapping_set_gfp_mask(struct address_space *m, gfp_t mask) · 50 unmodified lines | ||
| 51 | 51 | #define page_cache_release(page) put_page(page) |
| 52 | 52 | void release_pages(struct page **pages, int nr, int cold); |
| 53 | 53 | |
| 54 | +#ifdef CONFIG_NUMA | |
| 55 | +extern struct page *page_cache_alloc(struct address_space *x); | |
| 56 | +extern struct page *page_cache_alloc_cold(struct address_space *x); | |
| 57 | +#else | |
| 54 | 58 | static inline struct page *page_cache_alloc(struct address_space *x) |
| 55 | 59 | { |
| 56 | 60 | return alloc_pages(mapping_gfp_mask(x), 0); |
| @@ -60,6 +64,7 @@ static inline struct page *page_cache_alloc_cold(struct address_space *x) · 3 unmodified lines | ||
| 60 | 64 | { |
| 61 | 65 | return alloc_pages(mapping_gfp_mask(x)|__GFP_COLD, 0); |
| 62 | 66 | } |
| 67 | +#endif | |
| 63 | 68 | |
| 64 | 69 | typedef int filler_t(void *, struct page *); |
| 65 | 70 | |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | #include <linux/blkdev.h> |
| 30 | 30 | #include <linux/security.h> |
| 31 | 31 | #include <linux/syscalls.h> |
| 32 | +#include <linux/cpuset.h> | |
| 32 | 33 | #include "filemap.h" |
| 33 | 34 | #include "internal.h" |
| 34 | 35 | |
| @@ -427,6 +428,28 @@ int add_to_page_cache_lru(struct page *page, struct address_space *mapping, · 392 unmodified lines | ||
| 427 | 428 | return ret; |
| 428 | 429 | } |
| 429 | 430 | |
| 431 | +#ifdef CONFIG_NUMA | |
| 432 | +struct page *page_cache_alloc(struct address_space *x) | |
| 433 | +{ | |
| 434 | + if (cpuset_do_page_mem_spread()) { | |
| 435 | + int n = cpuset_mem_spread_node(); | |
| 436 | + return alloc_pages_node(n, mapping_gfp_mask(x), 0); | |
| 437 | + } | |
| 438 | + return alloc_pages(mapping_gfp_mask(x), 0); | |
| 439 | +} | |
| 440 | +EXPORT_SYMBOL(page_cache_alloc); | |
| 441 | + | |
| 442 | +struct page *page_cache_alloc_cold(struct address_space *x) | |
| 443 | +{ | |
| 444 | + if (cpuset_do_page_mem_spread()) { | |
| 445 | + int n = cpuset_mem_spread_node(); | |
| 446 | + return alloc_pages_node(n, mapping_gfp_mask(x)|__GFP_COLD, 0); | |
| 447 | + } | |
| 448 | + return alloc_pages(mapping_gfp_mask(x)|__GFP_COLD, 0); | |
| 449 | +} | |
| 450 | +EXPORT_SYMBOL(page_cache_alloc_cold); | |
| 451 | +#endif | |
| 452 | + | |
| 430 | 453 | /* |
| 431 | 454 | * In order to wait for pages to become available there must be |
| 432 | 455 | * waitqueues associated with pages. By using a hash table of |