diff options
| -rw-r--r-- | drivers/xen/balloon.c | 31 |
1 files changed, 5 insertions, 26 deletions
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index 6eb62654410a..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. |
| @@ -185,7 +183,7 @@ static void balloon_alarm(unsigned long unused) | |||
| 185 | 183 | ||
| 186 | static unsigned long current_target(void) | 184 | static unsigned long current_target(void) |
| 187 | { | 185 | { |
| 188 | unsigned long target = min(balloon_stats.target_pages, balloon_stats.hard_limit); | 186 | unsigned long target = balloon_stats.target_pages; |
| 189 | 187 | ||
| 190 | target = min(target, | 188 | target = min(target, |
| 191 | balloon_stats.current_pages + | 189 | balloon_stats.current_pages + |
| @@ -221,23 +219,10 @@ static int increase_reservation(unsigned long nr_pages) | |||
| 221 | set_xen_guest_handle(reservation.extent_start, frame_list); | 219 | set_xen_guest_handle(reservation.extent_start, frame_list); |
| 222 | reservation.nr_extents = nr_pages; | 220 | reservation.nr_extents = nr_pages; |
| 223 | rc = HYPERVISOR_memory_op(XENMEM_populate_physmap, &reservation); | 221 | rc = HYPERVISOR_memory_op(XENMEM_populate_physmap, &reservation); |
| 224 | if (rc < nr_pages) { | 222 | if (rc < 0) |
| 225 | if (rc > 0) { | ||
| 226 | int ret; | ||
| 227 | |||
| 228 | /* We hit the Xen hard limit: reprobe. */ | ||
| 229 | reservation.nr_extents = rc; | ||
| 230 | ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, | ||
| 231 | &reservation); | ||
| 232 | BUG_ON(ret != rc); | ||
| 233 | } | ||
| 234 | if (rc >= 0) | ||
| 235 | balloon_stats.hard_limit = (balloon_stats.current_pages + rc - | ||
| 236 | balloon_stats.driver_pages); | ||
| 237 | goto out; | 223 | goto out; |
| 238 | } | ||
| 239 | 224 | ||
| 240 | for (i = 0; i < nr_pages; i++) { | 225 | for (i = 0; i < rc; i++) { |
| 241 | page = balloon_retrieve(); | 226 | page = balloon_retrieve(); |
| 242 | BUG_ON(page == NULL); | 227 | BUG_ON(page == NULL); |
| 243 | 228 | ||
| @@ -263,12 +248,12 @@ static int increase_reservation(unsigned long nr_pages) | |||
| 263 | __free_page(page); | 248 | __free_page(page); |
| 264 | } | 249 | } |
| 265 | 250 | ||
| 266 | balloon_stats.current_pages += nr_pages; | 251 | balloon_stats.current_pages += rc; |
| 267 | 252 | ||
| 268 | out: | 253 | out: |
| 269 | spin_unlock_irqrestore(&balloon_lock, flags); | 254 | spin_unlock_irqrestore(&balloon_lock, flags); |
| 270 | 255 | ||
| 271 | return 0; | 256 | return rc < 0 ? rc : rc != nr_pages; |
| 272 | } | 257 | } |
| 273 | 258 | ||
| 274 | static int decrease_reservation(unsigned long nr_pages) | 259 | static int decrease_reservation(unsigned long nr_pages) |
| @@ -369,7 +354,6 @@ static void balloon_process(struct work_struct *work) | |||
| 369 | static void balloon_set_new_target(unsigned long target) | 354 | static void balloon_set_new_target(unsigned long target) |
| 370 | { | 355 | { |
| 371 | /* No need for lock. Not read-modify-write updates. */ | 356 | /* No need for lock. Not read-modify-write updates. */ |
| 372 | balloon_stats.hard_limit = ~0UL; | ||
| 373 | balloon_stats.target_pages = target; | 357 | balloon_stats.target_pages = target; |
| 374 | schedule_work(&balloon_worker); | 358 | schedule_work(&balloon_worker); |
| 375 | } | 359 | } |
| @@ -428,7 +412,6 @@ static int __init balloon_init(void) | |||
| 428 | balloon_stats.balloon_low = 0; | 412 | balloon_stats.balloon_low = 0; |
| 429 | balloon_stats.balloon_high = 0; | 413 | balloon_stats.balloon_high = 0; |
| 430 | balloon_stats.driver_pages = 0UL; | 414 | balloon_stats.driver_pages = 0UL; |
| 431 | balloon_stats.hard_limit = ~0UL; | ||
| 432 | 415 | ||
| 433 | init_timer(&balloon_timer); | 416 | init_timer(&balloon_timer); |
| 434 | balloon_timer.data = 0; | 417 | balloon_timer.data = 0; |
| @@ -473,9 +456,6 @@ module_exit(balloon_exit); | |||
| 473 | BALLOON_SHOW(current_kb, "%lu\n", PAGES2KB(balloon_stats.current_pages)); | 456 | BALLOON_SHOW(current_kb, "%lu\n", PAGES2KB(balloon_stats.current_pages)); |
| 474 | BALLOON_SHOW(low_kb, "%lu\n", PAGES2KB(balloon_stats.balloon_low)); | 457 | BALLOON_SHOW(low_kb, "%lu\n", PAGES2KB(balloon_stats.balloon_low)); |
| 475 | BALLOON_SHOW(high_kb, "%lu\n", PAGES2KB(balloon_stats.balloon_high)); | 458 | BALLOON_SHOW(high_kb, "%lu\n", PAGES2KB(balloon_stats.balloon_high)); |
| 476 | BALLOON_SHOW(hard_limit_kb, | ||
| 477 | (balloon_stats.hard_limit!=~0UL) ? "%lu\n" : "???\n", | ||
| 478 | (balloon_stats.hard_limit!=~0UL) ? PAGES2KB(balloon_stats.hard_limit) : 0); | ||
| 479 | BALLOON_SHOW(driver_kb, "%lu\n", PAGES2KB(balloon_stats.driver_pages)); | 459 | BALLOON_SHOW(driver_kb, "%lu\n", PAGES2KB(balloon_stats.driver_pages)); |
| 480 | 460 | ||
| 481 | 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, |
| @@ -545,7 +525,6 @@ static struct attribute *balloon_info_attrs[] = { | |||
| 545 | &attr_current_kb.attr, | 525 | &attr_current_kb.attr, |
| 546 | &attr_low_kb.attr, | 526 | &attr_low_kb.attr, |
| 547 | &attr_high_kb.attr, | 527 | &attr_high_kb.attr, |
| 548 | &attr_hard_limit_kb.attr, | ||
| 549 | &attr_driver_kb.attr, | 528 | &attr_driver_kb.attr, |
| 550 | NULL | 529 | NULL |
| 551 | }; | 530 | }; |
