506
506
*----------------------------------------------------------------------
510
* Attempt to find a "chunk" with a free slot to store locked page.
511
* Try to allocate new chunk if all existing chunks are full.
514
* Returns NULL on failure.
519
*----------------------------------------------------------------------
522
static BalloonChunk *
523
BalloonGetChunk(Balloon *b) // IN
527
/* Get first chunk from the list */
528
if (DblLnkLst_IsLinked(&b->chunks)) {
529
chunk = DblLnkLst_Container(b->chunks.next, BalloonChunk, node);
530
if (chunk->pageCount < BALLOON_CHUNK_PAGES) {
531
/* This chunk has free slots, use it */
536
/* create new chunk */
537
chunk = BalloonChunk_Create();
539
DblLnkLst_LinkFirst(&b->chunks, &chunk->node);
549
*----------------------------------------------------------------------
551
* BalloonPageStore --
553
* Add "page" to the given "chunk".
561
*----------------------------------------------------------------------
565
BalloonPageStore(BalloonChunk *chunk, PageHandle page)
567
chunk->page[chunk->pageCount++] = page;
572
*----------------------------------------------------------------------
508
574
* BalloonPageAlloc --
510
576
* Attempts to allocate a physical page, inflating balloon "b".
523
589
BalloonPageAlloc(Balloon *b, // IN
524
590
BalloonPageAllocType allocType) // IN
526
593
BalloonChunk *chunk = NULL;
532
597
/* allocate page, fail if unable */
533
STATS_INC(b->stats.primAlloc[allocType]);
536
* Attempts to allocate and reserve a physical page.
538
* If canSleep == 1, i.e., BALLOON_PAGE_ALLOC_CANSLEEP:
539
* The allocation can wait (sleep) for page writeout (swap) by the guest.
540
* otherwise canSleep == 0, i.e., BALLOON_PAGE_ALLOC_NOSLEEP:
541
* If allocation of a page requires disk writeout, then just fail. DON'T sleep.
543
* Returns the physical address of the allocated page, or 0 if error.
545
page = OS_ReservedPageAlloc(allocType);
547
if (page == PAGE_HANDLE_INVALID) {
548
STATS_INC(b->stats.primAllocFail[allocType]);
549
return BALLOON_PAGE_ALLOC_FAILURE;
552
/* Find chunk with free space, create it if necessary. */
553
if (DblLnkLst_IsLinked(&b->chunks)) {
554
/* Get first chunk from the list */
555
chunk = DblLnkLst_Container(b->chunks.next, BalloonChunk, node);
556
if (chunk->pageCount >= BALLOON_CHUNK_PAGES) {
557
/* This chunk is full. */
563
/* create new chunk */
564
chunk = BalloonChunk_Create();
566
/* reclaim storage, fail */
567
OS_ReservedPageFree(page);
599
STATS_INC(b->stats.primAlloc[allocType]);
602
* Attempts to allocate and reserve a physical page.
604
* If canSleep == 1, i.e., BALLOON_PAGE_ALLOC_CANSLEEP:
605
* The allocation can wait (sleep) for page writeout (swap) by the guest.
606
* otherwise canSleep == 0, i.e., BALLOON_PAGE_ALLOC_NOSLEEP:
607
* If allocation of a page requires disk writeout, then just fail. DON'T sleep.
609
* Returns the physical address of the allocated page, or 0 if error.
611
page = OS_ReservedPageAlloc(allocType);
612
if (page == PAGE_HANDLE_INVALID) {
613
STATS_INC(b->stats.primAllocFail[allocType]);
568
614
return BALLOON_PAGE_ALLOC_FAILURE;
571
DblLnkLst_LinkFirst(&b->chunks, &chunk->node);
577
/* inform monitor via backdoor */
578
status = BalloonMonitorLockPage(b, page);
579
if (status != BALLOON_SUCCESS) {
580
/* place on list of non-balloonable pages, retry allocation */
581
if ((status != BALLOON_ERROR_RESET) &&
582
(BalloonErrorPagesAlloc(b, page) == BALLOON_SUCCESS)) {
586
/* reclaim storage, fail */
587
OS_ReservedPageFree(page);
617
/* Get the chunk to store allocated page. */
619
chunk = BalloonGetChunk(b);
621
OS_ReservedPageFree(page);
622
return BALLOON_PAGE_ALLOC_FAILURE;
626
/* inform monitor via backdoor */
627
status = BalloonMonitorLockPage(b, page);
628
locked = status == BALLOON_SUCCESS;
630
if (status == BALLOON_ERROR_RESET ||
631
status == BALLOON_ERROR_PPN_NOTNEEDED) {
632
OS_ReservedPageFree(page);
636
/* place on list of non-balloonable pages, retry allocation */
637
status = BalloonErrorPageStore(b, page);
638
if (status != BALLOON_SUCCESS) {
639
OS_ReservedPageFree(page);
591
645
/* track allocated page */
592
chunk->page[chunk->pageCount++] = page;
646
BalloonPageStore(chunk, page);
594
648
/* update balloon size */
597
return BALLOON_SUCCESS;
683
737
*----------------------------------------------------------------------
685
* BalloonDecreaseRateAlloc --
687
* Wrapper to quickly reduce the page allocation rate. This function
688
* is called only when a CANSLEEP allocation fails. This implies severe
689
* memory pressure inside the guest, so quickly decrease the rateAlloc.
697
*----------------------------------------------------------------------
701
BalloonDecreaseRateAlloc(Balloon *b) // IN
703
if (BALLOON_RATE_ADAPT) {
704
b->rateAlloc = MAX(b->rateAlloc / 2, BALLOON_RATE_ALLOC_MIN);
710
*----------------------------------------------------------------------
712
* BalloonIncreaseRateAlloc --
714
* Wrapper to increase the page allocation rate.
716
* This function is called when the balloon target is met or
717
* b->rateAlloc (or more) pages have been successfully allocated.
718
* This implies that the guest may not be under high memory
719
* pressure. So let us increase the rateAlloc.
721
* If meeting balloon target requires less than b->rateAlloc
722
* pages, then we do not change the page allocation rate.
724
* If the number of pages successfully allocated (nAlloc) is far
725
* higher than b->rateAlloc, then it implies that NOSLEEP
726
* allocations are highly successful. Therefore, we predict that
727
* the guest is under no memory pressure, and so increase
728
* b->rateAlloc quickly.
736
*----------------------------------------------------------------------
740
BalloonIncreaseRateAlloc(Balloon *b, // IN
743
if (BALLOON_RATE_ADAPT) {
744
if (nAlloc >= b->rateAlloc) {
745
uint32 mult = nAlloc / b->rateAlloc;
746
b->rateAlloc = MIN(b->rateAlloc + mult * BALLOON_RATE_ALLOC_INC,
747
BALLOON_RATE_ALLOC_MAX);
754
*----------------------------------------------------------------------
756
739
* BalloonInflate--
758
741
* Attempts to allocate physical pages to inflate balloon.
787
774
* predicted that the guest is under memory pressure, then we
788
775
* slowdown page allocations considerably.
790
if (b->slowPageAllocationCycles > 0) {
791
nAllocNoSleep = MIN(target - b->nPages, b->rateAlloc);
793
nAllocNoSleep = MIN(target - b->nPages, BALLOON_NOSLEEP_ALLOC_MAX);
796
for (i = 0; i < nAllocNoSleep; i++) {
797
/* Try NOSLEEP allocation */
798
status = BalloonPageAlloc(b, BALLOON_PAGE_ALLOC_NOSLEEP);
778
goal = target - b->nPages;
780
* Start with no sleep allocation rate which may be higher
781
* than sleeping allocation rate.
783
rate = b->slowPageAllocationCycles ?
784
b->rateAlloc : BALLOON_NOSLEEP_ALLOC_MAX;
786
for (i = 0; i < goal; i++) {
788
status = BalloonPageAlloc(b, allocType);
799
789
if (status != BALLOON_SUCCESS) {
800
790
if (status != BALLOON_PAGE_ALLOC_FAILURE) {
802
* Not a page allocation failure, so release non-balloonable
805
BalloonErrorPagesFree(b);
792
* Not a page allocation failure, stop this cycle.
793
* Maybe we'll get new target from the host soon.
798
if (allocType == BALLOON_PAGE_ALLOC_CANSLEEP) {
800
* CANSLEEP page allocation failed, so guest is under severe
801
* memory pressure. Quickly decrease allocation rate.
803
b->rateAlloc = MAX(b->rateAlloc / 2, BALLOON_RATE_ALLOC_MIN);
809
808
* NOSLEEP page allocation failed, so the guest is under memory
810
* pressure. Let us slowdown page allocations for next few
811
* cycles so that the guest gets out of memory pressure.
809
* pressure. Let us slow down page allocations for next few cycles
810
* so that the guest gets out of memory pressure. Also, if we
811
* already allocated b->rateAlloc pages, let's pause, otherwise
812
* switch to sleeping allocations.
813
814
b->slowPageAllocationCycles = SLOW_PAGE_ALLOCATION_CYCLES;
816
if (i >= b->rateAlloc)
819
allocType = BALLOON_PAGE_ALLOC_CANSLEEP;
820
/* Lower rate for sleeping allocations. */
824
if (++allocations > BALLOON_ALLOC_YIELD_THRESHOLD) {
830
/* We allocated enough pages, let's take a break. */
817
if (++allocations > BALLOON_ALLOC_YIELD_THRESHOLD) {
824
* Check whether nosleep allocation successfully zapped nAllocNoSleep
827
if (i == nAllocNoSleep) {
828
BalloonIncreaseRateAlloc(b, nAllocNoSleep);
829
/* release non-balloonable pages, succeed */
830
BalloonErrorPagesFree(b);
831
return BALLOON_SUCCESS;
834
* NOSLEEP allocation failed, so the guest is under memory pressure.
835
* If already b->rateAlloc pages were zapped, then succeed. Otherwise,
836
* try CANSLEEP allocation.
838
if (i > b->rateAlloc) {
839
BalloonIncreaseRateAlloc(b, i);
840
/* release non-balloonable pages, succeed */
841
BalloonErrorPagesFree(b);
842
return BALLOON_SUCCESS;
844
/* update successful NOSLEEP allocations, and proceed */
850
* Use CANSLEEP page allocation to inflate balloon if below target.
852
* Sleep allocations are required only when nosleep allocation fails.
853
* This implies that the guest is already under memory pressure, so
854
* let us always throttle canSleep allocations. The total number pages
855
* allocated using noSleep and canSleep methods is throttled at
856
* b->rateAlloc per second when the guest is under memory pressure.
858
nAllocCanSleep = target - b->nPages;
859
nAllocCanSleep = MIN(nAllocCanSleep, b->rateAlloc - nAllocNoSleep);
861
for (i = 0; i < nAllocCanSleep; i++) {
862
/* Try CANSLEEP allocation */
863
status = BalloonPageAlloc(b, BALLOON_PAGE_ALLOC_CANSLEEP);
864
if(status != BALLOON_SUCCESS) {
865
if (status == BALLOON_PAGE_ALLOC_FAILURE) {
867
* CANSLEEP page allocation failed, so guest is under severe
868
* memory pressure. Quickly decrease rateAlloc.
870
BalloonDecreaseRateAlloc(b);
872
/* release non-balloonable pages, fail */
873
BalloonErrorPagesFree(b);
877
if (++allocations > BALLOON_ALLOC_YIELD_THRESHOLD) {
884
* Either met the balloon target or b->rateAlloc pages have been
885
* successfully zapped.
887
BalloonIncreaseRateAlloc(b, nAllocNoSleep + nAllocCanSleep);
836
* We reached our goal without failures so try increasing
839
if (status == BALLOON_SUCCESS && i >= b->rateAlloc) {
840
unsigned int mult = i / b->rateAlloc;
842
b->rateAlloc = MIN(b->rateAlloc + mult * BALLOON_RATE_ALLOC_INC,
843
BALLOON_RATE_ALLOC_MAX);
889
846
/* release non-balloonable pages, succeed */
890
847
BalloonErrorPagesFree(b);