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"); |