balloon.c (55b3da98a40dbb3776f7454daf0d95dde25c33d2) balloon.c (de5a77d8422fc7ed0b2f4349bceb65a1a639e5b2)
1/******************************************************************************
2 * Xen balloon driver - enables returning/claiming memory to/from Xen.
3 *
4 * Copyright (c) 2003, B Dragovic
5 * Copyright (c) 2003-2004, M Williamson, K Fraser
6 * Copyright (c) 2005 Dan M. Smith, IBM Corporation
7 * Copyright (c) 2010 Daniel Kiper
8 *

--- 180 unchanged lines hidden (view full) ---

189
190 if (balloon_stats.schedule_delay > balloon_stats.max_schedule_delay)
191 balloon_stats.schedule_delay = balloon_stats.max_schedule_delay;
192
193 return BP_EAGAIN;
194}
195
196#ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG
1/******************************************************************************
2 * Xen balloon driver - enables returning/claiming memory to/from Xen.
3 *
4 * Copyright (c) 2003, B Dragovic
5 * Copyright (c) 2003-2004, M Williamson, K Fraser
6 * Copyright (c) 2005 Dan M. Smith, IBM Corporation
7 * Copyright (c) 2010 Daniel Kiper
8 *

--- 180 unchanged lines hidden (view full) ---

189
190 if (balloon_stats.schedule_delay > balloon_stats.max_schedule_delay)
191 balloon_stats.schedule_delay = balloon_stats.max_schedule_delay;
192
193 return BP_EAGAIN;
194}
195
196#ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG
197static long current_credit(void)
198{
199 return balloon_stats.target_pages - balloon_stats.current_pages -
200 balloon_stats.hotplug_pages;
201}
202
203static bool balloon_is_inflated(void)
204{
205 if (balloon_stats.balloon_low || balloon_stats.balloon_high ||
206 balloon_stats.balloon_hotplug)
207 return true;
208 else
209 return false;
210}
211
212static struct resource *additional_memory_resource(phys_addr_t size)
213{
214 struct resource *res;
215 int ret;
216
217 res = kzalloc(sizeof(*res), GFP_KERNEL);
218 if (!res)
219 return NULL;

--- 64 unchanged lines hidden (view full) ---

284#endif
285
286 rc = add_memory_resource(nid, resource);
287 if (rc) {
288 pr_warn("Cannot add additional memory (%i)\n", rc);
289 goto err;
290 }
291
197static struct resource *additional_memory_resource(phys_addr_t size)
198{
199 struct resource *res;
200 int ret;
201
202 res = kzalloc(sizeof(*res), GFP_KERNEL);
203 if (!res)
204 return NULL;

--- 64 unchanged lines hidden (view full) ---

269#endif
270
271 rc = add_memory_resource(nid, resource);
272 if (rc) {
273 pr_warn("Cannot add additional memory (%i)\n", rc);
274 goto err;
275 }
276
292 balloon_hotplug -= credit;
277 balloon_stats.total_pages += balloon_hotplug;
293
278
294 balloon_stats.hotplug_pages += credit;
295 balloon_stats.balloon_hotplug = balloon_hotplug;
296
297 return BP_DONE;
298 err:
299 release_memory_resource(resource);
300 return BP_ECANCELED;
301}
302
303static void xen_online_page(struct page *page)
304{
305 __online_page_set_limits(page);
306
307 mutex_lock(&balloon_mutex);
308
309 __balloon_append(page);
310
279 return BP_DONE;
280 err:
281 release_memory_resource(resource);
282 return BP_ECANCELED;
283}
284
285static void xen_online_page(struct page *page)
286{
287 __online_page_set_limits(page);
288
289 mutex_lock(&balloon_mutex);
290
291 __balloon_append(page);
292
311 if (balloon_stats.hotplug_pages)
312 --balloon_stats.hotplug_pages;
313 else
314 --balloon_stats.balloon_hotplug;
315
316 mutex_unlock(&balloon_mutex);
317}
318
319static int xen_memory_notifier(struct notifier_block *nb, unsigned long val, void *v)
320{
321 if (val == MEM_ONLINE)
322 schedule_delayed_work(&balloon_worker, 0);
323
324 return NOTIFY_OK;
325}
326
327static struct notifier_block xen_memory_nb = {
328 .notifier_call = xen_memory_notifier,
329 .priority = 0
330};
331#else
293 mutex_unlock(&balloon_mutex);
294}
295
296static int xen_memory_notifier(struct notifier_block *nb, unsigned long val, void *v)
297{
298 if (val == MEM_ONLINE)
299 schedule_delayed_work(&balloon_worker, 0);
300
301 return NOTIFY_OK;
302}
303
304static struct notifier_block xen_memory_nb = {
305 .notifier_call = xen_memory_notifier,
306 .priority = 0
307};
308#else
332static long current_credit(void)
309static enum bp_state reserve_additional_memory(long credit)
333{
310{
334 unsigned long target = balloon_stats.target_pages;
335
336 target = min(target,
337 balloon_stats.current_pages +
338 balloon_stats.balloon_low +
339 balloon_stats.balloon_high);
340
341 return target - balloon_stats.current_pages;
311 balloon_stats.target_pages = balloon_stats.current_pages;
312 return BP_DONE;
342}
313}
314#endif /* CONFIG_XEN_BALLOON_MEMORY_HOTPLUG */
343
315
344static bool balloon_is_inflated(void)
316static long current_credit(void)
345{
317{
346 if (balloon_stats.balloon_low || balloon_stats.balloon_high)
347 return true;
348 else
349 return false;
318 return balloon_stats.target_pages - balloon_stats.current_pages;
350}
351
319}
320
352static enum bp_state reserve_additional_memory(long credit)
321static bool balloon_is_inflated(void)
353{
322{
354 balloon_stats.target_pages = balloon_stats.current_pages;
355 return BP_DONE;
323 return balloon_stats.balloon_low || balloon_stats.balloon_high;
356}
324}
357#endif /* CONFIG_XEN_BALLOON_MEMORY_HOTPLUG */
358
359static enum bp_state increase_reservation(unsigned long nr_pages)
360{
361 int rc;
362 unsigned long pfn, i;
363 struct page *page;
364 struct xen_memory_reservation reservation = {
365 .address_bits = 0,
366 .extent_order = 0,
367 .domid = DOMID_SELF
368 };
369
325
326static enum bp_state increase_reservation(unsigned long nr_pages)
327{
328 int rc;
329 unsigned long pfn, i;
330 struct page *page;
331 struct xen_memory_reservation reservation = {
332 .address_bits = 0,
333 .extent_order = 0,
334 .domid = DOMID_SELF
335 };
336
370#ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG
371 if (!balloon_stats.balloon_low && !balloon_stats.balloon_high) {
372 nr_pages = min(nr_pages, balloon_stats.balloon_hotplug);
373 balloon_stats.hotplug_pages += nr_pages;
374 balloon_stats.balloon_hotplug -= nr_pages;
375 return BP_DONE;
376 }
377#endif
378
379 if (nr_pages > ARRAY_SIZE(frame_list))
380 nr_pages = ARRAY_SIZE(frame_list);
381
382 page = list_first_entry_or_null(&ballooned_pages, struct page, lru);
383 for (i = 0; i < nr_pages; i++) {
384 if (!page) {
385 nr_pages = i;
386 break;

--- 46 unchanged lines hidden (view full) ---

433 struct page *page;
434 int ret;
435 struct xen_memory_reservation reservation = {
436 .address_bits = 0,
437 .extent_order = 0,
438 .domid = DOMID_SELF
439 };
440
337 if (nr_pages > ARRAY_SIZE(frame_list))
338 nr_pages = ARRAY_SIZE(frame_list);
339
340 page = list_first_entry_or_null(&ballooned_pages, struct page, lru);
341 for (i = 0; i < nr_pages; i++) {
342 if (!page) {
343 nr_pages = i;
344 break;

--- 46 unchanged lines hidden (view full) ---

391 struct page *page;
392 int ret;
393 struct xen_memory_reservation reservation = {
394 .address_bits = 0,
395 .extent_order = 0,
396 .domid = DOMID_SELF
397 };
398
441#ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG
442 if (balloon_stats.hotplug_pages) {
443 nr_pages = min(nr_pages, balloon_stats.hotplug_pages);
444 balloon_stats.hotplug_pages -= nr_pages;
445 balloon_stats.balloon_hotplug += nr_pages;
446 return BP_DONE;
447 }
448#endif
449
450 if (nr_pages > ARRAY_SIZE(frame_list))
451 nr_pages = ARRAY_SIZE(frame_list);
452
453 for (i = 0; i < nr_pages; i++) {
454 page = alloc_page(gfp);
455 if (page == NULL) {
456 nr_pages = i;
457 state = BP_EAGAIN;

--- 172 unchanged lines hidden (view full) ---

630
631 for (pfn = start_pfn; pfn < extra_pfn_end; pfn++) {
632 page = pfn_to_page(pfn);
633 /* totalram_pages and totalhigh_pages do not
634 include the boot-time balloon extension, so
635 don't subtract from it. */
636 __balloon_append(page);
637 }
399 if (nr_pages > ARRAY_SIZE(frame_list))
400 nr_pages = ARRAY_SIZE(frame_list);
401
402 for (i = 0; i < nr_pages; i++) {
403 page = alloc_page(gfp);
404 if (page == NULL) {
405 nr_pages = i;
406 state = BP_EAGAIN;

--- 172 unchanged lines hidden (view full) ---

579
580 for (pfn = start_pfn; pfn < extra_pfn_end; pfn++) {
581 page = pfn_to_page(pfn);
582 /* totalram_pages and totalhigh_pages do not
583 include the boot-time balloon extension, so
584 don't subtract from it. */
585 __balloon_append(page);
586 }
587
588 balloon_stats.total_pages += extra_pfn_end - start_pfn;
638}
639
640static int __init balloon_init(void)
641{
642 int i;
643
644 if (!xen_domain())
645 return -ENODEV;
646
647 pr_info("Initialising balloon driver\n");
648
649 balloon_stats.current_pages = xen_pv_domain()
650 ? min(xen_start_info->nr_pages - xen_released_pages, max_pfn)
651 : get_num_physpages();
652 balloon_stats.target_pages = balloon_stats.current_pages;
653 balloon_stats.balloon_low = 0;
654 balloon_stats.balloon_high = 0;
589}
590
591static int __init balloon_init(void)
592{
593 int i;
594
595 if (!xen_domain())
596 return -ENODEV;
597
598 pr_info("Initialising balloon driver\n");
599
600 balloon_stats.current_pages = xen_pv_domain()
601 ? min(xen_start_info->nr_pages - xen_released_pages, max_pfn)
602 : get_num_physpages();
603 balloon_stats.target_pages = balloon_stats.current_pages;
604 balloon_stats.balloon_low = 0;
605 balloon_stats.balloon_high = 0;
606 balloon_stats.total_pages = balloon_stats.current_pages;
655
656 balloon_stats.schedule_delay = 1;
657 balloon_stats.max_schedule_delay = 32;
658 balloon_stats.retry_count = 1;
659 balloon_stats.max_retry_count = RETRY_UNLIMITED;
660
661#ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG
607
608 balloon_stats.schedule_delay = 1;
609 balloon_stats.max_schedule_delay = 32;
610 balloon_stats.retry_count = 1;
611 balloon_stats.max_retry_count = RETRY_UNLIMITED;
612
613#ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG
662 balloon_stats.hotplug_pages = 0;
663 balloon_stats.balloon_hotplug = 0;
664
665 set_online_page_callback(&xen_online_page);
666 register_memory_notifier(&xen_memory_nb);
667#endif
668
669 /*
670 * Initialize the balloon with pages from the extra memory
671 * regions (see arch/x86/xen/setup.c).
672 */
673 for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++)
674 if (xen_extra_mem[i].n_pfns)
675 balloon_add_region(xen_extra_mem[i].start_pfn,
676 xen_extra_mem[i].n_pfns);
677
678 return 0;
679}
680
681subsys_initcall(balloon_init);
682
683MODULE_LICENSE("GPL");
614 set_online_page_callback(&xen_online_page);
615 register_memory_notifier(&xen_memory_nb);
616#endif
617
618 /*
619 * Initialize the balloon with pages from the extra memory
620 * regions (see arch/x86/xen/setup.c).
621 */
622 for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++)
623 if (xen_extra_mem[i].n_pfns)
624 balloon_add_region(xen_extra_mem[i].start_pfn,
625 xen_extra_mem[i].n_pfns);
626
627 return 0;
628}
629
630subsys_initcall(balloon_init);
631
632MODULE_LICENSE("GPL");