]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: http://xenbits.xensource.com/linux-2.6.18-xen.hg?rev/329ea0ccb344 |
2 | # HG changeset patch | |
3 | # User Keir Fraser <keir.fraser@citrix.com> | |
4 | # Date 1244206880 -3600 | |
5 | # Node ID 329ea0ccb344c636e918cc3cd2677c24b03af5bd | |
6 | # Parent f59c5daed527f3a7ddf1270480ec63028c206f31 | |
7 | Subject: balloon: try harder to balloon up under memory pressure. | |
8 | Patch-mainline: obsolete | |
9 | ||
10 | Currently if the balloon driver is unable to increase the guest's | |
11 | reservation it assumes the failure was due to reaching its full | |
12 | allocation, gives up on the ballooning operation and records the limit | |
13 | it reached as the "hard limit". The driver will not try again until | |
14 | the target is set again (even to the same value). | |
15 | ||
16 | However it is possible that ballooning has in fact failed due to | |
17 | memory pressure in the host and therefore it is desirable to keep | |
18 | attempting to reach the target in case memory becomes available. The | |
19 | most likely scenario is that some guests are ballooning down while | |
20 | others are ballooning up and therefore there is temporary memory | |
21 | pressure while things stabilise. You would not expect a well behaved | |
22 | toolstack to ask a domain to balloon to more than its allocation nor | |
23 | would you expect it to deliberately over-commit memory by setting | |
24 | balloon targets which exceed the total host memory. | |
25 | ||
26 | This patch drops the concept of a hard limit and causes the balloon | |
27 | driver to retry increasing the reservation on a timer in the same | |
28 | manner as when decreasing the reservation. | |
29 | ||
30 | Also if we partially succeed in increasing the reservation | |
31 | (i.e. receive less pages than we asked for) then we may as well keep | |
32 | those pages rather than returning them to Xen. | |
33 | ||
34 | Signed-off-by: Ian Campbell <ian.campbell@citrix.com> | |
35 | Acked-by: jbeulich@novell.com | |
36 | ||
37 | --- sle11-2009-06-29.orig/drivers/xen/balloon/balloon.c 2008-11-25 13:31:07.000000000 +0100 | |
38 | +++ sle11-2009-06-29/drivers/xen/balloon/balloon.c 2009-06-29 15:24:00.000000000 +0200 | |
39 | @@ -188,7 +188,7 @@ static void balloon_alarm(unsigned long | |
40 | ||
41 | static unsigned long current_target(void) | |
42 | { | |
43 | - unsigned long target = min(bs.target_pages, bs.hard_limit); | |
44 | + unsigned long target = bs.target_pages; | |
45 | if (target > (bs.current_pages + bs.balloon_low + bs.balloon_high)) | |
46 | target = bs.current_pages + bs.balloon_low + bs.balloon_high; | |
47 | return target; | |
48 | @@ -255,26 +255,12 @@ static int increase_reservation(unsigned | |
49 | } | |
50 | ||
51 | set_xen_guest_handle(reservation.extent_start, frame_list); | |
52 | - reservation.nr_extents = nr_pages; | |
53 | - rc = HYPERVISOR_memory_op( | |
54 | - XENMEM_populate_physmap, &reservation); | |
55 | - if (rc < nr_pages) { | |
56 | - if (rc > 0) { | |
57 | - int ret; | |
58 | - | |
59 | - /* We hit the Xen hard limit: reprobe. */ | |
60 | - reservation.nr_extents = rc; | |
61 | - ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, | |
62 | - &reservation); | |
63 | - BUG_ON(ret != rc); | |
64 | - } | |
65 | - if (rc >= 0) | |
66 | - bs.hard_limit = (bs.current_pages + rc - | |
67 | - bs.driver_pages); | |
68 | + reservation.nr_extents = nr_pages; | |
69 | + rc = HYPERVISOR_memory_op(XENMEM_populate_physmap, &reservation); | |
70 | + if (rc < 0) | |
71 | goto out; | |
72 | - } | |
73 | ||
74 | - for (i = 0; i < nr_pages; i++) { | |
75 | + for (i = 0; i < rc; i++) { | |
76 | page = balloon_retrieve(); | |
77 | BUG_ON(page == NULL); | |
78 | ||
79 | @@ -302,13 +288,13 @@ static int increase_reservation(unsigned | |
80 | balloon_free_page(page); | |
81 | } | |
82 | ||
83 | - bs.current_pages += nr_pages; | |
84 | + bs.current_pages += rc; | |
85 | totalram_pages = bs.current_pages; | |
86 | ||
87 | out: | |
88 | balloon_unlock(flags); | |
89 | ||
90 | - return 0; | |
91 | + return rc < 0 ? rc : rc != nr_pages; | |
92 | } | |
93 | ||
94 | static int decrease_reservation(unsigned long nr_pages) | |
95 | @@ -420,7 +406,6 @@ static void balloon_process(void *unused | |
96 | void balloon_set_new_target(unsigned long target) | |
97 | { | |
98 | /* No need for lock. Not read-modify-write updates. */ | |
99 | - bs.hard_limit = ~0UL; | |
100 | bs.target_pages = max(target, minimum_target()); | |
101 | schedule_work(&balloon_worker); | |
102 | } | |
103 | @@ -498,17 +483,11 @@ static int balloon_read(char *page, char | |
104 | "Requested target: %8lu kB\n" | |
105 | "Low-mem balloon: %8lu kB\n" | |
106 | "High-mem balloon: %8lu kB\n" | |
107 | - "Driver pages: %8lu kB\n" | |
108 | - "Xen hard limit: ", | |
109 | + "Driver pages: %8lu kB\n", | |
110 | PAGES2KB(bs.current_pages), PAGES2KB(bs.target_pages), | |
111 | PAGES2KB(bs.balloon_low), PAGES2KB(bs.balloon_high), | |
112 | PAGES2KB(bs.driver_pages)); | |
113 | ||
114 | - if (bs.hard_limit != ~0UL) | |
115 | - len += sprintf(page + len, "%8lu kB\n", | |
116 | - PAGES2KB(bs.hard_limit)); | |
117 | - else | |
118 | - len += sprintf(page + len, " ??? kB\n"); | |
119 | ||
120 | *eof = 1; | |
121 | return len; | |
122 | @@ -539,7 +518,6 @@ static int __init balloon_init(void) | |
123 | bs.balloon_low = 0; | |
124 | bs.balloon_high = 0; | |
125 | bs.driver_pages = 0UL; | |
126 | - bs.hard_limit = ~0UL; | |
127 | ||
128 | init_timer(&balloon_timer); | |
129 | balloon_timer.data = 0; | |
130 | --- sle11-2009-06-29.orig/drivers/xen/balloon/common.h 2009-06-29 15:14:51.000000000 +0200 | |
131 | +++ sle11-2009-06-29/drivers/xen/balloon/common.h 2009-06-29 15:24:00.000000000 +0200 | |
132 | @@ -35,8 +35,6 @@ struct balloon_stats { | |
133 | /* We aim for 'current allocation' == 'target allocation'. */ | |
134 | unsigned long current_pages; | |
135 | unsigned long target_pages; | |
136 | - /* We may hit the hard limit in Xen. If we do then we remember it. */ | |
137 | - unsigned long hard_limit; | |
138 | /* | |
139 | * Drivers may alter the memory reservation independently, but they | |
140 | * must inform the balloon driver so we avoid hitting the hard limit. | |
141 | --- sle11-2009-06-29.orig/drivers/xen/balloon/sysfs.c 2008-11-25 13:31:07.000000000 +0100 | |
142 | +++ sle11-2009-06-29/drivers/xen/balloon/sysfs.c 2009-06-29 15:24:00.000000000 +0200 | |
143 | @@ -53,9 +53,6 @@ | |
144 | BALLOON_SHOW(current_kb, "%lu\n", PAGES2KB(bs.current_pages)); | |
145 | BALLOON_SHOW(low_kb, "%lu\n", PAGES2KB(bs.balloon_low)); | |
146 | BALLOON_SHOW(high_kb, "%lu\n", PAGES2KB(bs.balloon_high)); | |
147 | -BALLOON_SHOW(hard_limit_kb, | |
148 | - (bs.hard_limit!=~0UL) ? "%lu\n" : "???\n", | |
149 | - (bs.hard_limit!=~0UL) ? PAGES2KB(bs.hard_limit) : 0); | |
150 | BALLOON_SHOW(driver_kb, "%lu\n", PAGES2KB(bs.driver_pages)); | |
151 | ||
152 | static ssize_t show_target_kb(struct sys_device *dev, char *buf) | |
153 | @@ -96,7 +93,6 @@ static struct attribute *balloon_info_at | |
154 | &attr_current_kb.attr, | |
155 | &attr_low_kb.attr, | |
156 | &attr_high_kb.attr, | |
157 | - &attr_hard_limit_kb.attr, | |
158 | &attr_driver_kb.attr, | |
159 | NULL | |
160 | }; |