diff options
Diffstat (limited to 'drivers/xen/balloon.c')
-rw-r--r-- | drivers/xen/balloon.c | 38 |
1 files changed, 9 insertions, 29 deletions
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index d31505b6f7a4..420433613584 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c | |||
@@ -66,8 +66,6 @@ struct balloon_stats { | |||
66 | /* We aim for 'current allocation' == 'target allocation'. */ | 66 | /* We aim for 'current allocation' == 'target allocation'. */ |
67 | unsigned long current_pages; | 67 | unsigned long current_pages; |
68 | unsigned long target_pages; | 68 | unsigned long target_pages; |
69 | /* We may hit the hard limit in Xen. If we do then we remember it. */ | ||
70 | unsigned long hard_limit; | ||
71 | /* | 69 | /* |
72 | * Drivers may alter the memory reservation independently, but they | 70 | * Drivers may alter the memory reservation independently, but they |
73 | * must inform the balloon driver so we avoid hitting the hard limit. | 71 | * must inform the balloon driver so we avoid hitting the hard limit. |
@@ -136,6 +134,8 @@ static void balloon_append(struct page *page) | |||
136 | list_add(&page->lru, &ballooned_pages); | 134 | list_add(&page->lru, &ballooned_pages); |
137 | balloon_stats.balloon_low++; | 135 | balloon_stats.balloon_low++; |
138 | } | 136 | } |
137 | |||
138 | totalram_pages--; | ||
139 | } | 139 | } |
140 | 140 | ||
141 | /* balloon_retrieve: rescue a page from the balloon, if it is not empty. */ | 141 | /* balloon_retrieve: rescue a page from the balloon, if it is not empty. */ |
@@ -156,6 +156,8 @@ static struct page *balloon_retrieve(void) | |||
156 | else | 156 | else |
157 | balloon_stats.balloon_low--; | 157 | balloon_stats.balloon_low--; |
158 | 158 | ||
159 | totalram_pages++; | ||
160 | |||
159 | return page; | 161 | return page; |
160 | } | 162 | } |
161 | 163 | ||
@@ -181,7 +183,7 @@ static void balloon_alarm(unsigned long unused) | |||
181 | 183 | ||
182 | static unsigned long current_target(void) | 184 | static unsigned long current_target(void) |
183 | { | 185 | { |
184 | unsigned long target = min(balloon_stats.target_pages, balloon_stats.hard_limit); | 186 | unsigned long target = balloon_stats.target_pages; |
185 | 187 | ||
186 | target = min(target, | 188 | target = min(target, |
187 | balloon_stats.current_pages + | 189 | balloon_stats.current_pages + |
@@ -217,23 +219,10 @@ static int increase_reservation(unsigned long nr_pages) | |||
217 | set_xen_guest_handle(reservation.extent_start, frame_list); | 219 | set_xen_guest_handle(reservation.extent_start, frame_list); |
218 | reservation.nr_extents = nr_pages; | 220 | reservation.nr_extents = nr_pages; |
219 | rc = HYPERVISOR_memory_op(XENMEM_populate_physmap, &reservation); | 221 | rc = HYPERVISOR_memory_op(XENMEM_populate_physmap, &reservation); |
220 | if (rc < nr_pages) { | 222 | if (rc < 0) |
221 | if (rc > 0) { | ||
222 | int ret; | ||
223 | |||
224 | /* We hit the Xen hard limit: reprobe. */ | ||
225 | reservation.nr_extents = rc; | ||
226 | ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, | ||
227 | &reservation); | ||
228 | BUG_ON(ret != rc); | ||
229 | } | ||
230 | if (rc >= 0) | ||
231 | balloon_stats.hard_limit = (balloon_stats.current_pages + rc - | ||
232 | balloon_stats.driver_pages); | ||
233 | goto out; | 223 | goto out; |
234 | } | ||
235 | 224 | ||
236 | for (i = 0; i < nr_pages; i++) { | 225 | for (i = 0; i < rc; i++) { |
237 | page = balloon_retrieve(); | 226 | page = balloon_retrieve(); |
238 | BUG_ON(page == NULL); | 227 | BUG_ON(page == NULL); |
239 | 228 | ||
@@ -259,13 +248,12 @@ static int increase_reservation(unsigned long nr_pages) | |||
259 | __free_page(page); | 248 | __free_page(page); |
260 | } | 249 | } |
261 | 250 | ||
262 | balloon_stats.current_pages += nr_pages; | 251 | balloon_stats.current_pages += rc; |
263 | totalram_pages = balloon_stats.current_pages; | ||
264 | 252 | ||
265 | out: | 253 | out: |
266 | spin_unlock_irqrestore(&balloon_lock, flags); | 254 | spin_unlock_irqrestore(&balloon_lock, flags); |
267 | 255 | ||
268 | return 0; | 256 | return rc < 0 ? rc : rc != nr_pages; |
269 | } | 257 | } |
270 | 258 | ||
271 | static int decrease_reservation(unsigned long nr_pages) | 259 | static int decrease_reservation(unsigned long nr_pages) |
@@ -323,7 +311,6 @@ static int decrease_reservation(unsigned long nr_pages) | |||
323 | BUG_ON(ret != nr_pages); | 311 | BUG_ON(ret != nr_pages); |
324 | 312 | ||
325 | balloon_stats.current_pages -= nr_pages; | 313 | balloon_stats.current_pages -= nr_pages; |
326 | totalram_pages = balloon_stats.current_pages; | ||
327 | 314 | ||
328 | spin_unlock_irqrestore(&balloon_lock, flags); | 315 | spin_unlock_irqrestore(&balloon_lock, flags); |
329 | 316 | ||
@@ -367,7 +354,6 @@ static void balloon_process(struct work_struct *work) | |||
367 | static void balloon_set_new_target(unsigned long target) | 354 | static void balloon_set_new_target(unsigned long target) |
368 | { | 355 | { |
369 | /* No need for lock. Not read-modify-write updates. */ | 356 | /* No need for lock. Not read-modify-write updates. */ |
370 | balloon_stats.hard_limit = ~0UL; | ||
371 | balloon_stats.target_pages = target; | 357 | balloon_stats.target_pages = target; |
372 | schedule_work(&balloon_worker); | 358 | schedule_work(&balloon_worker); |
373 | } | 359 | } |
@@ -422,12 +408,10 @@ static int __init balloon_init(void) | |||
422 | pr_info("xen_balloon: Initialising balloon driver.\n"); | 408 | pr_info("xen_balloon: Initialising balloon driver.\n"); |
423 | 409 | ||
424 | balloon_stats.current_pages = min(xen_start_info->nr_pages, max_pfn); | 410 | balloon_stats.current_pages = min(xen_start_info->nr_pages, max_pfn); |
425 | totalram_pages = balloon_stats.current_pages; | ||
426 | balloon_stats.target_pages = balloon_stats.current_pages; | 411 | balloon_stats.target_pages = balloon_stats.current_pages; |
427 | balloon_stats.balloon_low = 0; | 412 | balloon_stats.balloon_low = 0; |
428 | balloon_stats.balloon_high = 0; | 413 | balloon_stats.balloon_high = 0; |
429 | balloon_stats.driver_pages = 0UL; | 414 | balloon_stats.driver_pages = 0UL; |
430 | balloon_stats.hard_limit = ~0UL; | ||
431 | 415 | ||
432 | init_timer(&balloon_timer); | 416 | init_timer(&balloon_timer); |
433 | balloon_timer.data = 0; | 417 | balloon_timer.data = 0; |
@@ -472,9 +456,6 @@ module_exit(balloon_exit); | |||
472 | BALLOON_SHOW(current_kb, "%lu\n", PAGES2KB(balloon_stats.current_pages)); | 456 | BALLOON_SHOW(current_kb, "%lu\n", PAGES2KB(balloon_stats.current_pages)); |
473 | BALLOON_SHOW(low_kb, "%lu\n", PAGES2KB(balloon_stats.balloon_low)); | 457 | BALLOON_SHOW(low_kb, "%lu\n", PAGES2KB(balloon_stats.balloon_low)); |
474 | BALLOON_SHOW(high_kb, "%lu\n", PAGES2KB(balloon_stats.balloon_high)); | 458 | BALLOON_SHOW(high_kb, "%lu\n", PAGES2KB(balloon_stats.balloon_high)); |
475 | BALLOON_SHOW(hard_limit_kb, | ||
476 | (balloon_stats.hard_limit!=~0UL) ? "%lu\n" : "???\n", | ||
477 | (balloon_stats.hard_limit!=~0UL) ? PAGES2KB(balloon_stats.hard_limit) : 0); | ||
478 | BALLOON_SHOW(driver_kb, "%lu\n", PAGES2KB(balloon_stats.driver_pages)); | 459 | BALLOON_SHOW(driver_kb, "%lu\n", PAGES2KB(balloon_stats.driver_pages)); |
479 | 460 | ||
480 | static ssize_t show_target_kb(struct sys_device *dev, struct sysdev_attribute *attr, | 461 | static ssize_t show_target_kb(struct sys_device *dev, struct sysdev_attribute *attr, |
@@ -544,7 +525,6 @@ static struct attribute *balloon_info_attrs[] = { | |||
544 | &attr_current_kb.attr, | 525 | &attr_current_kb.attr, |
545 | &attr_low_kb.attr, | 526 | &attr_low_kb.attr, |
546 | &attr_high_kb.attr, | 527 | &attr_high_kb.attr, |
547 | &attr_hard_limit_kb.attr, | ||
548 | &attr_driver_kb.attr, | 528 | &attr_driver_kb.attr, |
549 | NULL | 529 | NULL |
550 | }; | 530 | }; |