]> git.ipfire.org Git - ipfire-2.x.git/blob - src/patches/suse-2.6.27.39/patches.xen/xen-balloon-accounting
Imported linux-2.6.27.39 suse/xen patches.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.xen / xen-balloon-accounting
1 From: jbeulich@novell.com
2 Subject: improve interaction with mm's accounting
3 References: bnc#509753
4 Patch-mainline: obsolete
5
6 --- sle11-2009-08-26.orig/arch/x86/kernel/e820-xen.c 2009-08-31 11:47:11.000000000 +0200
7 +++ sle11-2009-08-26/arch/x86/kernel/e820-xen.c 2009-06-25 14:20:32.000000000 +0200
8 @@ -1221,6 +1221,11 @@ int __init e820_find_active_region(const
9 {
10 u64 align = PAGE_SIZE;
11
12 +#ifdef CONFIG_XEN
13 + if (last_pfn > xen_start_info->nr_pages)
14 + last_pfn = xen_start_info->nr_pages;
15 +#endif
16 +
17 *ei_startpfn = round_up(ei->addr, align) >> PAGE_SHIFT;
18 *ei_endpfn = round_down(ei->addr + ei->size, align) >> PAGE_SHIFT;
19
20 @@ -1255,6 +1260,10 @@ void __init e820_register_active_regions
21 start_pfn, last_pfn,
22 &ei_startpfn, &ei_endpfn))
23 add_active_range(nid, ei_startpfn, ei_endpfn);
24 +#ifdef CONFIG_XEN
25 + BUG_ON(nid);
26 + add_active_range(nid, last_pfn, last_pfn);
27 +#endif
28 }
29
30 /*
31 --- sle11-2009-08-26.orig/arch/x86/mm/init_32-xen.c 2009-08-31 11:47:11.000000000 +0200
32 +++ sle11-2009-08-26/arch/x86/mm/init_32-xen.c 2009-08-26 12:11:50.000000000 +0200
33 @@ -399,8 +399,7 @@ static void __init add_one_highpage_init
34 {
35 ClearPageReserved(page);
36 init_page_count(page);
37 - if (pfn < xen_start_info->nr_pages)
38 - __free_page(page);
39 + __free_page(page);
40 totalhigh_pages++;
41 }
42
43 @@ -450,8 +449,16 @@ void __init add_highpages_with_active_re
44 #ifndef CONFIG_NUMA
45 static void __init set_highmem_pages_init(void)
46 {
47 + unsigned long pfn;
48 +
49 add_highpages_with_active_regions(0, highstart_pfn, highend_pfn);
50
51 + /* XEN: init high-mem pages outside initial allocation. */
52 + for (pfn = xen_start_info->nr_pages; pfn < highend_pfn; pfn++) {
53 + ClearPageReserved(pfn_to_page(pfn));
54 + init_page_count(pfn_to_page(pfn));
55 + }
56 +
57 totalram_pages += totalhigh_pages;
58 }
59 #endif /* !CONFIG_NUMA */
60 @@ -1006,11 +1013,10 @@ void __init mem_init(void)
61 #endif
62 /* this will put all low memory onto the freelists */
63 totalram_pages += free_all_bootmem();
64 - /* XEN: init and count low-mem pages outside initial allocation. */
65 + /* XEN: init low-mem pages outside initial allocation. */
66 for (pfn = xen_start_info->nr_pages; pfn < max_low_pfn; pfn++) {
67 ClearPageReserved(pfn_to_page(pfn));
68 init_page_count(pfn_to_page(pfn));
69 - totalram_pages++;
70 }
71
72 reservedpages = 0;
73 --- sle11-2009-08-26.orig/arch/x86/mm/init_64-xen.c 2009-08-31 11:47:11.000000000 +0200
74 +++ sle11-2009-08-26/arch/x86/mm/init_64-xen.c 2009-08-26 12:11:53.000000000 +0200
75 @@ -1085,11 +1085,10 @@ void __init mem_init(void)
76 #else
77 totalram_pages = free_all_bootmem();
78 #endif
79 - /* XEN: init and count pages outside initial allocation. */
80 + /* XEN: init pages outside initial allocation. */
81 for (pfn = xen_start_info->nr_pages; pfn < max_pfn; pfn++) {
82 ClearPageReserved(pfn_to_page(pfn));
83 init_page_count(pfn_to_page(pfn));
84 - totalram_pages++;
85 }
86 reservedpages = max_pfn - totalram_pages -
87 absent_pages_in_range(0, max_pfn);
88 --- sle11-2009-08-26.orig/drivers/xen/balloon/balloon.c 2009-06-29 15:44:49.000000000 +0200
89 +++ sle11-2009-08-26/drivers/xen/balloon/balloon.c 2009-08-31 11:47:38.000000000 +0200
90 @@ -37,6 +37,7 @@
91 #include <linux/sched.h>
92 #include <linux/errno.h>
93 #include <linux/mm.h>
94 +#include <linux/swap.h>
95 #include <linux/mman.h>
96 #include <linux/smp_lock.h>
97 #include <linux/pagemap.h>
98 @@ -81,11 +82,7 @@ struct balloon_stats balloon_stats;
99 /* We increase/decrease in batches which fit in a page */
100 static unsigned long frame_list[PAGE_SIZE / sizeof(unsigned long)];
101
102 -/* VM /proc information for memory */
103 -extern unsigned long totalram_pages;
104 -
105 #ifdef CONFIG_HIGHMEM
106 -extern unsigned long totalhigh_pages;
107 #define inc_totalhigh_pages() (totalhigh_pages++)
108 #define dec_totalhigh_pages() (totalhigh_pages--)
109 #else
110 @@ -121,29 +118,44 @@ static struct timer_list balloon_timer;
111 printk(KERN_WARNING "xen_mem: " fmt, ##args)
112
113 /* balloon_append: add the given page to the balloon. */
114 -static void balloon_append(struct page *page)
115 +static void balloon_append(struct page *page, int account)
116 {
117 + unsigned long pfn;
118 +
119 /* Lowmem is re-populated first, so highmem pages go at list tail. */
120 if (PageHighMem(page)) {
121 list_add_tail(PAGE_TO_LIST(page), &ballooned_pages);
122 bs.balloon_high++;
123 - dec_totalhigh_pages();
124 + if (account)
125 + dec_totalhigh_pages();
126 } else {
127 list_add(PAGE_TO_LIST(page), &ballooned_pages);
128 bs.balloon_low++;
129 }
130 +
131 + pfn = page_to_pfn(page);
132 + if (account) {
133 + SetPageReserved(page);
134 + set_phys_to_machine(pfn, INVALID_P2M_ENTRY);
135 + page_zone(page)->present_pages--;
136 + } else {
137 + BUG_ON(!PageReserved(page));
138 + WARN_ON_ONCE(phys_to_machine_mapping_valid(pfn));
139 + }
140 }
141
142 /* balloon_retrieve: rescue a page from the balloon, if it is not empty. */
143 -static struct page *balloon_retrieve(void)
144 +static struct page *balloon_retrieve(int *was_empty)
145 {
146 struct page *page;
147 + struct zone *zone;
148
149 if (list_empty(&ballooned_pages))
150 return NULL;
151
152 page = LIST_TO_PAGE(ballooned_pages.next);
153 UNLIST_PAGE(page);
154 + BUG_ON(!PageReserved(page));
155
156 if (PageHighMem(page)) {
157 bs.balloon_high--;
158 @@ -151,6 +163,9 @@ static struct page *balloon_retrieve(voi
159 }
160 else
161 bs.balloon_low--;
162 + zone = page_zone(page);
163 + *was_empty |= !populated_zone(zone);
164 + zone->present_pages++;
165
166 return page;
167 }
168 @@ -236,6 +251,7 @@ static int increase_reservation(unsigned
169 unsigned long pfn, i, flags;
170 struct page *page;
171 long rc;
172 + int need_zonelists_rebuild = 0;
173 struct xen_memory_reservation reservation = {
174 .address_bits = 0,
175 .extent_order = 0,
176 @@ -261,7 +277,7 @@ static int increase_reservation(unsigned
177 goto out;
178
179 for (i = 0; i < rc; i++) {
180 - page = balloon_retrieve();
181 + page = balloon_retrieve(&need_zonelists_rebuild);
182 BUG_ON(page == NULL);
183
184 pfn = page_to_pfn(page);
185 @@ -294,6 +310,14 @@ static int increase_reservation(unsigned
186 out:
187 balloon_unlock(flags);
188
189 +#ifndef MODULE
190 + setup_per_zone_pages_min();
191 + if (need_zonelists_rebuild)
192 + build_all_zonelists();
193 + else
194 + vm_total_pages = nr_free_pagecache_pages();
195 +#endif
196 +
197 return rc < 0 ? rc : rc != nr_pages;
198 }
199
200 @@ -352,8 +376,7 @@ static int decrease_reservation(unsigned
201 /* No more mappings: invalidate P2M and add to balloon. */
202 for (i = 0; i < nr_pages; i++) {
203 pfn = mfn_to_pfn(frame_list[i]);
204 - set_phys_to_machine(pfn, INVALID_P2M_ENTRY);
205 - balloon_append(pfn_to_page(pfn));
206 + balloon_append(pfn_to_page(pfn), 1);
207 }
208
209 set_xen_guest_handle(reservation.extent_start, frame_list);
210 @@ -541,8 +564,11 @@ static int __init balloon_init(void)
211 /* Initialise the balloon with excess memory space. */
212 for (pfn = xen_start_info->nr_pages; pfn < max_pfn; pfn++) {
213 page = pfn_to_page(pfn);
214 - if (!PageReserved(page))
215 - balloon_append(page);
216 + if (!PageReserved(page)) {
217 + SetPageReserved(page);
218 + set_phys_to_machine(pfn, INVALID_P2M_ENTRY);
219 + balloon_append(page, 0);
220 + }
221 }
222 #endif
223
224 @@ -577,7 +603,7 @@ void balloon_update_driver_allowance(lon
225 static int dealloc_pte_fn(
226 pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
227 {
228 - unsigned long mfn = pte_mfn(*pte);
229 + unsigned long pfn, mfn = pte_mfn(*pte);
230 int ret;
231 struct xen_memory_reservation reservation = {
232 .nr_extents = 1,
233 @@ -586,7 +612,9 @@ static int dealloc_pte_fn(
234 };
235 set_xen_guest_handle(reservation.extent_start, &mfn);
236 set_pte_at(&init_mm, addr, pte, __pte_ma(0));
237 - set_phys_to_machine(__pa(addr) >> PAGE_SHIFT, INVALID_P2M_ENTRY);
238 + pfn = __pa(addr) >> PAGE_SHIFT;
239 + set_phys_to_machine(pfn, INVALID_P2M_ENTRY);
240 + SetPageReserved(pfn_to_page(pfn));
241 ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation);
242 BUG_ON(ret != 1);
243 return 0;
244 @@ -644,6 +672,9 @@ struct page **alloc_empty_pages_and_page
245 }
246
247 totalram_pages = --bs.current_pages;
248 + if (PageHighMem(page))
249 + dec_totalhigh_pages();
250 + page_zone(page)->present_pages--;
251
252 balloon_unlock(flags);
253 }
254 @@ -658,7 +689,7 @@ struct page **alloc_empty_pages_and_page
255 err:
256 balloon_lock(flags);
257 while (--i >= 0)
258 - balloon_append(pagevec[i]);
259 + balloon_append(pagevec[i], 0);
260 balloon_unlock(flags);
261 kfree(pagevec);
262 pagevec = NULL;
263 @@ -676,7 +707,7 @@ void free_empty_pages_and_pagevec(struct
264 balloon_lock(flags);
265 for (i = 0; i < nr_pages; i++) {
266 BUG_ON(page_count(pagevec[i]) != 1);
267 - balloon_append(pagevec[i]);
268 + balloon_append(pagevec[i], 0);
269 }
270 balloon_unlock(flags);
271
272 @@ -690,7 +721,7 @@ void balloon_release_driver_page(struct
273 unsigned long flags;
274
275 balloon_lock(flags);
276 - balloon_append(page);
277 + balloon_append(page, 1);
278 bs.driver_pages--;
279 balloon_unlock(flags);
280
281 --- sle11-2009-08-26.orig/mm/page_alloc.c 2009-08-31 11:47:11.000000000 +0200
282 +++ sle11-2009-08-26/mm/page_alloc.c 2009-07-31 15:14:57.000000000 +0200
283 @@ -4343,6 +4343,23 @@ static void __setup_per_zone_pages_min(v
284 spin_unlock_irqrestore(&zone->lock, flags);
285 }
286
287 +#ifdef CONFIG_XEN
288 + for_each_zone(zone) {
289 + unsigned int cpu;
290 +
291 + if (!populated_zone(zone))
292 + continue;
293 + for_each_online_cpu(cpu) {
294 + unsigned long high;
295 +
296 + high = percpu_pagelist_fraction
297 + ? zone->present_pages / percpu_pagelist_fraction
298 + : 5 * zone_batchsize(zone);
299 + setup_pagelist_highmark(zone_pcp(zone, cpu), high);
300 + }
301 + }
302 +#endif
303 +
304 /* update totalreserve_pages */
305 calculate_totalreserve_pages();
306 }