aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/xen/balloon.c31
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
186static unsigned long current_target(void) 184static 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
274static int decrease_reservation(unsigned long nr_pages) 259static int decrease_reservation(unsigned long nr_pages)
@@ -369,7 +354,6 @@ static void balloon_process(struct work_struct *work)
369static void balloon_set_new_target(unsigned long target) 354static 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);
473BALLOON_SHOW(current_kb, "%lu\n", PAGES2KB(balloon_stats.current_pages)); 456BALLOON_SHOW(current_kb, "%lu\n", PAGES2KB(balloon_stats.current_pages));
474BALLOON_SHOW(low_kb, "%lu\n", PAGES2KB(balloon_stats.balloon_low)); 457BALLOON_SHOW(low_kb, "%lu\n", PAGES2KB(balloon_stats.balloon_low));
475BALLOON_SHOW(high_kb, "%lu\n", PAGES2KB(balloon_stats.balloon_high)); 458BALLOON_SHOW(high_kb, "%lu\n", PAGES2KB(balloon_stats.balloon_high));
476BALLOON_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);
479BALLOON_SHOW(driver_kb, "%lu\n", PAGES2KB(balloon_stats.driver_pages)); 459BALLOON_SHOW(driver_kb, "%lu\n", PAGES2KB(balloon_stats.driver_pages));
480 460
481static ssize_t show_target_kb(struct sys_device *dev, struct sysdev_attribute *attr, 461static 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};