diff options
| author | Jeff Garzik <jgarzik@pobox.com> | 2005-09-08 05:43:49 -0400 |
|---|---|---|
| committer | Jeff Garzik <jgarzik@pobox.com> | 2005-09-08 05:43:49 -0400 |
| commit | 1d6ae775d7a948c9575658eb41184fd2e506c0df (patch) | |
| tree | 8128a28e89d82f13bb8e3a2160382240c66e2816 /mm/page_alloc.c | |
| parent | 739cdbf1d8f0739b80035b80d69d871e33749b86 (diff) | |
| parent | caf39e87cc1182f7dae84eefc43ca14d54c78ef9 (diff) | |
Merge /spare/repo/linux-2.6/
Diffstat (limited to 'mm/page_alloc.c')
| -rw-r--r-- | mm/page_alloc.c | 57 |
1 files changed, 38 insertions, 19 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 8d088371196a..3974fd81d27c 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
| @@ -42,13 +42,13 @@ | |||
| 42 | * MCD - HACK: Find somewhere to initialize this EARLY, or make this | 42 | * MCD - HACK: Find somewhere to initialize this EARLY, or make this |
| 43 | * initializer cleaner | 43 | * initializer cleaner |
| 44 | */ | 44 | */ |
| 45 | nodemask_t node_online_map = { { [0] = 1UL } }; | 45 | nodemask_t node_online_map __read_mostly = { { [0] = 1UL } }; |
| 46 | EXPORT_SYMBOL(node_online_map); | 46 | EXPORT_SYMBOL(node_online_map); |
| 47 | nodemask_t node_possible_map = NODE_MASK_ALL; | 47 | nodemask_t node_possible_map __read_mostly = NODE_MASK_ALL; |
| 48 | EXPORT_SYMBOL(node_possible_map); | 48 | EXPORT_SYMBOL(node_possible_map); |
| 49 | struct pglist_data *pgdat_list; | 49 | struct pglist_data *pgdat_list __read_mostly; |
| 50 | unsigned long totalram_pages; | 50 | unsigned long totalram_pages __read_mostly; |
| 51 | unsigned long totalhigh_pages; | 51 | unsigned long totalhigh_pages __read_mostly; |
| 52 | long nr_swap_pages; | 52 | long nr_swap_pages; |
| 53 | 53 | ||
| 54 | /* | 54 | /* |
| @@ -68,7 +68,7 @@ EXPORT_SYMBOL(nr_swap_pages); | |||
| 68 | * Used by page_zone() to look up the address of the struct zone whose | 68 | * Used by page_zone() to look up the address of the struct zone whose |
| 69 | * id is encoded in the upper bits of page->flags | 69 | * id is encoded in the upper bits of page->flags |
| 70 | */ | 70 | */ |
| 71 | struct zone *zone_table[1 << ZONETABLE_SHIFT]; | 71 | struct zone *zone_table[1 << ZONETABLE_SHIFT] __read_mostly; |
| 72 | EXPORT_SYMBOL(zone_table); | 72 | EXPORT_SYMBOL(zone_table); |
| 73 | 73 | ||
| 74 | static char *zone_names[MAX_NR_ZONES] = { "DMA", "Normal", "HighMem" }; | 74 | static char *zone_names[MAX_NR_ZONES] = { "DMA", "Normal", "HighMem" }; |
| @@ -329,7 +329,7 @@ static inline void free_pages_check(const char *function, struct page *page) | |||
| 329 | 1 << PG_writeback ))) | 329 | 1 << PG_writeback ))) |
| 330 | bad_page(function, page); | 330 | bad_page(function, page); |
| 331 | if (PageDirty(page)) | 331 | if (PageDirty(page)) |
| 332 | ClearPageDirty(page); | 332 | __ClearPageDirty(page); |
| 333 | } | 333 | } |
| 334 | 334 | ||
| 335 | /* | 335 | /* |
| @@ -806,11 +806,14 @@ __alloc_pages(unsigned int __nocast gfp_mask, unsigned int order, | |||
| 806 | classzone_idx = zone_idx(zones[0]); | 806 | classzone_idx = zone_idx(zones[0]); |
| 807 | 807 | ||
| 808 | restart: | 808 | restart: |
| 809 | /* Go through the zonelist once, looking for a zone with enough free */ | 809 | /* |
| 810 | * Go through the zonelist once, looking for a zone with enough free. | ||
| 811 | * See also cpuset_zone_allowed() comment in kernel/cpuset.c. | ||
| 812 | */ | ||
| 810 | for (i = 0; (z = zones[i]) != NULL; i++) { | 813 | for (i = 0; (z = zones[i]) != NULL; i++) { |
| 811 | int do_reclaim = should_reclaim_zone(z, gfp_mask); | 814 | int do_reclaim = should_reclaim_zone(z, gfp_mask); |
| 812 | 815 | ||
| 813 | if (!cpuset_zone_allowed(z)) | 816 | if (!cpuset_zone_allowed(z, __GFP_HARDWALL)) |
| 814 | continue; | 817 | continue; |
| 815 | 818 | ||
| 816 | /* | 819 | /* |
| @@ -845,6 +848,7 @@ zone_reclaim_retry: | |||
| 845 | * | 848 | * |
| 846 | * This is the last chance, in general, before the goto nopage. | 849 | * This is the last chance, in general, before the goto nopage. |
| 847 | * Ignore cpuset if GFP_ATOMIC (!wait) rather than fail alloc. | 850 | * Ignore cpuset if GFP_ATOMIC (!wait) rather than fail alloc. |
| 851 | * See also cpuset_zone_allowed() comment in kernel/cpuset.c. | ||
| 848 | */ | 852 | */ |
| 849 | for (i = 0; (z = zones[i]) != NULL; i++) { | 853 | for (i = 0; (z = zones[i]) != NULL; i++) { |
| 850 | if (!zone_watermark_ok(z, order, z->pages_min, | 854 | if (!zone_watermark_ok(z, order, z->pages_min, |
| @@ -852,7 +856,7 @@ zone_reclaim_retry: | |||
| 852 | gfp_mask & __GFP_HIGH)) | 856 | gfp_mask & __GFP_HIGH)) |
| 853 | continue; | 857 | continue; |
| 854 | 858 | ||
| 855 | if (wait && !cpuset_zone_allowed(z)) | 859 | if (wait && !cpuset_zone_allowed(z, gfp_mask)) |
| 856 | continue; | 860 | continue; |
| 857 | 861 | ||
| 858 | page = buffered_rmqueue(z, order, gfp_mask); | 862 | page = buffered_rmqueue(z, order, gfp_mask); |
| @@ -867,7 +871,7 @@ zone_reclaim_retry: | |||
| 867 | if (!(gfp_mask & __GFP_NOMEMALLOC)) { | 871 | if (!(gfp_mask & __GFP_NOMEMALLOC)) { |
| 868 | /* go through the zonelist yet again, ignoring mins */ | 872 | /* go through the zonelist yet again, ignoring mins */ |
| 869 | for (i = 0; (z = zones[i]) != NULL; i++) { | 873 | for (i = 0; (z = zones[i]) != NULL; i++) { |
| 870 | if (!cpuset_zone_allowed(z)) | 874 | if (!cpuset_zone_allowed(z, gfp_mask)) |
| 871 | continue; | 875 | continue; |
| 872 | page = buffered_rmqueue(z, order, gfp_mask); | 876 | page = buffered_rmqueue(z, order, gfp_mask); |
| 873 | if (page) | 877 | if (page) |
| @@ -903,7 +907,7 @@ rebalance: | |||
| 903 | gfp_mask & __GFP_HIGH)) | 907 | gfp_mask & __GFP_HIGH)) |
| 904 | continue; | 908 | continue; |
| 905 | 909 | ||
| 906 | if (!cpuset_zone_allowed(z)) | 910 | if (!cpuset_zone_allowed(z, gfp_mask)) |
| 907 | continue; | 911 | continue; |
| 908 | 912 | ||
| 909 | page = buffered_rmqueue(z, order, gfp_mask); | 913 | page = buffered_rmqueue(z, order, gfp_mask); |
| @@ -922,7 +926,7 @@ rebalance: | |||
| 922 | classzone_idx, 0, 0)) | 926 | classzone_idx, 0, 0)) |
| 923 | continue; | 927 | continue; |
| 924 | 928 | ||
| 925 | if (!cpuset_zone_allowed(z)) | 929 | if (!cpuset_zone_allowed(z, __GFP_HARDWALL)) |
| 926 | continue; | 930 | continue; |
| 927 | 931 | ||
| 928 | page = buffered_rmqueue(z, order, gfp_mask); | 932 | page = buffered_rmqueue(z, order, gfp_mask); |
| @@ -1130,19 +1134,20 @@ EXPORT_SYMBOL(nr_pagecache); | |||
| 1130 | DEFINE_PER_CPU(long, nr_pagecache_local) = 0; | 1134 | DEFINE_PER_CPU(long, nr_pagecache_local) = 0; |
| 1131 | #endif | 1135 | #endif |
| 1132 | 1136 | ||
| 1133 | void __get_page_state(struct page_state *ret, int nr) | 1137 | void __get_page_state(struct page_state *ret, int nr, cpumask_t *cpumask) |
| 1134 | { | 1138 | { |
| 1135 | int cpu = 0; | 1139 | int cpu = 0; |
| 1136 | 1140 | ||
| 1137 | memset(ret, 0, sizeof(*ret)); | 1141 | memset(ret, 0, sizeof(*ret)); |
| 1142 | cpus_and(*cpumask, *cpumask, cpu_online_map); | ||
| 1138 | 1143 | ||
| 1139 | cpu = first_cpu(cpu_online_map); | 1144 | cpu = first_cpu(*cpumask); |
| 1140 | while (cpu < NR_CPUS) { | 1145 | while (cpu < NR_CPUS) { |
| 1141 | unsigned long *in, *out, off; | 1146 | unsigned long *in, *out, off; |
| 1142 | 1147 | ||
| 1143 | in = (unsigned long *)&per_cpu(page_states, cpu); | 1148 | in = (unsigned long *)&per_cpu(page_states, cpu); |
| 1144 | 1149 | ||
| 1145 | cpu = next_cpu(cpu, cpu_online_map); | 1150 | cpu = next_cpu(cpu, *cpumask); |
| 1146 | 1151 | ||
| 1147 | if (cpu < NR_CPUS) | 1152 | if (cpu < NR_CPUS) |
| 1148 | prefetch(&per_cpu(page_states, cpu)); | 1153 | prefetch(&per_cpu(page_states, cpu)); |
| @@ -1153,19 +1158,33 @@ void __get_page_state(struct page_state *ret, int nr) | |||
| 1153 | } | 1158 | } |
| 1154 | } | 1159 | } |
| 1155 | 1160 | ||
| 1161 | void get_page_state_node(struct page_state *ret, int node) | ||
| 1162 | { | ||
| 1163 | int nr; | ||
| 1164 | cpumask_t mask = node_to_cpumask(node); | ||
| 1165 | |||
| 1166 | nr = offsetof(struct page_state, GET_PAGE_STATE_LAST); | ||
| 1167 | nr /= sizeof(unsigned long); | ||
| 1168 | |||
| 1169 | __get_page_state(ret, nr+1, &mask); | ||
| 1170 | } | ||
| 1171 | |||
| 1156 | void get_page_state(struct page_state *ret) | 1172 | void get_page_state(struct page_state *ret) |
| 1157 | { | 1173 | { |
| 1158 | int nr; | 1174 | int nr; |
| 1175 | cpumask_t mask = CPU_MASK_ALL; | ||
| 1159 | 1176 | ||
| 1160 | nr = offsetof(struct page_state, GET_PAGE_STATE_LAST); | 1177 | nr = offsetof(struct page_state, GET_PAGE_STATE_LAST); |
| 1161 | nr /= sizeof(unsigned long); | 1178 | nr /= sizeof(unsigned long); |
| 1162 | 1179 | ||
| 1163 | __get_page_state(ret, nr + 1); | 1180 | __get_page_state(ret, nr + 1, &mask); |
| 1164 | } | 1181 | } |
| 1165 | 1182 | ||
| 1166 | void get_full_page_state(struct page_state *ret) | 1183 | void get_full_page_state(struct page_state *ret) |
| 1167 | { | 1184 | { |
| 1168 | __get_page_state(ret, sizeof(*ret) / sizeof(unsigned long)); | 1185 | cpumask_t mask = CPU_MASK_ALL; |
| 1186 | |||
| 1187 | __get_page_state(ret, sizeof(*ret) / sizeof(unsigned long), &mask); | ||
| 1169 | } | 1188 | } |
| 1170 | 1189 | ||
| 1171 | unsigned long __read_page_state(unsigned long offset) | 1190 | unsigned long __read_page_state(unsigned long offset) |
| @@ -1909,7 +1928,7 @@ static void __init free_area_init_core(struct pglist_data *pgdat, | |||
| 1909 | zone->nr_scan_inactive = 0; | 1928 | zone->nr_scan_inactive = 0; |
| 1910 | zone->nr_active = 0; | 1929 | zone->nr_active = 0; |
| 1911 | zone->nr_inactive = 0; | 1930 | zone->nr_inactive = 0; |
| 1912 | atomic_set(&zone->reclaim_in_progress, -1); | 1931 | atomic_set(&zone->reclaim_in_progress, 0); |
| 1913 | if (!size) | 1932 | if (!size) |
| 1914 | continue; | 1933 | continue; |
| 1915 | 1934 | ||
