1
/*********************************************************
2
* Copyright (C) 2000 VMware, Inc. All rights reserved.
4
* The contents of this file are subject to the terms of the Common
5
* Development and Distribution License (the "License") version 1.0
6
* and no later version. You may not use this file except in
7
* compliance with the License.
9
* You can obtain a copy of the License at
10
* http://www.opensource.org/licenses/cddl1.php
12
* See the License for the specific language governing permissions
13
* and limitations under the License.
15
*********************************************************/
20
* VMware server physical memory management driver for Unix-ish
21
* (Linux, FreeBSD, Solaris) guests. The driver acts like a
22
* "balloon" that can be inflated to reclaim physical pages by
23
* reserving them in the guest and invalidating them in the
24
* monitor, freeing up the underlying machine pages so they can
25
* be allocated to other guests. The balloon can also be
26
* deflated to allow the guest to use more physical memory.
27
* Higher level policies can control the sizes of balloons in VMs
28
* in order to manage physical memory resources.
36
* Compile-Time Options
39
#define BALLOON_RATE_ADAPT (1)
41
#define BALLOON_DEBUG (1)
42
#define BALLOON_DEBUG_VERBOSE (0)
45
#define BALLOON_STATS_PROCFS
51
#include "balloon_def.h"
54
#include "backdoor_balloon.h"
56
#include "vmballoon.h"
66
#define BALLOON_NAME "vmmemctl"
67
#define BALLOON_NAME_VERBOSE "VMware memory control driver"
69
#define BALLOON_PROTOCOL_VERSION (2)
71
#define BALLOON_CHUNK_PAGES (1000)
73
#define BALLOON_NOSLEEP_ALLOC_MAX (16384)
75
#define BALLOON_RATE_ALLOC_MIN (512)
76
#define BALLOON_RATE_ALLOC_MAX (2048)
77
#define BALLOON_RATE_ALLOC_INC (16)
79
#define BALLOON_RATE_FREE_MIN (512)
80
#define BALLOON_RATE_FREE_MAX (16384)
81
#define BALLOON_RATE_FREE_INC (16)
83
#define BALLOON_ERROR_PAGES (16)
86
* When guest is under memory pressure, use a reduced page allocation
87
* rate for next several cycles.
89
#define SLOW_PAGE_ALLOCATION_CYCLES (4)
92
* Move it to bora/public/balloon_def.h later, if needed. Note that
93
* BALLOON_PAGE_ALLOC_FAILURE is an internal error code used for
94
* distinguishing page allocation failures from monitor-backdoor errors.
95
* We use value 1000 because all monitor-backdoor error codes are < 1000.
97
#define BALLOON_PAGE_ALLOC_FAILURE (1000)
99
// Maximum number of page allocations without yielding processor
100
#define BALLOON_ALLOC_YIELD_THRESHOLD (1024)
107
typedef struct BalloonChunk {
108
unsigned long page[BALLOON_CHUNK_PAGES];
110
struct BalloonChunk *prev, *next;
114
unsigned long page[BALLOON_ERROR_PAGES];
119
/* sets of reserved physical pages */
120
BalloonChunk *chunks;
123
/* transient list of non-balloonable pages */
124
BalloonErrorPages errors;
133
/* adjustment rates (pages per second) */
137
/* slowdown page allocations for next few cycles */
138
int slowPageAllocationCycles;
148
static Balloon globalBalloon;
151
* Forward Declarations
154
static int BalloonGuestType(void);
156
static unsigned long BalloonPrimAllocPage(BalloonPageAllocType canSleep);
157
static void BalloonPrimFreePage(unsigned long page);
159
static int Balloon_AllocPage(Balloon *b, BalloonPageAllocType allocType);
160
static int Balloon_FreePage(Balloon *b, int monitorUnlock);
161
static int Balloon_AdjustSize(Balloon *b, uint32 target);
162
static void Balloon_Reset(Balloon *b);
164
static void Balloon_StartTimer(Balloon *b);
165
static void Balloon_StopTimer(Balloon *b);
166
static void CDECL Balloon_BH(void *data);
168
static int Balloon_MonitorStart(Balloon *b);
169
static int Balloon_MonitorGuestType(Balloon *b);
170
static int Balloon_MonitorGetTarget(Balloon *b, uint32 *nPages);
171
static int Balloon_MonitorLockPage(Balloon *b, unsigned long addr);
172
static int Balloon_MonitorUnlockPage(Balloon *b, unsigned long addr);
179
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
182
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
186
#define STATS_INC(stat) (stat)++
188
#define STATS_INC(stat)
192
* Macros to generate operations for simple lists of OBJ.
193
* OBJ must contain next and prev fields.
197
#define GENERATE_LIST_INSERT(OBJ) \
198
static void OBJ ## _Insert(OBJ **head, OBJ *obj) \
202
/* add element to head of list */ \
211
#define GENERATE_LIST_REMOVE(OBJ) \
212
static void OBJ ## _Remove(OBJ **head, OBJ *obj) \
214
/* splice element out of list */ \
215
if (obj->prev != NULL) { \
216
obj->prev->next = obj->next; \
220
if (obj->next != NULL) { \
221
obj->next->prev = obj->prev; \
229
GENERATE_LIST_INSERT(BalloonChunk);
230
GENERATE_LIST_REMOVE(BalloonChunk);
237
*----------------------------------------------------------------------
241
* Ballon driver status reporting routine. Note that this is only
245
* Writes ASCII status information into "buf".
246
* Returns number of bytes written.
251
*----------------------------------------------------------------------
254
BalloonProcRead(char *buf)
259
BalloonGetStats(&stats);
261
/* format size info */
262
len += os_sprintf(buf + len,
263
"target: %8d pages\n"
264
"current: %8d pages\n",
268
/* format rate info */
269
len += os_sprintf(buf + len,
270
"rateNoSleepAlloc: %8d pages/sec\n"
271
"rateSleepAlloc: %8d pages/sec\n"
272
"rateFree: %8d pages/sec\n",
273
BALLOON_NOSLEEP_ALLOC_MAX,
277
#ifdef BALLOON_STATS_PROCFS
278
len += os_sprintf(buf + len,
281
"start: %8u (%4u failed)\n"
282
"guestType: %8u (%4u failed)\n"
283
"lock: %8u (%4u failed)\n"
284
"unlock: %8u (%4u failed)\n"
285
"target: %8u (%4u failed)\n"
286
"primNoSleepAlloc: %8u (%4u failed)\n"
287
"primCanSleepAlloc: %8u (%4u failed)\n"
292
stats.start, stats.startFail,
293
stats.guestType, stats.guestTypeFail,
294
stats.lock, stats.lockFail,
295
stats.unlock, stats.unlockFail,
296
stats.target, stats.targetFail,
297
stats.primAlloc[BALLOON_PAGE_ALLOC_NOSLEEP],
298
stats.primAllocFail[BALLOON_PAGE_ALLOC_NOSLEEP],
299
stats.primAlloc[BALLOON_PAGE_ALLOC_CANSLEEP],
300
stats.primAllocFail[BALLOON_PAGE_ALLOC_CANSLEEP],
302
stats.primErrorPageAlloc,
303
stats.primErrorPageFree);
314
*----------------------------------------------------------------------
318
* Return the physical page number corresponding to the specified
319
* Linux kernel-mapped address.
322
* Returns PPN for "addr".
327
*----------------------------------------------------------------------
329
static inline unsigned long
330
AddrToPPN(unsigned long addr)
332
return(os_addr_to_ppn(addr));
336
*----------------------------------------------------------------------
338
* BalloonPrimAllocPage --
340
* Attempts to allocate and reserve a physical page.
342
* If canSleep == 1, i.e., BALLOON_PAGE_ALLOC_CANSLEEP:
343
* The allocation can wait (sleep) for page writeout (swap)
345
* otherwise canSleep == 0, i.e., BALLOON_PAGE_ALLOC_NOSLEEP:
346
* If allocation of a page requires disk writeout, then
347
* just fail. DON'T sleep.
350
* Returns the physical address of the allocated page, or 0 if error.
355
*----------------------------------------------------------------------
358
BalloonPrimAllocPage(BalloonPageAllocType canSleep)
360
return(os_alloc_reserved_page(canSleep));
364
*----------------------------------------------------------------------
366
* BalloonPrimFreePage --
368
* Unreserves and deallocates specified physical page.
376
*----------------------------------------------------------------------
379
BalloonPrimFreePage(unsigned long page)
381
return(os_free_reserved_page(page));
385
*----------------------------------------------------------------------
387
* BalloonGuestType --
389
* Return balloon guest OS identifier obtained by parsing
390
* system-dependent identity string.
393
* Returns one of BALLOON_GUEST_{LINUX,BSD,SOLARIS,UNKNOWN}.
398
*----------------------------------------------------------------------
401
BalloonGuestType(void)
405
/* obtain OS identify string */
406
identity = os_identity();
408
/* unknown if not specified */
409
if (identity == NULL) {
410
return(BALLOON_GUEST_UNKNOWN);
413
/* classify based on first letter (avoid defining strcmp) */
414
switch (identity[0]) {
417
return(BALLOON_GUEST_LINUX);
420
return(BALLOON_GUEST_BSD);
423
return(BALLOON_GUEST_SOLARIS);
429
return(BALLOON_GUEST_UNKNOWN);
433
* Returns information about balloon state, including the current and
434
* target size, rates for allocating and freeing pages, and statistics
435
* about past activity.
437
void BalloonGetStats(BalloonStats *stats)
439
Balloon *b = &globalBalloon;
442
* Copy statistics out of global structure.
444
os_memcpy(stats, &b->stats, sizeof (BalloonStats));
447
* Fill in additional information about size and rates, which is
448
* normally kept in the Balloon structure itself.
450
stats->nPages = b->nPages;
451
stats->nPagesTarget = b->nPagesTarget;
452
stats->rateAlloc = b->rateAlloc;
453
stats->rateFree = b->rateFree;
457
* BalloonChunk Operations
461
*----------------------------------------------------------------------
463
* BalloonChunk_Create --
465
* Creates a new BalloonChunk object capable of tracking
466
* BALLOON_CHUNK_PAGES PPNs.
468
* We do not bother to define two versions (NOSLEEP and CANSLEEP)
469
* of os_kmalloc because Chunk_Create does not require a new page
473
* Returns initialized BalloonChunk, or NULL if error.
478
*----------------------------------------------------------------------
480
static BalloonChunk *
481
BalloonChunk_Create(void)
485
/* allocate memory, fail if unable */
486
if ((chunk = (BalloonChunk *) os_kmalloc_nosleep(sizeof(BalloonChunk))) == NULL) {
491
os_bzero(chunk, sizeof(BalloonChunk));
498
*----------------------------------------------------------------------
500
* BalloonChunk_Destroy --
502
* Reclaims all storage associated with specified BalloonChunk.
510
*----------------------------------------------------------------------
513
BalloonChunk_Destroy(BalloonChunk *chunk)
515
/* reclaim storage */
516
os_kfree(chunk, sizeof (BalloonChunk));
525
*----------------------------------------------------------------------
529
* Initializes device state for balloon "b".
532
* Returns BALLOON_SUCCESS.
537
*----------------------------------------------------------------------
540
Balloon_Init(Balloon *b)
543
os_bzero(b, sizeof(Balloon));
545
/* initialize rates */
546
b->rateAlloc = BALLOON_RATE_ALLOC_MAX;
547
b->rateFree = BALLOON_RATE_FREE_MAX;
549
/* initialize reset flag */
553
return(BALLOON_SUCCESS);
557
*----------------------------------------------------------------------
559
* Balloon_Deallocate --
561
* Frees all allocated pages.
569
*----------------------------------------------------------------------
572
Balloon_Deallocate(Balloon *b)
574
unsigned int cnt = 0;
576
/* free all pages, skipping monitor unlock */
577
while (b->nChunks > 0) {
578
(void) Balloon_FreePage(b, FALSE);
579
if (++cnt >= b->rateFree) {
587
*----------------------------------------------------------------------
591
* Resets balloon "b" to empty state. Frees all allocated pages
592
* and attempts to reset contact with the monitor.
598
* Schedules next execution of balloon timer handler.
600
*----------------------------------------------------------------------
603
Balloon_Reset(Balloon *b)
607
/* free all pages, skipping monitor unlock */
608
Balloon_Deallocate(b);
610
/* send start command */
611
status = Balloon_MonitorStart(b);
612
if (status == BALLOON_SUCCESS) {
616
/* report guest type */
617
(void) Balloon_MonitorGuestType(b);
622
*----------------------------------------------------------------------
626
* Balloon bottom half handler. Contacts monitor via backdoor
627
* to obtain balloon size target, and starts adjusting balloon
628
* size to achieve target by allocating or deallocating pages.
629
* Resets balloon if requested by the monitor.
635
* Schedules next execution of balloon timer handler.
637
*----------------------------------------------------------------------
640
Balloon_BH(void *data)
642
Balloon *b = (Balloon *) data;
647
STATS_INC(b->stats.timer);
649
/* reset, if specified */
654
/* contact monitor via backdoor */
655
status = Balloon_MonitorGetTarget(b, &target);
657
/* decrement slowPageAllocationCycles counter */
658
if (b->slowPageAllocationCycles > 0) {
659
b->slowPageAllocationCycles--;
662
if (status == BALLOON_SUCCESS) {
663
/* update target, adjust size */
664
b->nPagesTarget = target;
665
(void) Balloon_AdjustSize(b, target);
670
*----------------------------------------------------------------------
672
* Balloon_StartTimer --
674
* Schedules next execution of balloon timer handler.
682
*----------------------------------------------------------------------
685
Balloon_StartTimer(Balloon *b)
691
*----------------------------------------------------------------------
693
* Balloon_StopTimer --
695
* Deschedules balloon timer handler.
703
*----------------------------------------------------------------------
706
Balloon_StopTimer(Balloon *b)
713
*----------------------------------------------------------------------
715
* Balloon_ErrorPagesAlloc --
717
* Attempt to add "page" to list of non-balloonable pages
718
* associated with "b".
721
* Returns BALLOON_SUCCESS iff successful, or BALLOON_FAILURE
722
* if non-balloonable page list is already full.
727
*----------------------------------------------------------------------
730
Balloon_ErrorPagesAlloc(Balloon *b, unsigned long page)
732
/* fail if list already full */
733
if (b->errors.nextPage >= BALLOON_ERROR_PAGES) {
734
return(BALLOON_FAILURE);
737
/* add page to list */
738
b->errors.page[b->errors.nextPage] = page;
739
b->errors.nextPage++;
740
STATS_INC(b->stats.primErrorPageAlloc);
741
return(BALLOON_SUCCESS);
745
*----------------------------------------------------------------------
747
* Balloon_ErrorPagesFree --
749
* Deallocates all pages on the list of non-balloonable pages
750
* associated with "b".
758
*----------------------------------------------------------------------
761
Balloon_ErrorPagesFree(Balloon *b)
765
/* free all non-balloonable "error" pages */
766
for (i = 0; i < b->errors.nextPage; i++) {
767
BalloonPrimFreePage(b->errors.page[i]);
768
b->errors.page[i] = 0;
769
STATS_INC(b->stats.primErrorPageFree);
771
b->errors.nextPage = 0;
775
*----------------------------------------------------------------------
777
* Balloon_AllocPage --
779
* Attempts to allocate a physical page, inflating balloon "b".
780
* Informs monitor of PPN for allocated page via backdoor.
783
* Returns BALLOON_SUCCESS if successful, otherwise error code.
788
*----------------------------------------------------------------------
791
Balloon_AllocPage(Balloon *b, BalloonPageAllocType allocType)
799
/* allocate page, fail if unable */
800
STATS_INC(b->stats.primAlloc[allocType]);
802
page = BalloonPrimAllocPage(allocType);
805
STATS_INC(b->stats.primAllocFail[allocType]);
806
return(BALLOON_PAGE_ALLOC_FAILURE);
809
/* find chunk with space, create if necessary */
811
if ((chunk == NULL) || (chunk->nextPage >= BALLOON_CHUNK_PAGES)) {
812
/* create new chunk */
813
if ((chunk = BalloonChunk_Create()) == NULL) {
814
/* reclaim storage, fail */
815
BalloonPrimFreePage(page);
816
return(BALLOON_PAGE_ALLOC_FAILURE);
818
BalloonChunk_Insert(&b->chunks, chunk);
824
/* inform monitor via backdoor */
825
status = Balloon_MonitorLockPage(b, page);
826
if (status != BALLOON_SUCCESS) {
827
/* place on list of non-balloonable pages, retry allocation */
828
if ((status != BALLOON_ERROR_RESET) &&
829
(Balloon_ErrorPagesAlloc(b, page) == BALLOON_SUCCESS)) {
833
/* reclaim storage, fail */
834
BalloonPrimFreePage(page);
838
/* track allocated page */
839
chunk->page[chunk->nextPage] = page;
842
/* update balloon size */
846
return(BALLOON_SUCCESS);
850
*----------------------------------------------------------------------
852
* Balloon_FreePage --
854
* Attempts to deallocate a physical page, deflating balloon "b".
855
* Informs monitor of PPN for deallocated page via backdoor if
856
* "monitorUnlock" is specified.
859
* Returns BALLOON_SUCCESS if successful, otherwise error code.
864
*----------------------------------------------------------------------
867
Balloon_FreePage(Balloon *b, int monitorUnlock)
875
while ((chunk != NULL) && (chunk->nextPage == 0)) {
876
/* destroy empty chunk */
877
BalloonChunk_Remove(&b->chunks, chunk);
878
BalloonChunk_Destroy(chunk);
887
return(BALLOON_FAILURE);
890
/* select page to deallocate */
892
page = chunk->page[chunk->nextPage];
894
/* inform monitor via backdoor */
896
status = Balloon_MonitorUnlockPage(b, page);
897
if (status != BALLOON_SUCCESS) {
898
/* reset next pointer, fail */
904
/* deallocate page */
905
BalloonPrimFreePage(page);
906
STATS_INC(b->stats.primFree);
908
/* update balloon size */
911
/* reclaim chunk, if empty */
912
if (chunk->nextPage == 0) {
913
/* destroy empty chunk */
914
BalloonChunk_Remove(&b->chunks, chunk);
915
BalloonChunk_Destroy(chunk);
922
return(BALLOON_SUCCESS);
926
*----------------------------------------------------------------------
928
* BalloonDecreaseRateAlloc --
930
* Wrapper to quickly reduce the page allocation rate. This function
931
* is called only when a CANSLEEP allocation fails. This implies severe
932
* memory pressure inside the guest, so quickly decrease the rateAlloc.
940
*----------------------------------------------------------------------
943
BalloonDecreaseRateAlloc(Balloon *b)
945
if (BALLOON_RATE_ADAPT) {
946
b->rateAlloc = MAX(b->rateAlloc / 2, BALLOON_RATE_ALLOC_MIN);
951
*----------------------------------------------------------------------
953
* BalloonIncreaseRateAlloc --
955
* Wrapper to increase the page allocation rate.
957
* This function is called when the balloon target is met or
958
* b->rateAlloc (or more) pages have been successfully allocated.
959
* This implies that the guest may not be under high memory
960
* pressure. So let us increase the rateAlloc.
962
* If meeting balloon target requires less than b->rateAlloc
963
* pages, then we do not change the page allocation rate.
965
* If the number of pages successfully allocated (nAlloc) is far
966
* higher than b->rateAlloc, then it implies that NOSLEEP
967
* allocations are highly successful. Therefore, we predict that
968
* the guest is under no memory pressure, and so increase
969
* b->rateAlloc quickly.
977
*----------------------------------------------------------------------
980
BalloonIncreaseRateAlloc(Balloon *b, uint32 nAlloc)
982
if (BALLOON_RATE_ADAPT) {
983
if (nAlloc >= b->rateAlloc) {
984
uint32 mult = nAlloc / b->rateAlloc;
985
b->rateAlloc = MIN(b->rateAlloc + mult * BALLOON_RATE_ALLOC_INC,
986
BALLOON_RATE_ALLOC_MAX);
992
*----------------------------------------------------------------------
996
* Attempts to allocate physical pages to inflate balloon.
999
* Returns BALLOON_SUCCESS if successful, otherwise error code.
1004
*----------------------------------------------------------------------
1007
BalloonInflate(Balloon *b, uint32 target)
1009
int status, allocations = 0;
1010
uint32 i, nAllocNoSleep, nAllocCanSleep;
1013
* First try NOSLEEP page allocations to inflate balloon.
1015
* If we do not throttle nosleep allocations, we can drain all
1016
* free pages in the guest quickly (if the balloon target is high).
1017
* As a side-effect, draining free pages helps to inform (force)
1018
* the guest to start swapping if balloon target is not met yet,
1019
* which is a desired behavior. However, balloon driver can consume
1020
* all available CPU cycles if too many pages are allocated in a
1021
* second. Therefore, we throttle nosleep allocations even when
1022
* the guest is not under memory pressure. OTOH, if we have already
1023
* predicted that the guest is under memory pressure, then we
1024
* slowdown page allocations considerably.
1026
if (b->slowPageAllocationCycles > 0) {
1027
nAllocNoSleep = MIN(target - b->nPages, b->rateAlloc);
1029
nAllocNoSleep = MIN(target - b->nPages, BALLOON_NOSLEEP_ALLOC_MAX);
1032
for (i = 0; i < nAllocNoSleep; i++) {
1033
/* Try NOSLEEP allocation */
1034
status = Balloon_AllocPage(b, BALLOON_PAGE_ALLOC_NOSLEEP);
1035
if (status != BALLOON_SUCCESS) {
1036
if (status != BALLOON_PAGE_ALLOC_FAILURE) {
1038
* Not a page allocation failure, so release non-balloonable
1041
Balloon_ErrorPagesFree(b);
1045
* NOSLEEP page allocation failed, so the guest is under memory
1046
* pressure. Let us slowdown page allocations for next few
1047
* cycles so that the guest gets out of memory pressure.
1049
b->slowPageAllocationCycles = SLOW_PAGE_ALLOCATION_CYCLES;
1053
if (++allocations > BALLOON_ALLOC_YIELD_THRESHOLD) {
1060
* Check whether nosleep allocation successfully zapped nAllocNoSleep
1063
if (i == nAllocNoSleep) {
1064
BalloonIncreaseRateAlloc(b, nAllocNoSleep);
1065
/* release non-balloonable pages, succeed */
1066
Balloon_ErrorPagesFree(b);
1067
return(BALLOON_SUCCESS);
1070
* NOSLEEP allocation failed, so the guest is under memory pressure.
1071
* If already b->rateAlloc pages were zapped, then succeed. Otherwise,
1072
* try CANSLEEP allocation.
1074
if (i > b->rateAlloc) {
1075
BalloonIncreaseRateAlloc(b, i);
1076
/* release non-balloonable pages, succeed */
1077
Balloon_ErrorPagesFree(b);
1078
return(BALLOON_SUCCESS);
1080
/* update successful NOSLEEP allocations, and proceed */
1086
* Use CANSLEEP page allocation to inflate balloon if below target.
1088
* Sleep allocations are required only when nosleep allocation fails.
1089
* This implies that the guest is already under memory pressure, so
1090
* let us always throttle canSleep allocations. The total number pages
1091
* allocated using noSleep and canSleep methods is throttled at
1092
* b->rateAlloc per second when the guest is under memory pressure.
1094
nAllocCanSleep = target - b->nPages;
1095
nAllocCanSleep = MIN(nAllocCanSleep, b->rateAlloc - nAllocNoSleep);
1097
for (i = 0; i < nAllocCanSleep; i++) {
1098
/* Try CANSLEEP allocation */
1099
status = Balloon_AllocPage(b, BALLOON_PAGE_ALLOC_CANSLEEP);
1100
if(status != BALLOON_SUCCESS) {
1101
if (status == BALLOON_PAGE_ALLOC_FAILURE) {
1103
* CANSLEEP page allocation failed, so guest is under severe
1104
* memory pressure. Quickly decrease rateAlloc.
1106
BalloonDecreaseRateAlloc(b);
1108
/* release non-balloonable pages, fail */
1109
Balloon_ErrorPagesFree(b);
1113
if (++allocations > BALLOON_ALLOC_YIELD_THRESHOLD) {
1120
* Either met the balloon target or b->rateAlloc pages have been
1121
* successfully zapped.
1123
BalloonIncreaseRateAlloc(b, nAllocNoSleep + nAllocCanSleep);
1125
/* release non-balloonable pages, succeed */
1126
Balloon_ErrorPagesFree(b);
1127
return(BALLOON_SUCCESS);
1131
*----------------------------------------------------------------------
1135
* Frees physical pages to deflate balloon.
1138
* Returns BALLOON_SUCCESS if successful, otherwise error code.
1143
*----------------------------------------------------------------------
1146
BalloonDeflate(Balloon *b, uint32 target)
1149
uint32 nFree = b->nPages - target;
1151
/* limit deallocation rate */
1152
nFree = MIN(nFree, b->rateFree);
1154
/* free pages to reach target */
1155
for (i = 0; i < nFree; i++) {
1156
if ((status = Balloon_FreePage(b, TRUE)) != BALLOON_SUCCESS) {
1157
if (BALLOON_RATE_ADAPT) {
1158
/* quickly decrease rate if error */
1159
b->rateFree = MAX(b->rateFree / 2, BALLOON_RATE_FREE_MIN);
1165
if (BALLOON_RATE_ADAPT) {
1166
/* slowly increase rate if no errors */
1167
b->rateFree = MIN(b->rateFree + BALLOON_RATE_FREE_INC,
1168
BALLOON_RATE_FREE_MAX);
1172
return(BALLOON_SUCCESS);
1176
*----------------------------------------------------------------------
1178
* Balloon_AdjustSize --
1180
* Attempts to allocate or deallocate physical pages in order
1181
* to reach desired "target" size for balloon "b".
1184
* Returns BALLOON_SUCCESS if successful, otherwise error code.
1189
*----------------------------------------------------------------------
1192
Balloon_AdjustSize(Balloon *b, uint32 target)
1194
/* done if already at target */
1195
if (b->nPages == target) {
1196
return(BALLOON_SUCCESS);
1199
/* inflate balloon if below target */
1200
if (b->nPages < target) {
1201
return BalloonInflate(b, target);
1204
/* deflate balloon if above target */
1205
if (b->nPages > target) {
1206
return BalloonDeflate(b, target);
1210
return(BALLOON_FAILURE);
1214
* Backdoor Operations
1218
*----------------------------------------------------------------------
1220
* Balloon_MonitorStart --
1222
* Attempts to contact monitor via backdoor to begin operation.
1225
* Returns BALLOON_SUCCESS if successful, otherwise error code.
1230
*----------------------------------------------------------------------
1233
Balloon_MonitorStart(Balloon *b)
1235
uint32 status, target;
1238
/* prepare backdoor args */
1239
bp.in.cx.halfs.low = BALLOON_BDOOR_CMD_START;
1240
bp.in.size = BALLOON_PROTOCOL_VERSION;
1242
/* invoke backdoor */
1243
Backdoor_Balloon(&bp);
1245
/* parse return values */
1246
status = bp.out.ax.word;
1247
target = bp.out.bx.word;
1250
STATS_INC(b->stats.start);
1251
if (status != BALLOON_SUCCESS) {
1252
STATS_INC(b->stats.startFail);
1260
*----------------------------------------------------------------------
1262
* Balloon_MonitorGuestType --
1264
* Attempts to contact monitor and report guest OS identity.
1267
* Returns BALLOON_SUCCESS if successful, otherwise error code.
1272
*----------------------------------------------------------------------
1275
Balloon_MonitorGuestType(Balloon *b)
1277
uint32 status, target;
1280
/* prepare backdoor args */
1281
bp.in.cx.halfs.low = BALLOON_BDOOR_CMD_GUEST_ID;
1282
bp.in.size = BalloonGuestType();
1284
/* invoke backdoor */
1285
Backdoor_Balloon(&bp);
1287
/* parse return values */
1288
status = bp.out.ax.word;
1289
target = bp.out.bx.word;
1291
/* set flag if reset requested */
1292
if (status == BALLOON_ERROR_RESET) {
1297
STATS_INC(b->stats.guestType);
1298
if (status != BALLOON_SUCCESS) {
1299
STATS_INC(b->stats.guestTypeFail);
1307
*----------------------------------------------------------------------
1309
* Balloon_MonitorGetTarget --
1311
* Attempts to contact monitor via backdoor to obtain desired
1314
* Predicts the maximum achievable balloon size and sends it
1315
* to vmm => vmkernel via vEbx register.
1317
* os_predict_max_balloon_pages() returns either predicted max balloon
1318
* pages or BALLOON_MAX_SIZE_USE_CONFIG. In the later scenario,
1319
* vmkernel uses global config options for determining a guest's max
1320
* balloon size. Note that older vmballoon drivers set vEbx to
1321
* BALLOON_MAX_SIZE_USE_CONFIG, i.e., value 0 (zero). So vmkernel
1322
* will fallback to config-based max balloon size estimation.
1325
* If successful, sets "target" to value obtained from monitor,
1326
* and returns BALLOON_SUCCESS. Otherwise returns error code.
1331
*----------------------------------------------------------------------
1334
Balloon_MonitorGetTarget(Balloon *b, uint32 *target)
1339
/* prepare backdoor args */
1340
bp.in.cx.halfs.low = BALLOON_BDOOR_CMD_TARGET;
1341
bp.in.size = os_predict_max_balloon_pages();
1343
/* invoke backdoor */
1344
Backdoor_Balloon(&bp);
1346
/* parse return values */
1347
status = bp.out.ax.word;
1348
*target = bp.out.bx.word;
1350
/* set flag if reset requested */
1351
if (status == BALLOON_ERROR_RESET) {
1356
STATS_INC(b->stats.target);
1357
if (status != BALLOON_SUCCESS) {
1358
STATS_INC(b->stats.targetFail);
1366
*----------------------------------------------------------------------
1368
* Balloon_MonitorLockPage --
1370
* Attempts to contact monitor and add PPN containing "addr"
1371
* to set of "balloon locked" pages.
1374
* Returns BALLOON_SUCCESS if successful, otherwise error code.
1379
*----------------------------------------------------------------------
1382
Balloon_MonitorLockPage(Balloon *b, unsigned long addr)
1386
uint32 status, target;
1389
/* convert kernel-mapped "physical addr" to ppn */
1390
ppn = AddrToPPN(addr);
1392
/* Ensure PPN fits in 32-bits, i.e. guest memory is limited to 16TB. */
1393
ppn32 = (uint32)ppn;
1395
return BALLOON_ERROR_PPN_INVALID;
1398
/* prepare backdoor args */
1399
bp.in.cx.halfs.low = BALLOON_BDOOR_CMD_LOCK;
1402
/* invoke backdoor */
1403
Backdoor_Balloon(&bp);
1405
/* parse return values */
1406
status = bp.out.ax.word;
1407
target = bp.out.bx.word;
1409
/* set flag if reset requested */
1410
if (status == BALLOON_ERROR_RESET) {
1415
STATS_INC(b->stats.lock);
1416
if (status != BALLOON_SUCCESS) {
1417
STATS_INC(b->stats.lockFail);
1425
*----------------------------------------------------------------------
1427
* Balloon_MonitorUnlockPage --
1429
* Attempts to contact monitor and remove PPN containing "addr"
1430
* from set of "balloon locked" pages.
1433
* Returns BALLOON_SUCCESS if successful, otherwise error code.
1438
*----------------------------------------------------------------------
1441
Balloon_MonitorUnlockPage(Balloon *b, unsigned long addr)
1445
uint32 status, target;
1448
/* convert kernel-mapped "physical addr" to ppn */
1449
ppn = AddrToPPN(addr);
1451
/* Ensure PPN fits in 32-bits, i.e. guest memory is limited to 16TB. */
1452
ppn32 = (uint32)ppn;
1454
return BALLOON_ERROR_PPN_INVALID;
1457
/* prepare backdoor args */
1458
bp.in.cx.halfs.low = BALLOON_BDOOR_CMD_UNLOCK;
1461
/* invoke backdoor */
1462
Backdoor_Balloon(&bp);
1464
/* parse return values */
1465
status = bp.out.ax.word;
1466
target = bp.out.bx.word;
1468
/* set flag if reset requested */
1469
if (status == BALLOON_ERROR_RESET) {
1474
STATS_INC(b->stats.unlock);
1475
if (status != BALLOON_SUCCESS) {
1476
STATS_INC(b->stats.unlockFail);
1488
BalloonModuleInit(void)
1490
static int initialized = 0;
1491
Balloon *b = &globalBalloon;
1493
/* initialize only once */
1494
if (initialized++) {
1495
return(BALLOON_FAILURE);
1498
/* initialize global state */
1501
/* os-specific initialization */
1502
os_init(BALLOON_NAME, BALLOON_NAME_VERBOSE, BalloonProcRead);
1503
os_timer_init(Balloon_BH, (void *) b, os_timer_hz());
1506
Balloon_StartTimer(b);
1509
return(BALLOON_SUCCESS);
1513
BalloonModuleCleanup(void)
1515
Balloon *b = &globalBalloon;
1518
Balloon_StopTimer(b);
1521
* Deallocate all reserved memory, and reset connection with monitor.
1522
* Reset connection before deallocating memory to avoid potential for
1523
* additional spurious resets from guest touching deallocated pages.
1525
(void) Balloon_MonitorStart(b);
1526
Balloon_Deallocate(b);
1528
/* os-specific cleanup */
1532
int init_module(void)
1534
return(BalloonModuleInit());
1537
void cleanup_module(void)
1539
BalloonModuleCleanup();