Contents of /trunk/kernel26-xen/patches-2.6.25-r1/1041-2.6.25-xen-x86-dcr-fallback.patch
Parent Directory | Revision Log
Revision 609 -
(show annotations)
(download)
Fri May 23 17:35:37 2008 UTC (16 years, 4 months ago) by niro
File size: 4721 byte(s)
Fri May 23 17:35:37 2008 UTC (16 years, 4 months ago) by niro
File size: 4721 byte(s)
-using opensuse xen patchset, updated kernel configs
1 | Subject: Add fallback when XENMEM_exchange fails to replace contiguous region |
2 | From: jbeulich@novell.com |
3 | Patch-mainline: obsolete |
4 | References: 181869 |
5 | |
6 | This avoids losing precious special memory in places where any memory can be |
7 | used. |
8 | |
9 | Index: head-2008-04-15/arch/x86/mm/hypervisor.c |
10 | =================================================================== |
11 | --- head-2008-04-15.orig/arch/x86/mm/hypervisor.c 2008-04-15 10:34:43.000000000 +0200 |
12 | +++ head-2008-04-15/arch/x86/mm/hypervisor.c 2008-04-15 10:48:04.000000000 +0200 |
13 | @@ -41,6 +41,7 @@ |
14 | #include <xen/interface/memory.h> |
15 | #include <linux/module.h> |
16 | #include <linux/percpu.h> |
17 | +#include <linux/highmem.h> |
18 | #include <asm/tlbflush.h> |
19 | #include <linux/highmem.h> |
20 | |
21 | @@ -426,6 +427,83 @@ void xen_destroy_contiguous_region(unsig |
22 | BUG(); |
23 | |
24 | balloon_unlock(flags); |
25 | + |
26 | + if (unlikely(!success)) { |
27 | + /* Try hard to get the special memory back to Xen. */ |
28 | + exchange.in.extent_order = 0; |
29 | + set_xen_guest_handle(exchange.in.extent_start, &in_frame); |
30 | + |
31 | + for (i = 0; i < (1U<<order); i++) { |
32 | + struct page *page = alloc_page(__GFP_HIGHMEM|__GFP_COLD); |
33 | + unsigned long pfn; |
34 | + mmu_update_t mmu; |
35 | + unsigned int j = 0; |
36 | + |
37 | + if (!page) { |
38 | + printk(KERN_WARNING "Xen and kernel out of memory " |
39 | + "while trying to release an order %u " |
40 | + "contiguous region\n", order); |
41 | + break; |
42 | + } |
43 | + pfn = page_to_pfn(page); |
44 | + |
45 | + balloon_lock(flags); |
46 | + |
47 | + if (!PageHighMem(page)) { |
48 | + void *v = __va(pfn << PAGE_SHIFT); |
49 | + |
50 | + scrub_pages(v, 1); |
51 | + MULTI_update_va_mapping(cr_mcl + j, (unsigned long)v, |
52 | + __pte_ma(0), UVMF_INVLPG|UVMF_ALL); |
53 | + ++j; |
54 | + } |
55 | +#ifdef CONFIG_XEN_SCRUB_PAGES |
56 | + else { |
57 | + scrub_pages(kmap(page), 1); |
58 | + kunmap(page); |
59 | + kmap_flush_unused(); |
60 | + } |
61 | +#endif |
62 | + |
63 | + frame = pfn_to_mfn(pfn); |
64 | + set_phys_to_machine(pfn, INVALID_P2M_ENTRY); |
65 | + |
66 | + MULTI_update_va_mapping(cr_mcl + j, vstart, |
67 | + pfn_pte_ma(frame, PAGE_KERNEL), |
68 | + UVMF_INVLPG|UVMF_ALL); |
69 | + ++j; |
70 | + |
71 | + pfn = __pa(vstart) >> PAGE_SHIFT; |
72 | + set_phys_to_machine(pfn, frame); |
73 | + if (!xen_feature(XENFEAT_auto_translated_physmap)) { |
74 | + mmu.ptr = ((uint64_t)frame << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE; |
75 | + mmu.val = pfn; |
76 | + cr_mcl[j].op = __HYPERVISOR_mmu_update; |
77 | + cr_mcl[j].args[0] = (unsigned long)&mmu; |
78 | + cr_mcl[j].args[1] = 1; |
79 | + cr_mcl[j].args[2] = 0; |
80 | + cr_mcl[j].args[3] = DOMID_SELF; |
81 | + ++j; |
82 | + } |
83 | + |
84 | + cr_mcl[j].op = __HYPERVISOR_memory_op; |
85 | + cr_mcl[j].args[0] = XENMEM_decrease_reservation; |
86 | + cr_mcl[j].args[1] = (unsigned long)&exchange.in; |
87 | + |
88 | + if (HYPERVISOR_multicall(cr_mcl, j + 1)) |
89 | + BUG(); |
90 | + BUG_ON(cr_mcl[j].result != 1); |
91 | + while (j--) |
92 | + BUG_ON(cr_mcl[j].result != 0); |
93 | + |
94 | + balloon_unlock(flags); |
95 | + |
96 | + free_empty_pages(&page, 1); |
97 | + |
98 | + in_frame++; |
99 | + vstart += PAGE_SIZE; |
100 | + } |
101 | + } |
102 | } |
103 | EXPORT_SYMBOL_GPL(xen_destroy_contiguous_region); |
104 | |
105 | Index: head-2008-04-15/drivers/xen/balloon/balloon.c |
106 | =================================================================== |
107 | --- head-2008-04-15.orig/drivers/xen/balloon/balloon.c 2008-04-15 10:48:02.000000000 +0200 |
108 | +++ head-2008-04-15/drivers/xen/balloon/balloon.c 2008-04-15 10:48:04.000000000 +0200 |
109 | @@ -686,7 +686,7 @@ struct page **alloc_empty_pages_and_page |
110 | goto out; |
111 | } |
112 | |
113 | -void free_empty_pages_and_pagevec(struct page **pagevec, int nr_pages) |
114 | +static void _free_empty_pages_and_pagevec(struct page **pagevec, int nr_pages, int free_vec) |
115 | { |
116 | unsigned long flags; |
117 | int i; |
118 | @@ -701,11 +701,24 @@ void free_empty_pages_and_pagevec(struct |
119 | } |
120 | balloon_unlock(flags); |
121 | |
122 | - kfree(pagevec); |
123 | + if (free_vec) |
124 | + kfree(pagevec); |
125 | + else |
126 | + totalram_pages = bs.current_pages -= nr_pages; |
127 | |
128 | schedule_work(&balloon_worker); |
129 | } |
130 | |
131 | +void free_empty_pages_and_pagevec(struct page **pagevec, int nr_pages) |
132 | +{ |
133 | + _free_empty_pages_and_pagevec(pagevec, nr_pages, 1); |
134 | +} |
135 | + |
136 | +void free_empty_pages(struct page **pagevec, int nr_pages) |
137 | +{ |
138 | + _free_empty_pages_and_pagevec(pagevec, nr_pages, 0); |
139 | +} |
140 | + |
141 | void balloon_release_driver_page(struct page *page) |
142 | { |
143 | unsigned long flags; |
144 | Index: head-2008-04-15/include/xen/balloon.h |
145 | =================================================================== |
146 | --- head-2008-04-15.orig/include/xen/balloon.h 2007-06-12 13:14:19.000000000 +0200 |
147 | +++ head-2008-04-15/include/xen/balloon.h 2008-04-15 10:48:04.000000000 +0200 |
148 | @@ -44,6 +44,10 @@ void balloon_update_driver_allowance(lon |
149 | struct page **alloc_empty_pages_and_pagevec(int nr_pages); |
150 | void free_empty_pages_and_pagevec(struct page **pagevec, int nr_pages); |
151 | |
152 | +/* Free an empty page range (not allocated through |
153 | + alloc_empty_pages_and_pagevec), adding to the balloon. */ |
154 | +void free_empty_pages(struct page **pagevec, int nr_pages); |
155 | + |
156 | void balloon_release_driver_page(struct page *page); |
157 | |
158 | /* |