aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen/balloon.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/xen/balloon.c')
-rw-r--r--drivers/xen/balloon.c38
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
182static unsigned long current_target(void) 184static 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
271static int decrease_reservation(unsigned long nr_pages) 259static 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)
367static void balloon_set_new_target(unsigned long target) 354static 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);
472BALLOON_SHOW(current_kb, "%lu\n", PAGES2KB(balloon_stats.current_pages)); 456BALLOON_SHOW(current_kb, "%lu\n", PAGES2KB(balloon_stats.current_pages));
473BALLOON_SHOW(low_kb, "%lu\n", PAGES2KB(balloon_stats.balloon_low)); 457BALLOON_SHOW(low_kb, "%lu\n", PAGES2KB(balloon_stats.balloon_low));
474BALLOON_SHOW(high_kb, "%lu\n", PAGES2KB(balloon_stats.balloon_high)); 458BALLOON_SHOW(high_kb, "%lu\n", PAGES2KB(balloon_stats.balloon_high));
475BALLOON_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);
478BALLOON_SHOW(driver_kb, "%lu\n", PAGES2KB(balloon_stats.driver_pages)); 459BALLOON_SHOW(driver_kb, "%lu\n", PAGES2KB(balloon_stats.driver_pages));
479 460
480static 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,
@@ -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};