Changeset 26999 in vbox for trunk/src/VBox
- Timestamp:
- Mar 3, 2010 5:00:05 PM (15 years ago)
- Location:
- trunk/src/VBox/Additions
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/VBoxGuest/VBoxGuest.cpp
r26922 r26999 745 745 if (RT_FAILURE(rc)) 746 746 { 747 dprintf(("VBoxGuest::VBoxGuestDeviceControl VBOXGUEST_IOCTL_C TL_CHECK_BALLOON: error issuing request to VMMDev! "747 dprintf(("VBoxGuest::VBoxGuestDeviceControl VBOXGUEST_IOCTL_CHECK_BALLOON: error issuing request to VMMDev! " 748 748 "rc = %Rrc\n", rc)); 749 749 } … … 1380 1380 1381 1381 #ifdef VBOX_WITH_MANAGEMENT 1382 case VBOXGUEST_IOCTL_C TL_CHECK_BALLOON_MASK:1382 case VBOXGUEST_IOCTL_CHECK_BALLOON: 1383 1383 { 1384 1384 ULONG *pMemBalloonSize = (ULONG *) pBuf; … … 1395 1395 if (RT_FAILURE(rc)) 1396 1396 { 1397 dprintf(("VBOXGUEST_IOCTL_C TL_CHECK_BALLOON: vbox rc = %Rrc\n", rc));1397 dprintf(("VBOXGUEST_IOCTL_CHECK_BALLOON: vbox rc = %Rrc\n", rc)); 1398 1398 Status = STATUS_UNSUCCESSFUL; 1399 1399 } -
trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp
r26934 r26999 276 276 277 277 /** 278 * Infl tate/deflate the memory balloon and notify the host.278 * Inflate/deflate the memory balloon and notify the host. 279 279 * 280 280 * @returns VBox status code. … … 282 282 * @param u32BalloonSize The new size of the balloon in chunks of 1MB. 283 283 */ 284 static int vboxGuestSetBalloonSize(PVBOXGUESTDEVEXT pDevExt, uint32_t u32BalloonSize) 285 { 286 VMMDevChangeMemBalloon *pReq; 284 static int vboxGuestSetBalloonSizeKernel(PVBOXGUESTDEVEXT pDevExt, uint32_t u32BalloonSize) 285 { 287 286 int rc = VINF_SUCCESS; 288 uint32_t i, j;289 const size_t cbReq = RT_OFFSETOF(VMMDevChangeMemBalloon, aPhysPage[VMMDEV_MEMORY_BALLOON_CHUNK_PAGES]);290 291 if (u32BalloonSize > pDevExt->MemBalloon.cMaxChunks)292 {293 AssertMsgFailed(("vboxGuestSetBalloonSize illegal balloon size %d (max=%d)\n",294 u32BalloonSize, pDevExt->MemBalloon.cMaxChunks));295 return VERR_INVALID_PARAMETER;296 }297 298 if (u32BalloonSize == pDevExt->MemBalloon.cMaxChunks)299 return VINF_SUCCESS; /* nothing to do */300 301 rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, cbReq, VMMDevReq_ChangeMemBalloon);302 if (RT_FAILURE(rc))303 return rc;304 287 305 288 if (pDevExt->MemBalloon.fUseKernelAPI) 306 289 { 290 VMMDevChangeMemBalloon *pReq; 291 uint32_t i, j; 292 const size_t cbReq = RT_OFFSETOF(VMMDevChangeMemBalloon, aPhysPage[VMMDEV_MEMORY_BALLOON_CHUNK_PAGES]); 293 294 if (u32BalloonSize > pDevExt->MemBalloon.cMaxChunks) 295 { 296 AssertMsgFailed(("vboxGuestSetBalloonSize illegal balloon size %d (max=%d)\n", 297 u32BalloonSize, pDevExt->MemBalloon.cMaxChunks)); 298 return VERR_INVALID_PARAMETER; 299 } 300 301 if (u32BalloonSize == pDevExt->MemBalloon.cMaxChunks) 302 return VINF_SUCCESS; /* nothing to do */ 303 304 rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, cbReq, VMMDevReq_ChangeMemBalloon); 305 if (RT_FAILURE(rc)) 306 return rc; 307 307 308 if (u32BalloonSize > pDevExt->MemBalloon.cChunks) 308 309 { … … 381 382 } 382 383 } 384 385 VbglGRFree(&pReq->header); 383 386 } 384 387 385 388 if (!pDevExt->MemBalloon.fUseKernelAPI) 386 389 { 387 /* R3 to allocate memory, R0 to lock it down and tell the host */ 388 } 390 /* R3 to allocate memory, then do ioctl(VBOXGUEST_IOCTL_CHANGE_BALLOON) 391 * and R0 to lock it down and tell the host. */ 392 rc = VERR_NO_PHYS_MEMORY; 393 } 394 395 return rc; 396 } 397 398 399 /** 400 * Inflate/deflate the balloon by one chunk. 401 */ 402 static int vboxGuestSetBalloonSizeFromUser(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, 403 uint64_t u64ChunkAddr, bool fInflate) 404 { 405 VMMDevChangeMemBalloon *pReq; 406 int rc = VINF_SUCCESS; 407 uint32_t i, j; 408 const size_t cbReq = RT_OFFSETOF(VMMDevChangeMemBalloon, aPhysPage[VMMDEV_MEMORY_BALLOON_CHUNK_PAGES]); 409 PRTR0MEMOBJ pMemObj = NULL; 410 411 if ( fInflate 412 && pSession->MemBalloon.cChunks > pSession->MemBalloon.cMaxChunks - 1) 413 { 414 AssertMsgFailed(("vboxGuestSetBalloonSize: cannot inflate balloon, already have (max=%d)\n", 415 pSession->MemBalloon.cChunks, pSession->MemBalloon.cMaxChunks)); 416 return VERR_INVALID_PARAMETER; 417 } 418 else if ( !fInflate 419 && pSession->MemBalloon.cChunks == 0) 420 { 421 AssertMsgFailed(("vboxGuestSetBalloonSize: cannot decrease balloon, already at size 0\n")); 422 return VERR_INVALID_PARAMETER; 423 } 424 425 /* 426 * Enumerate all memory objects and check if the object is already registered. 427 */ 428 for (i = 0; i < pSession->MemBalloon.cMaxChunks; i++) 429 { 430 if ( fInflate 431 && !pSession->MemBalloon.paMemObj[i] == NIL_RTR0MEMOBJ 432 && !pMemObj) 433 pMemObj = &pSession->MemBalloon.paMemObj[i]; /* found free object pointer */ 434 if (RTR0MemObjAddressR3(pSession->MemBalloon.paMemObj[i]) == u64ChunkAddr) 435 { 436 if (fInflate) 437 return VERR_ALREADY_EXISTS; /* don't provide the same memory twice */ 438 pMemObj = &pSession->MemBalloon.paMemObj[i]; 439 break; 440 } 441 } 442 if (!pMemObj) 443 { 444 if (fInflate) 445 return VERR_NO_MEMORY; /* no free object pointer found -- should not happen */ 446 else 447 return VERR_NOT_FOUND; /* cannot free this memory as it wasn't provided before */ 448 } 449 450 rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, cbReq, VMMDevReq_ChangeMemBalloon); 451 if (RT_FAILURE(rc)) 452 return rc; 453 454 do 455 { 456 if (fInflate) 457 { 458 rc = RTR0MemObjLockUser(pMemObj, u64ChunkAddr, VMMDEV_MEMORY_BALLOON_CHUNK_PAGES * PAGE_SIZE, 459 RTMEM_PROT_READ | RTMEM_PROT_WRITE, NIL_RTR0PROCESS); 460 if (RT_SUCCESS(rc)) 461 { 462 RTR0MEMOBJ MemObj = pDevExt->MemBalloon.paMemObj[i]; 463 for (j = 0; j < VMMDEV_MEMORY_BALLOON_CHUNK_PAGES; j++) 464 { 465 RTHCPHYS phys = RTR0MemObjGetPagePhysAddr(MemObj, j); 466 pReq->aPhysPage[j] = phys; 467 } 468 469 pReq->header.size = cbReq; 470 pReq->cPages = VMMDEV_MEMORY_BALLOON_CHUNK_PAGES; 471 pReq->fInflate = true; 472 473 rc = VbglGRPerform(&pReq->header); 474 if (RT_FAILURE(rc)) 475 { 476 Log(("vboxGuestSetBalloonSize(inflate): VbglGRPerform failed, rc=%Rrc!\n", rc)); 477 break; 478 } 479 pSession->MemBalloon.cChunks++; 480 } 481 } 482 else 483 { 484 /* deflate */ 485 for (j = 0; j < VMMDEV_MEMORY_BALLOON_CHUNK_PAGES; j++) 486 { 487 RTHCPHYS phys = RTR0MemObjGetPagePhysAddr(*pMemObj, j); 488 pReq->aPhysPage[j] = phys; 489 } 490 491 pReq->header.size = cbReq; 492 pReq->cPages = VMMDEV_MEMORY_BALLOON_CHUNK_PAGES; 493 pReq->fInflate = false; 494 495 rc = VbglGRPerform(&pReq->header); 496 if (RT_FAILURE(rc)) 497 { 498 Log(("vboxGuestSetBalloonSize(deflate): VbglGRPerform failed, rc=%Rrc!\n", rc)); 499 break; 500 } 501 502 rc = RTR0MemObjFree(*pMemObj, true); 503 if (RT_FAILURE(rc)) 504 { 505 Log(("vboxGuestSetBalloonSize(deflate): RTR0MemObjFree() failed, rc=%Rrc!\n", rc)); 506 break; 507 } 508 *pMemObj = NIL_RTR0MEMOBJ; 509 pSession->MemBalloon.cChunks--; 510 } 511 } while (0); 389 512 390 513 VbglGRFree(&pReq->header); … … 402 525 pDevExt->MemBalloon.cChunks = 0; 403 526 pDevExt->MemBalloon.cMaxChunks = 0; 404 #ifdef RT_OS_LINUX405 pDevExt->MemBalloon.fUseKernelAPI = true;406 #else527 //#ifdef RT_OS_LINUX 528 // pDevExt->MemBalloon.fUseKernelAPI = true; 529 //#else 407 530 pDevExt->MemBalloon.fUseKernelAPI = false; 408 #endif531 //#endif 409 532 pDevExt->MemBalloon.paMemObj = NULL; 410 533 } … … 420 543 if (pDevExt->MemBalloon.paMemObj) 421 544 { 422 vboxGuestSetBalloonSize (pDevExt, 0);545 vboxGuestSetBalloonSizeKernel(pDevExt, 0); 423 546 RTMemFree(pDevExt->MemBalloon.paMemObj); 424 547 pDevExt->MemBalloon.paMemObj = NULL; … … 652 775 int VBoxGuestCreateUserSession(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION *ppSession) 653 776 { 777 unsigned i; 654 778 PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)RTMemAllocZ(sizeof(*pSession)); 655 779 if (RT_UNLIKELY(!pSession)) … … 662 786 pSession->R0Process = RTR0ProcHandleSelf(); 663 787 pSession->pDevExt = pDevExt; 788 789 pSession->MemBalloon.cChunks = 0; 790 pSession->MemBalloon.cMaxChunks = 0; 664 791 665 792 *ppSession = pSession; … … 1612 1739 1613 1740 /** 1614 * Handle VBOXGUEST_IOCTL_CTL_CHECK_BALLOON_MASK from R3. Ask the host for the size of 1615 * the balloon and set it accordingly. 1741 * Handle VBOXGUEST_IOCTL_CHECK_BALLOON from R3. Ask the host for the size 1742 * of the balloon and try to set it accordingly. If this fails, return with 1743 * VERR_NO_PHYS_MEMORY and userland has to provide the memory. 1616 1744 * 1617 1745 * @returns VBox status code. 1618 1746 */ 1619 static int VBoxGuestCommonIOCtl_QueryMemoryBalloon(PVBOXGUESTDEVEXT pDevExt, uint32_t *memBalloonSize, size_t *pcbDataReturned) 1747 static int VBoxGuestCommonIOCtl_QueryMemoryBalloon(PVBOXGUESTDEVEXT pDevExt, 1748 uint32_t *memBalloonSize, size_t *pcbDataReturned) 1620 1749 { 1621 1750 VMMDevGetMemBalloonChangeRequest *pReq; … … 1642 1771 } 1643 1772 1644 rc = vboxGuestSetBalloonSize (pDevExt, pReq->u32BalloonSize);1773 rc = vboxGuestSetBalloonSizeKernel(pDevExt, pReq->u32BalloonSize); 1645 1774 /* ignore out of memory failures */ 1646 1775 if (rc == VERR_NO_MEMORY) … … 1654 1783 return rc; 1655 1784 } 1785 1786 1787 /** 1788 * 1789 */ 1790 static int VBoxGuestCommonIOCtl_ChangeMemoryBalloon(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, 1791 VBoxGuestChangeBalloonInfo *pInfo, size_t *pcbDataReturned) 1792 { 1793 int rc = vboxGuestSetBalloonSizeFromUser(pDevExt, pSession, pInfo->u64ChunkAddr, pInfo->fInflate); 1794 if (pcbDataReturned) 1795 *pcbDataReturned = 0; 1796 return rc; 1797 } 1798 1656 1799 1657 1800 /** … … 1833 1976 #endif /* VBOX_WITH_HGCM */ 1834 1977 1835 case VBOXGUEST_IOCTL_C TL_CHECK_BALLOON_MASK:1836 CHECKRET_MIN_SIZE(" MEMORY_BALLOON", sizeof(uint32_t));1978 case VBOXGUEST_IOCTL_CHECK_BALLOON: 1979 CHECKRET_MIN_SIZE("CHECK_MEMORY_BALLOON", sizeof(uint32_t)); 1837 1980 rc = VBoxGuestCommonIOCtl_QueryMemoryBalloon(pDevExt, (uint32_t *)pvData, pcbDataReturned); 1981 break; 1982 1983 case VBOXGUEST_IOCTL_CHANGE_BALLOON: 1984 CHECKRET_MIN_SIZE("CHANGE_MEMORY_BALLOON", sizeof(VBoxGuestChangeBalloonInfo)); 1985 rc = VBoxGuestCommonIOCtl_ChangeMemoryBalloon(pDevExt, pSession, (VBoxGuestChangeBalloonInfo *)pvData, pcbDataReturned); 1838 1986 break; 1839 1987 -
trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h
r26934 r26999 140 140 uint32_t u32ClipboardClientId; 141 141 142 /* Memory balloon information . */142 /* Memory balloon information for RTR0MemObjAllocPhysNC(). */ 143 143 VBOXGUESTMEMBALLOON MemBalloon; 144 144 … … 183 183 * Used to implement polling. */ 184 184 uint32_t volatile u32MousePosChangedSeq; 185 186 /* Memory ballooning information if userland provides the balloon memory. */ 187 VBOXGUESTMEMBALLOON MemBalloon; 185 188 } VBOXGUESTSESSION; 186 189 -
trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibMisc.cpp
r26493 r26999 240 240 VBGLR3DECL(int) VbglR3MemBalloonRefresh(uint32_t *pu32Size) 241 241 { 242 return vbglR3DoIOCtl(VBOXGUEST_IOCTL_CTL_CHECK_BALLOON_MASK, pu32Size, sizeof(*pu32Size)); 242 return vbglR3DoIOCtl(VBOXGUEST_IOCTL_CHECK_BALLOON, pu32Size, sizeof(*pu32Size)); 243 } 244 245 246 /** 247 * 248 */ 249 VBGLR3DECL(int) VbglR3MemBalloonChange(void *pv, bool fInflate) 250 { 251 VBoxGuestChangeBalloonInfo Info; 252 Info.u64ChunkAddr = (uint64_t)pv; 253 Info.fInflate = fInflate; 254 return vbglR3DoIOCtl(VBOXGUEST_IOCTL_CHANGE_BALLOON, &Info, sizeof(Info)); 243 255 } 244 256 -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceBalloon.cpp
r26904 r26999 22 22 #include <iprt/mem.h> 23 23 #include <iprt/thread.h> 24 #include <iprt/stream.h> 24 25 #include <iprt/string.h> 25 26 #include <iprt/semaphore.h> … … 40 41 static RTSEMEVENTMULTI g_MemBalloonEvent = NIL_RTSEMEVENTMULTI; 41 42 43 static void **g_pavBalloon = NULL; 44 45 46 static void VBoxServiceBalloonSetUser(uint32_t OldSize, uint32_t NewSize) 47 { 48 if (NewSize == OldSize) 49 return; 50 51 int rc = VINF_SUCCESS; 52 if (NewSize > OldSize) 53 { 54 /* inflate */ 55 uint32_t i; 56 g_pavBalloon = (void**)RTMemRealloc(g_pavBalloon, NewSize * sizeof(void*)); 57 RTPrintf("allocated %d bytes\n", g_pavBalloon, NewSize * sizeof(void*)); 58 for (i = OldSize; i < NewSize; i++) 59 { 60 void *pv = RTMemAlloc(VMMDEV_MEMORY_BALLOON_CHUNK_PAGES * PAGE_SIZE); 61 VBoxServiceVerbose(3, "Alloc %p\n", pv); 62 rc = VbglR3MemBalloonChange(pv, /* inflate=*/ true); 63 if (RT_SUCCESS(rc)) 64 { 65 VBoxServiceVerbose(3, " => %Rrc\n", rc); 66 g_pavBalloon[i] = pv; 67 OldSize++; 68 } 69 else 70 break; 71 } 72 } 73 else 74 { 75 /* deflate */ 76 uint32_t i; 77 for (i = OldSize; i > NewSize; i--) 78 { 79 void *pv = g_pavBalloon[i-1]; 80 rc = VbglR3MemBalloonChange(pv, /* inflate=*/ false); 81 if (RT_SUCCESS(rc)) 82 { 83 VBoxServiceVerbose(3, "Free %p\n", g_pavBalloon[i-1]); 84 RTMemFree(g_pavBalloon[i-1]); 85 g_pavBalloon[i-1] = NULL; 86 OldSize--; 87 } 88 else 89 break; 90 } 91 } 92 93 if (RT_FAILURE(rc)) 94 g_MemBalloonSize = OldSize; 95 } 96 97 42 98 /** @copydoc VBOXSERVICE::pfnPreInit */ 43 99 static DECLCALLBACK(int) VBoxServiceBalloonPreInit(void) … … 68 124 if (RT_SUCCESS(rc)) 69 125 VBoxServiceVerbose(3, "VBoxMemBalloonInit: new balloon size %d MB\n", g_MemBalloonSize); 126 else if (rc == VERR_NO_PHYS_MEMORY) 127 VBoxServiceBalloonSetUser(0, g_MemBalloonSize); 70 128 else 71 129 VBoxServiceVerbose(3, "VBoxMemBalloonInit: VbglR3MemBalloonRefresh failed with %d\n", rc); … … 113 171 && (fEvents & VMMDEV_EVENT_BALLOON_CHANGE_REQUEST)) 114 172 { 173 uint32_t OldMemBalloonSize = g_MemBalloonSize; 115 174 rc = VbglR3MemBalloonRefresh(&g_MemBalloonSize); 116 175 if (RT_SUCCESS(rc)) 117 176 VBoxServiceVerbose(3, "VBoxServiceBalloonWorker: new balloon size %d MB\n", g_MemBalloonSize); 177 else if (rc == VERR_NO_PHYS_MEMORY) 178 VBoxServiceBalloonSetUser(OldMemBalloonSize, g_MemBalloonSize); 118 179 else 119 180 VBoxServiceVerbose(3, "VBoxServiceBalloonWorker: VbglR3MemBalloonRefresh failed with %d\n", rc);
Note:
See TracChangeset
for help on using the changeset viewer.