Annotation of /trunk/kernel26-xen/patches-2.6.25-r1/1041-2.6.25-xen-x86-dcr-fallback.patch
Parent Directory | Revision Log
Revision 609 -
(hide 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 | niro | 609 | 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 | /* |