Changeset 27084 in vbox
- Timestamp:
- Mar 5, 2010 1:08:58 PM (15 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/GMM.cpp
r26606 r27084 276 276 277 277 278 #if 0 /* impractical */ 279 GMMR3DECL(int) GMMR3BalloonedPages(PVM pVM, uint32_t cBalloonedPages, uint32_t cPagesToFree, PGMMFREEPAGEDESC paPages, bool fCompleted) 278 /** 279 * @see GMMR0BalloonedPages 280 */ 281 GMMR3DECL(int) GMMR3BalloonedPages(PVM pVM, bool fInflate, uint32_t cBalloonedPages) 280 282 { 281 283 GMMBALLOONEDPAGESREQ Req; 282 284 Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC; 283 285 Req.Hdr.cbReq = sizeof(Req); 286 Req.fInflate = fInflate; 287 Req.cBalloonedPages = cBalloonedPages; 284 288 285 289 return VMMR3CallR0(pVM, VMMR0_DO_GMM_BALLOONED_PAGES, 0, &Req.Hdr); 286 }287 #endif288 289 290 /**291 * @see GMMR0DeflatedBalloon292 */293 GMMR3DECL(int) GMMR3DeflatedBalloon(PVM pVM, uint32_t cPages)294 {295 return VMMR3CallR0(pVM, VMMR0_DO_GMM_DEFLATED_BALLOON, cPages, NULL);296 290 } 297 291 -
trunk/src/VBox/VMM/PGMPhys.cpp
r27042 r27084 772 772 773 773 /** 774 * Rendezvous callback used by PGMR3 PhysFreeRamPages that frees a range of guest physical pages774 * Rendezvous callback used by PGMR3ChangeMemBalloon that changes the memory balloon size 775 775 * 776 776 * This is only called on one of the EMTs while the other ones are waiting for … … 782 782 * @param pvUser User parameter 783 783 */ 784 static DECLCALLBACK(VBOXSTRICTRC) pgmR3Phys FreeRamPagesRendezvous(PVM pVM, PVMCPU pVCpu, void *pvUser)784 static DECLCALLBACK(VBOXSTRICTRC) pgmR3PhysChangeMemBalloonRendezvous(PVM pVM, PVMCPU pVCpu, void *pvUser) 785 785 { 786 786 uintptr_t *paUser = (uintptr_t *)pvUser; 787 unsigned cPages = paUser[0]; 788 RTGCPHYS *paPhysPage = (RTGCPHYS *)paUser[1]; 787 bool fInflate = !!paUser[0]; 788 unsigned cPages = paUser[1]; 789 RTGCPHYS *paPhysPage = (RTGCPHYS *)paUser[2]; 789 790 uint32_t cPendingPages = 0; 790 791 PGMMFREEPAGESREQ pReq; 792 int rc; 791 793 792 794 pgmLock(pVM); 793 int rc = GMMR3FreePagesPrepare(pVM, &pReq, PGMPHYS_FREE_PAGE_BATCH_SIZE, GMMACCOUNT_BASE); 794 if (RT_FAILURE(rc)) 795 { 796 pgmUnlock(pVM); 797 AssertLogRelRC(rc); 798 return rc; 799 } 800 801 /* Iterate the pages. */ 802 for (unsigned i = 0; i < cPages; i++) 803 { 804 PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, paPhysPage[i]); 805 if ( pPage == NULL 806 || pPage->uTypeY != PGMPAGETYPE_RAM) 807 { 808 Log(("PGMR3PhysFreePageRange: invalid physical page %RGp pPage->u3Type=%d\n", paPhysPage[i], (pPage) ? pPage->uTypeY : 0)); 809 break; 810 } 811 812 rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPage, paPhysPage[i]); 795 796 if (fInflate) 797 { 798 /* Replace pages with ZERO pages. */ 799 rc = GMMR3FreePagesPrepare(pVM, &pReq, PGMPHYS_FREE_PAGE_BATCH_SIZE, GMMACCOUNT_BASE); 813 800 if (RT_FAILURE(rc)) 814 801 { … … 817 804 return rc; 818 805 } 819 } 820 821 if (cPendingPages) 822 { 823 rc = GMMR3FreePagesPerform(pVM, pReq, cPendingPages); 824 if (RT_FAILURE(rc)) 825 { 826 pgmUnlock(pVM); 827 AssertLogRelRC(rc); 828 return rc; 829 } 830 } 831 GMMR3FreePagesCleanup(pReq); 832 833 /* Flush the PGM pool cache as we might have stale references to pages that we just freed. */ 834 pgmR3PoolClearAllRendezvous(pVM, pVCpu, NULL); 835 806 807 /* Iterate the pages. */ 808 for (unsigned i = 0; i < cPages; i++) 809 { 810 PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, paPhysPage[i]); 811 if ( pPage == NULL 812 || pPage->uTypeY != PGMPAGETYPE_RAM) 813 { 814 Log(("PGMR3PhysFreePageRange: invalid physical page %RGp pPage->u3Type=%d\n", paPhysPage[i], (pPage) ? pPage->uTypeY : 0)); 815 break; 816 } 817 818 rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPage, paPhysPage[i]); 819 if (RT_FAILURE(rc)) 820 { 821 pgmUnlock(pVM); 822 AssertLogRelRC(rc); 823 return rc; 824 } 825 } 826 827 if (cPendingPages) 828 { 829 rc = GMMR3FreePagesPerform(pVM, pReq, cPendingPages); 830 if (RT_FAILURE(rc)) 831 { 832 pgmUnlock(pVM); 833 AssertLogRelRC(rc); 834 return rc; 835 } 836 } 837 GMMR3FreePagesCleanup(pReq); 838 839 /* Flush the PGM pool cache as we might have stale references to pages that we just freed. */ 840 pgmR3PoolClearAllRendezvous(pVM, pVCpu, NULL); 841 } 842 843 /* Notify GMM about the balloon change. */ 844 rc = GMMR3BalloonedPages(pVM, fInflate, cPages); 836 845 pgmUnlock(pVM); 846 AssertLogRelRC(rc); 837 847 return rc; 838 848 } … … 843 853 * @returns VBox status code. 844 854 * @param pVM The VM handle. 855 * @param fInflate Inflate or deflate memory balloon 845 856 * @param cPages Number of pages to free 846 857 * @param paPhysPage Array of guest physical addresses 847 858 */ 848 static DECLCALLBACK(void) pgmR3PhysFreeRamPagesHelper(PVM pVM, unsigned cPages, RTGCPHYS *paPhysPage) 849 { 850 uintptr_t paUser[2]; 851 852 paUser[0] = cPages; 853 paUser[1] = (uintptr_t)paPhysPage; 854 int rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, pgmR3PhysFreeRamPagesRendezvous, (void *)paUser); 859 static DECLCALLBACK(void) pgmR3PhysChangeMemBalloonHelper(PVM pVM, bool fInflate, unsigned cPages, RTGCPHYS *paPhysPage) 860 { 861 uintptr_t paUser[3]; 862 863 paUser[0] = fInflate; 864 paUser[1] = cPages; 865 paUser[2] = (uintptr_t)paPhysPage; 866 int rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, pgmR3PhysChangeMemBalloonRendezvous, (void *)paUser); 855 867 AssertRC(rc); 856 868 … … 860 872 861 873 /** 862 * Frees a range of ram pages, replacing them with ZERO pages874 * Inflate or deflate a memory balloon 863 875 * 864 876 * @returns VBox status code. 865 877 * @param pVM The VM handle. 878 * @param fInflate Inflate or deflate memory balloon 866 879 * @param cPages Number of pages to free 867 880 * @param paPhysPage Array of guest physical addresses 868 881 */ 869 VMMR3DECL(int) PGMR3Phys FreeRamPages(PVM pVM, unsigned cPages, RTGCPHYS *paPhysPage)882 VMMR3DECL(int) PGMR3PhysChangeMemBalloon(PVM pVM, bool fInflate, unsigned cPages, RTGCPHYS *paPhysPage) 870 883 { 871 884 int rc; 872 873 /* Currently only used by the VMM device in responds to a balloon request. */874 885 875 886 /* We own the IOM lock here and could cause a deadlock by waiting for another VCPU that is blocking on the IOM lock. … … 884 895 memcpy(paPhysPageCopy, paPhysPage, cbPhysPage); 885 896 886 rc = VMR3ReqCallNoWait(pVM, VMCPUID_ANY_QUEUE, (PFNRT)pgmR3Phys FreeRamPagesHelper, 3, pVM, cPages, paPhysPageCopy);897 rc = VMR3ReqCallNoWait(pVM, VMCPUID_ANY_QUEUE, (PFNRT)pgmR3PhysChangeMemBalloonHelper, 4, pVM, fInflate, cPages, paPhysPageCopy); 887 898 AssertRC(rc); 888 899 } 889 900 else 890 901 { 891 uintptr_t paUser[2]; 892 893 paUser[0] = cPages; 894 paUser[1] = (uintptr_t)paPhysPage; 895 rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, pgmR3PhysFreeRamPagesRendezvous, (void *)paUser); 902 uintptr_t paUser[3]; 903 904 paUser[0] = fInflate; 905 paUser[1] = cPages; 906 paUser[2] = (uintptr_t)paPhysPage; 907 rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, pgmR3PhysChangeMemBalloonRendezvous, (void *)paUser); 896 908 AssertRC(rc); 897 909 } -
trunk/src/VBox/VMM/VMMR0/GMMR0.cpp
r27005 r27084 1079 1079 * The initial resource reservations. 1080 1080 * 1081 * This will make memory reservations according to policy and priority. If there isn't1081 * This will make memory reservations according to policy and priority. If there aren't 1082 1082 * sufficient resources available to sustain the VM this function will fail and all 1083 1083 * future allocations requests will fail as well. … … 1813 1813 { 1814 1814 case GMMACCOUNT_BASE: 1815 if (RT_UNLIKELY(pGVM->gmm.s.Allocated.cBasePages + cPages > pGVM->gmm.s.Reserved.cBasePages))1815 if (RT_UNLIKELY(pGVM->gmm.s.Allocated.cBasePages + pGVM->gmm.s.cBalloonedPages + cPages > pGVM->gmm.s.Reserved.cBasePages)) 1816 1816 { 1817 1817 Log(("gmmR0AllocatePages: Reserved=%#llx Allocated+Requested=%#llx+%#x!\n", … … 2324 2324 GMMPAGEDESC PageDesc; 2325 2325 2326 if (RT_UNLIKELY(pGVM->gmm.s.Allocated.cBasePages + cPages > pGVM->gmm.s.Reserved.cBasePages))2326 if (RT_UNLIKELY(pGVM->gmm.s.Allocated.cBasePages + pGVM->gmm.s.cBalloonedPages + cPages > pGVM->gmm.s.Reserved.cBasePages)) 2327 2327 { 2328 2328 Log(("GMMR0AllocateLargePage: Reserved=%#llx Allocated+Requested=%#llx+%#x!\n", … … 2841 2841 * ballooned. 2842 2842 * 2843 * Since the whole purpose of ballooning is to free up guest RAM pages, this API2844 * may also be given a set of related pages to be freed. These pages are assumed2845 * to be on the base account.2846 *2847 2843 * @returns VBox status code: 2848 2844 * @retval xxx … … 2850 2846 * @param pVM Pointer to the shared VM structure. 2851 2847 * @param idCpu VCPU id 2848 * @param fInflate Inflate or deflate the balloon 2852 2849 * @param cBalloonedPages The number of pages that was ballooned. 2853 * @param cPagesToFree The number of pages to be freed. 2854 * @param paPages Pointer to the page descriptors for the pages that's to be freed. 2855 * @param fCompleted Indicates whether the ballooning request was completed (true) or 2856 * if there is more pages to come (false). If the ballooning was not 2857 * not triggered by the GMM, don't set this. 2850 * 2858 2851 * @thread EMT. 2859 2852 */ 2860 GMMR0DECL(int) GMMR0BalloonedPages(PVM pVM, VMCPUID idCpu, uint32_t cBalloonedPages, uint32_t cPagesToFree, PGMMFREEPAGEDESC paPages, bool fCompleted)2861 { 2862 LogFlow(("GMMR0BalloonedPages: pVM=%p cBalloonedPages=%#x cPagestoFree=%#x paPages=%p enmAccount=%d fCompleted=%RTbool\n",2863 pVM, cBalloonedPages, cPagesToFree, paPages, fCompleted));2853 GMMR0DECL(int) GMMR0BalloonedPages(PVM pVM, VMCPUID idCpu, bool fInflate, uint32_t cBalloonedPages) 2854 { 2855 LogFlow(("GMMR0BalloonedPages: pVM=%p fInflate=%RTBool cBalloonedPages=%#x\n", 2856 pVM, fInflate, cBalloonedPages)); 2864 2857 2865 2858 /* … … 2873 2866 return rc; 2874 2867 2875 AssertPtrReturn(paPages, VERR_INVALID_PARAMETER);2876 2868 AssertMsgReturn(cBalloonedPages < RT_BIT(32 - PAGE_SHIFT), ("%#x\n", cBalloonedPages), VERR_INVALID_PARAMETER); 2877 AssertMsgReturn(cPagesToFree <= cBalloonedPages, ("%#x\n", cPagesToFree), VERR_INVALID_PARAMETER);2878 2879 for (unsigned iPage = 0; iPage < cPagesToFree; iPage++)2880 AssertMsgReturn( paPages[iPage].idPage <= GMM_PAGEID_LAST2881 /*|| paPages[iPage].idPage == NIL_GMM_PAGEID*/,2882 ("#%#x: %#x\n", iPage, paPages[iPage].idPage), VERR_INVALID_PARAMETER);2883 2869 2884 2870 /* … … 2889 2875 if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM)) 2890 2876 { 2891 2892 if (pGVM->gmm.s.Allocated.cBasePages >= cPagesToFree) 2893 { 2894 /* 2895 * Record the ballooned memory. 2896 */ 2897 pGMM->cBalloonedPages += cBalloonedPages; 2898 if (pGVM->gmm.s.cReqBalloonedPages) 2877 if (fInflate) 2878 { 2879 if (pGVM->gmm.s.Allocated.cBasePages >= cBalloonedPages) 2899 2880 { 2900 pGVM->gmm.s.cBalloonedPages += cBalloonedPages; 2901 pGVM->gmm.s.cReqActuallyBalloonedPages += cBalloonedPages; 2902 if (fCompleted) 2881 /* 2882 * Record the ballooned memory. 2883 */ 2884 pGMM->cBalloonedPages += cBalloonedPages; 2885 if (pGVM->gmm.s.cReqBalloonedPages) 2903 2886 { 2904 Log(("GMMR0BalloonedPages: +%#x - Global=%#llx; / VM: Total=%#llx Req=%#llx Actual=%#llx (completed)\n", cBalloonedPages, 2887 /* Codepath never taken. Might be interesting in the future to request ballooned memory from guests in low memory conditions.. */ 2888 AssertFailed(); 2889 2890 pGVM->gmm.s.cBalloonedPages += cBalloonedPages; 2891 pGVM->gmm.s.cReqActuallyBalloonedPages += cBalloonedPages; 2892 Log(("GMMR0BalloonedPages: +%#x - Global=%#llx / VM: Total=%#llx Req=%#llx Actual=%#llx (pending)\n", cBalloonedPages, 2905 2893 pGMM->cBalloonedPages, pGVM->gmm.s.cBalloonedPages, pGVM->gmm.s.cReqBalloonedPages, pGVM->gmm.s.cReqActuallyBalloonedPages)); 2906 2907 /*2908 * Anything we need to do here now when the request has been completed?2909 */2910 pGVM->gmm.s.cReqBalloonedPages = 0;2911 2894 } 2912 2895 else 2913 Log(("GMMR0BalloonedPages: +%#x - Global=%#llx / VM: Total=%#llx Req=%#llx Actual=%#llx (pending)\n", cBalloonedPages, 2914 pGMM->cBalloonedPages, pGVM->gmm.s.cBalloonedPages, pGVM->gmm.s.cReqBalloonedPages, pGVM->gmm.s.cReqActuallyBalloonedPages)); 2896 { 2897 pGVM->gmm.s.cBalloonedPages += cBalloonedPages; 2898 Log(("GMMR0BalloonedPages: +%#x - Global=%#llx / VM: Total=%#llx (user)\n", 2899 cBalloonedPages, pGMM->cBalloonedPages, pGVM->gmm.s.cBalloonedPages)); 2900 } 2915 2901 } 2916 2902 else 2903 rc = VERR_GMM_ATTEMPT_TO_FREE_TOO_MUCH; 2904 } 2905 else 2906 { 2907 /* Deflate. */ 2908 if (pGVM->gmm.s.cBalloonedPages >= cBalloonedPages) 2917 2909 { 2918 pGVM->gmm.s.cBalloonedPages += cBalloonedPages; 2919 Log(("GMMR0BalloonedPages: +%#x - Global=%#llx / VM: Total=%#llx (user)\n", 2910 /* 2911 * Record the ballooned memory. 2912 */ 2913 Assert(pGMM->cBalloonedPages >= cBalloonedPages); 2914 pGMM->cBalloonedPages -= cBalloonedPages; 2915 pGVM->gmm.s.cBalloonedPages -= cBalloonedPages; 2916 Log(("GMMR0BalloonedPages: -%#x - Global=%#llx / VM: Total=%#llx (user)\n", 2920 2917 cBalloonedPages, pGMM->cBalloonedPages, pGVM->gmm.s.cBalloonedPages)); 2921 2918 } 2922 2923 /* 2924 * Any pages to free? 2925 */ 2926 if (cPagesToFree) 2927 rc = gmmR0FreePages(pGMM, pGVM, cPagesToFree, paPages, GMMACCOUNT_BASE); 2928 } 2929 else 2930 rc = VERR_GMM_ATTEMPT_TO_FREE_TOO_MUCH; 2919 else 2920 rc = VERR_GMM_ATTEMPT_TO_DEFLATE_TOO_MUCH; 2921 } 2931 2922 GMM_CHECK_SANITY_UPON_LEAVING(pGMM); 2932 2923 } … … 2954 2945 AssertPtrReturn(pVM, VERR_INVALID_POINTER); 2955 2946 AssertPtrReturn(pReq, VERR_INVALID_POINTER); 2956 AssertMsgReturn(pReq->Hdr.cbReq >= RT_UOFFSETOF(GMMBALLOONEDPAGESREQ, aPages[0]),2957 ("%#x < %#x\n", pReq->Hdr.cbReq, RT_UOFFSETOF(GMMBALLOONEDPAGESREQ, aPages[0])),2947 AssertMsgReturn(pReq->Hdr.cbReq == sizeof(GMMBALLOONEDPAGESREQ), 2948 ("%#x < %#x\n", pReq->Hdr.cbReq, sizeof(GMMBALLOONEDPAGESREQ)), 2958 2949 VERR_INVALID_PARAMETER); 2959 AssertMsgReturn(pReq->Hdr.cbReq == RT_UOFFSETOF(GMMBALLOONEDPAGESREQ, aPages[pReq->cPagesToFree]), 2960 ("%#x != %#x\n", pReq->Hdr.cbReq, RT_UOFFSETOF(GMMBALLOONEDPAGESREQ, aPages[pReq->cPagesToFree])), 2961 VERR_INVALID_PARAMETER); 2962 2963 return GMMR0BalloonedPages(pVM, idCpu, pReq->cBalloonedPages, pReq->cPagesToFree, &pReq->aPages[0], pReq->fCompleted); 2950 2951 return GMMR0BalloonedPages(pVM, idCpu, pReq->fInflate, pReq->cBalloonedPages); 2964 2952 } 2965 2953 -
trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
r26606 r27084 915 915 return GMMR0BalloonedPagesReq(pVM, idCpu, (PGMMBALLOONEDPAGESREQ)pReqHdr); 916 916 917 case VMMR0_DO_GMM_DEFLATED_BALLOON:918 if (pReqHdr)919 return VERR_INVALID_PARAMETER;920 return GMMR0DeflatedBalloon(pVM, idCpu, (uint32_t)u64Arg);921 922 917 case VMMR0_DO_GMM_MAP_UNMAP_CHUNK: 923 918 if (u64Arg) … … 1116 1111 case VMMR0_DO_GMM_FREE_PAGES: 1117 1112 case VMMR0_DO_GMM_BALLOONED_PAGES: 1118 case VMMR0_DO_GMM_DEFLATED_BALLOON:1119 1113 /* On the mac we might not have a valid jmp buf, so check these as well. */ 1120 1114 case VMMR0_DO_VMMR0_INIT:
Note:
See TracChangeset
for help on using the changeset viewer.