diff options
| -rw-r--r-- | drivers/base/node.c | 24 | ||||
| -rw-r--r-- | include/linux/page-flags.h | 1 | ||||
| -rw-r--r-- | mm/page_alloc.c | 25 |
3 files changed, 43 insertions, 7 deletions
diff --git a/drivers/base/node.c b/drivers/base/node.c index 904b27caf697..16c513aa4d48 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c | |||
| @@ -39,13 +39,25 @@ static ssize_t node_read_meminfo(struct sys_device * dev, char * buf) | |||
| 39 | int n; | 39 | int n; |
| 40 | int nid = dev->id; | 40 | int nid = dev->id; |
| 41 | struct sysinfo i; | 41 | struct sysinfo i; |
| 42 | struct page_state ps; | ||
| 42 | unsigned long inactive; | 43 | unsigned long inactive; |
| 43 | unsigned long active; | 44 | unsigned long active; |
| 44 | unsigned long free; | 45 | unsigned long free; |
| 45 | 46 | ||
| 46 | si_meminfo_node(&i, nid); | 47 | si_meminfo_node(&i, nid); |
| 48 | get_page_state_node(&ps, nid); | ||
| 47 | __get_zone_counts(&active, &inactive, &free, NODE_DATA(nid)); | 49 | __get_zone_counts(&active, &inactive, &free, NODE_DATA(nid)); |
| 48 | 50 | ||
| 51 | /* Check for negative values in these approximate counters */ | ||
| 52 | if ((long)ps.nr_dirty < 0) | ||
| 53 | ps.nr_dirty = 0; | ||
| 54 | if ((long)ps.nr_writeback < 0) | ||
| 55 | ps.nr_writeback = 0; | ||
| 56 | if ((long)ps.nr_mapped < 0) | ||
| 57 | ps.nr_mapped = 0; | ||
| 58 | if ((long)ps.nr_slab < 0) | ||
| 59 | ps.nr_slab = 0; | ||
| 60 | |||
| 49 | n = sprintf(buf, "\n" | 61 | n = sprintf(buf, "\n" |
| 50 | "Node %d MemTotal: %8lu kB\n" | 62 | "Node %d MemTotal: %8lu kB\n" |
| 51 | "Node %d MemFree: %8lu kB\n" | 63 | "Node %d MemFree: %8lu kB\n" |
| @@ -55,7 +67,11 @@ static ssize_t node_read_meminfo(struct sys_device * dev, char * buf) | |||
| 55 | "Node %d HighTotal: %8lu kB\n" | 67 | "Node %d HighTotal: %8lu kB\n" |
| 56 | "Node %d HighFree: %8lu kB\n" | 68 | "Node %d HighFree: %8lu kB\n" |
| 57 | "Node %d LowTotal: %8lu kB\n" | 69 | "Node %d LowTotal: %8lu kB\n" |
| 58 | "Node %d LowFree: %8lu kB\n", | 70 | "Node %d LowFree: %8lu kB\n" |
| 71 | "Node %d Dirty: %8lu kB\n" | ||
| 72 | "Node %d Writeback: %8lu kB\n" | ||
| 73 | "Node %d Mapped: %8lu kB\n" | ||
| 74 | "Node %d Slab: %8lu kB\n", | ||
| 59 | nid, K(i.totalram), | 75 | nid, K(i.totalram), |
| 60 | nid, K(i.freeram), | 76 | nid, K(i.freeram), |
| 61 | nid, K(i.totalram - i.freeram), | 77 | nid, K(i.totalram - i.freeram), |
| @@ -64,7 +80,11 @@ static ssize_t node_read_meminfo(struct sys_device * dev, char * buf) | |||
| 64 | nid, K(i.totalhigh), | 80 | nid, K(i.totalhigh), |
| 65 | nid, K(i.freehigh), | 81 | nid, K(i.freehigh), |
| 66 | nid, K(i.totalram - i.totalhigh), | 82 | nid, K(i.totalram - i.totalhigh), |
| 67 | nid, K(i.freeram - i.freehigh)); | 83 | nid, K(i.freeram - i.freehigh), |
| 84 | nid, K(ps.nr_dirty), | ||
| 85 | nid, K(ps.nr_writeback), | ||
| 86 | nid, K(ps.nr_mapped), | ||
| 87 | nid, K(ps.nr_slab)); | ||
| 68 | n += hugetlb_report_node_meminfo(nid, buf + n); | 88 | n += hugetlb_report_node_meminfo(nid, buf + n); |
| 69 | return n; | 89 | return n; |
| 70 | } | 90 | } |
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 99f7cc495065..f34767c5fc79 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h | |||
| @@ -134,6 +134,7 @@ struct page_state { | |||
| 134 | }; | 134 | }; |
| 135 | 135 | ||
| 136 | extern void get_page_state(struct page_state *ret); | 136 | extern void get_page_state(struct page_state *ret); |
| 137 | extern void get_page_state_node(struct page_state *ret, int node); | ||
| 137 | extern void get_full_page_state(struct page_state *ret); | 138 | extern void get_full_page_state(struct page_state *ret); |
| 138 | extern unsigned long __read_page_state(unsigned long offset); | 139 | extern unsigned long __read_page_state(unsigned long offset); |
| 139 | extern void __mod_page_state(unsigned long offset, unsigned long delta); | 140 | extern void __mod_page_state(unsigned long offset, unsigned long delta); |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index d157dae8c9f3..b06a9636d971 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
| @@ -1130,19 +1130,20 @@ EXPORT_SYMBOL(nr_pagecache); | |||
| 1130 | DEFINE_PER_CPU(long, nr_pagecache_local) = 0; | 1130 | DEFINE_PER_CPU(long, nr_pagecache_local) = 0; |
| 1131 | #endif | 1131 | #endif |
| 1132 | 1132 | ||
| 1133 | void __get_page_state(struct page_state *ret, int nr) | 1133 | void __get_page_state(struct page_state *ret, int nr, cpumask_t *cpumask) |
| 1134 | { | 1134 | { |
| 1135 | int cpu = 0; | 1135 | int cpu = 0; |
| 1136 | 1136 | ||
| 1137 | memset(ret, 0, sizeof(*ret)); | 1137 | memset(ret, 0, sizeof(*ret)); |
| 1138 | cpus_and(*cpumask, *cpumask, cpu_online_map); | ||
| 1138 | 1139 | ||
| 1139 | cpu = first_cpu(cpu_online_map); | 1140 | cpu = first_cpu(*cpumask); |
| 1140 | while (cpu < NR_CPUS) { | 1141 | while (cpu < NR_CPUS) { |
| 1141 | unsigned long *in, *out, off; | 1142 | unsigned long *in, *out, off; |
| 1142 | 1143 | ||
| 1143 | in = (unsigned long *)&per_cpu(page_states, cpu); | 1144 | in = (unsigned long *)&per_cpu(page_states, cpu); |
| 1144 | 1145 | ||
| 1145 | cpu = next_cpu(cpu, cpu_online_map); | 1146 | cpu = next_cpu(cpu, *cpumask); |
| 1146 | 1147 | ||
| 1147 | if (cpu < NR_CPUS) | 1148 | if (cpu < NR_CPUS) |
| 1148 | prefetch(&per_cpu(page_states, cpu)); | 1149 | prefetch(&per_cpu(page_states, cpu)); |
| @@ -1153,19 +1154,33 @@ void __get_page_state(struct page_state *ret, int nr) | |||
| 1153 | } | 1154 | } |
| 1154 | } | 1155 | } |
| 1155 | 1156 | ||
| 1157 | void get_page_state_node(struct page_state *ret, int node) | ||
| 1158 | { | ||
| 1159 | int nr; | ||
| 1160 | cpumask_t mask = node_to_cpumask(node); | ||
| 1161 | |||
| 1162 | nr = offsetof(struct page_state, GET_PAGE_STATE_LAST); | ||
| 1163 | nr /= sizeof(unsigned long); | ||
| 1164 | |||
| 1165 | __get_page_state(ret, nr+1, &mask); | ||
| 1166 | } | ||
| 1167 | |||
| 1156 | void get_page_state(struct page_state *ret) | 1168 | void get_page_state(struct page_state *ret) |
| 1157 | { | 1169 | { |
| 1158 | int nr; | 1170 | int nr; |
| 1171 | cpumask_t mask = CPU_MASK_ALL; | ||
| 1159 | 1172 | ||
| 1160 | nr = offsetof(struct page_state, GET_PAGE_STATE_LAST); | 1173 | nr = offsetof(struct page_state, GET_PAGE_STATE_LAST); |
| 1161 | nr /= sizeof(unsigned long); | 1174 | nr /= sizeof(unsigned long); |
| 1162 | 1175 | ||
| 1163 | __get_page_state(ret, nr + 1); | 1176 | __get_page_state(ret, nr + 1, &mask); |
| 1164 | } | 1177 | } |
| 1165 | 1178 | ||
| 1166 | void get_full_page_state(struct page_state *ret) | 1179 | void get_full_page_state(struct page_state *ret) |
| 1167 | { | 1180 | { |
| 1168 | __get_page_state(ret, sizeof(*ret) / sizeof(unsigned long)); | 1181 | cpumask_t mask = CPU_MASK_ALL; |
| 1182 | |||
| 1183 | __get_page_state(ret, sizeof(*ret) / sizeof(unsigned long), &mask); | ||
| 1169 | } | 1184 | } |
| 1170 | 1185 | ||
| 1171 | unsigned long __read_page_state(unsigned long offset) | 1186 | unsigned long __read_page_state(unsigned long offset) |
