Changeset 15411 in vbox
- Timestamp:
- Dec 13, 2008 3:30:58 AM (16 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/pgm.h
r15403 r15411 455 455 VMMDECL(void) PGMDynMapFlushAutoSet(PVMCPU pVCpu); 456 456 VMMDECL(void) PGMDynMapMigrateAutoSet(PVMCPU pVCpu); 457 VMMDECL(uint32_t) PGMDynMapPushAutoSubset(PVMCPU pVCpu); 458 VMMDECL(void) PGMDynMapPopAutoSubset(PVMCPU pVCpu, uint32_t iPrevSubset); 457 459 458 460 /** -
trunk/src/VBox/VMM/PGM.cpp
r15404 r15411 1609 1609 STAM_REG(pVM, &pPGM->StatR0DynMapPage, STAMTYPE_COUNTER, "/PGM/R0/DynMapPage", STAMUNIT_OCCURENCES, "Calls to pgmR0DynMapPage"); 1610 1610 STAM_REG(pVM, &pPGM->StatR0DynMapSetOptimize, STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/SetOptimize", STAMUNIT_OCCURENCES, "Calls to pgmDynMapOptimizeAutoSet."); 1611 STAM_REG(pVM, &pPGM->StatR0DynMapSetSearchFlushes, STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/SetSearchFlushes",STAMUNIT_OCCURENCES, "Set search restorting to subset flushes."); 1611 1612 STAM_REG(pVM, &pPGM->StatR0DynMapSetSearchHits, STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/SetSearchHits", STAMUNIT_OCCURENCES, "Set search hits."); 1612 1613 STAM_REG(pVM, &pPGM->StatR0DynMapSetSearchMisses, STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/SetSearchMisses", STAMUNIT_OCCURENCES, "Set search misses."); … … 1620 1621 STAM_REG(pVM, &pPGM->StatR0DynMapPageSlowLoopMisses, STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/SlowLoopMisses", STAMUNIT_OCCURENCES, "Misses in the loop path. NonLoopMisses = Slow - SlowLoopHit - SlowLoopMisses"); 1621 1622 //STAM_REG(pVM, &pPGM->StatR0DynMapPageSlowLostHits, STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/SlowLostHits", STAMUNIT_OCCURENCES, "Lost hits."); 1623 STAM_REG(pVM, &pPGM->StatR0DynMapSubsets, STAMTYPE_COUNTER, "/PGM/R0/Subsets", STAMUNIT_OCCURENCES, "Times PGMDynMapPushAutoSubset was called."); 1624 STAM_REG(pVM, &pPGM->StatR0DynMapPopFlushes, STAMTYPE_COUNTER, "/PGM/R0/SubsetPopFlushes", STAMUNIT_OCCURENCES, "Times PGMDynMapPopAutoSubset flushes the subset."); 1622 1625 1623 1626 /* GC only: */ -
trunk/src/VBox/VMM/PGMInternal.h
r15410 r15411 1315 1315 typedef struct PGMMAPSET 1316 1316 { 1317 /** The index of the current CPU, only valid if the set is open. */ 1318 int32_t iCpu; 1319 /** The number of occupied. 1317 /** The number of occupied entries. 1320 1318 * This is PGMMAPSET_CLOSED if the set is closed and we're not supposed to do 1321 1319 * dynamic mappings. */ 1322 1320 uint32_t cEntries; 1321 /** The start of the current subset. 1322 * This is UINT32_MAX if no subset is currently open. */ 1323 uint32_t iSubset; 1324 /** The index of the current CPU, only valid if the set is open. */ 1325 int32_t iCpu; 1323 1326 /** The entries. */ 1324 1327 PGMMAPSETENTRY aEntries[32]; … … 1818 1821 1819 1822 #if defined(IN_RC) || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) 1820 DECLINLINE(void *) pgmPoolMapPageInlined(PVM pVM, PPGMPOOLPAGE pPage );1823 DECLINLINE(void *) pgmPoolMapPageInlined(PVM pVM, PPGMPOOLPAGE pPage, int iLine, const char *pszFile); 1821 1824 #endif 1822 1825 … … 1832 1835 * @remark There is no need to assert on the result. 1833 1836 */ 1834 #if defined(IN_RC) || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) 1835 # define PGMPOOL_PAGE_2_PTR(pVM, pPage) pgmPoolMapPageInlined(&(pVM)->pgm.s, (pPage)) 1837 #if defined(IN_RC) 1838 # define PGMPOOL_PAGE_2_PTR(pVM, pPage) pgmPoolMapPageInlined(&(pVM)->pgm.s, (pPage), __LINE__, 0) 1839 #elif defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) 1840 # define PGMPOOL_PAGE_2_PTR(pVM, pPage) pgmPoolMapPageInlined(&(pVM)->pgm.s, (pPage), __LINE__, __PRETTY_FUNCTION__) 1836 1841 #elif defined(VBOX_STRICT) 1837 1842 # define PGMPOOL_PAGE_2_PTR(pVM, pPage) pgmPoolMapPageStrict(pPage) … … 1856 1861 * @remark There is no need to assert on the result. 1857 1862 */ 1858 #if defined(IN_RC) || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) 1859 # define PGMPOOL_PAGE_2_PTR_BY_PGM(pPGM, pPage) pgmPoolMapPageInlined((pPGM), (pPage)) 1863 #if defined(IN_RC) 1864 # define PGMPOOL_PAGE_2_PTR_BY_PGM(pPGM, pPage) pgmPoolMapPageInlined((pPGM), (pPage), __LINE__, 0) 1865 #elif defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) 1866 # define PGMPOOL_PAGE_2_PTR_BY_PGM(pPGM, pPage) pgmPoolMapPageInlined((pPGM), (pPage), __LINE__, __PRETTY_FUNCTION__) 1860 1867 #else 1861 1868 # define PGMPOOL_PAGE_2_PTR_BY_PGM(pPGM, pPage) PGMPOOL_PAGE_2_PTR(PGM2VM(pPGM), pPage) … … 2660 2667 STAMPROFILE StatR0DynMapHCPage; /**< R0: Calls to PGMDynMapHCPage. */ 2661 2668 STAMCOUNTER StatR0DynMapSetOptimize; /**< R0: Calls to pgmDynMapOptimizeAutoSet. */ 2669 STAMCOUNTER StatR0DynMapSetSearchFlushes; /**< R0: Set search restorting to subset flushes. */ 2662 2670 STAMCOUNTER StatR0DynMapSetSearchHits; /**< R0: Set search hits. */ 2663 2671 STAMCOUNTER StatR0DynMapSetSearchMisses; /**< R0: Set search misses. */ … … 2671 2679 STAMCOUNTER StatR0DynMapPageSlowLoopMisses; /**< R0: Misses in the pgmR0DynMapPageSlow search loop. */ 2672 2680 //STAMCOUNTER StatR0DynMapPageSlowLostHits; /**< R0: Lost hits. */ 2681 STAMCOUNTER StatR0DynMapSubsets; /**< R0: Times PGMDynMapPushAutoSubset was called. */ 2682 STAMCOUNTER StatR0DynMapPopFlushes; /**< R0: Times PGMDynMapPopAutoSubset flushes the subset. */ 2673 2683 2674 2684 /* RC only: */ … … 4621 4631 * @param pPage The page. 4622 4632 */ 4623 DECLINLINE(void *) pgmPoolMapPageInlined(PPGM pPGM, PPGMPOOLPAGE pPage )4633 DECLINLINE(void *) pgmPoolMapPageInlined(PPGM pPGM, PPGMPOOLPAGE pPage, int iLine, const char *pszFile) 4624 4634 { 4625 4635 if (pPage->idx >= PGMPOOL_IDX_FIRST) … … 4634 4644 if (RT_SUCCESS(rc)) 4635 4645 return pv; 4646 AssertMsgFailed(("%Rrc: %s(%d)\n", rc, pszFile, iLine)); 4636 4647 } 4637 4648 return pgmPoolMapPageFallback(pPGM, pPage); -
trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp
r15410 r15411 3674 3674 } 3675 3675 3676 #ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0 3677 /* Start a subset so we won't run out of mapping space. */ 3678 PVMCPU pVCpu = VMMGetCpu(pPool->CTX_SUFF(pVM)); 3679 uint32_t iPrevSubset = PGMDynMapPushAutoSubset(pVCpu); 3680 #endif 3681 3676 3682 /* 3677 3683 * Nuke the free list and reinsert all pages into it. … … 3815 3821 } 3816 3822 3823 #ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0 3824 /* Pop the subset. */ 3825 PGMDynMapPopAutoSubset(pVCpu, iPrevSubset); 3826 #endif 3827 3817 3828 /* 3818 3829 * Finally, assert the FF. … … 3863 3874 } 3864 3875 3876 #ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0 3877 /* Start a subset so we won't run out of mapping space. */ 3878 PVMCPU pVCpu = VMMGetCpu(pPool->CTX_SUFF(pVM)); 3879 uint32_t iPrevSubset = PGMDynMapPushAutoSubset(pVCpu); 3880 #endif 3881 3865 3882 /* 3866 3883 * Mark the page as being in need of a ASMMemZeroPage(). … … 3884 3901 pgmPoolCacheFlushPage(pPool, pPage); 3885 3902 #endif /* PGMPOOL_WITH_CACHE */ 3903 3904 #ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0 3905 /* Heavy stuff done. */ 3906 PGMDynMapPopAutoSubset(pVCpu, iPrevSubset); 3907 #endif 3886 3908 3887 3909 #ifdef PGMPOOL_WITH_MONITORING -
trunk/src/VBox/VMM/VMMR0/PGMR0DynMap.cpp
r15402 r15411 367 367 } 368 368 pSet->cEntries = PGMMAPSET_CLOSED; 369 pSet->iSubset = UINT32_MAX; 369 370 pSet->iCpu = -1; 370 371 memset(&pSet->aiHashTable[0], 0xff, sizeof(pSet->aiHashTable)); … … 466 467 } 467 468 pSet->cEntries = PGMMAPSET_CLOSED; 469 pSet->iSubset = UINT32_MAX; 468 470 pSet->iCpu = -1; 469 471 } … … 1498 1500 { 1499 1501 Assert(pVCpu->pgm.s.AutoSet.cEntries == PGMMAPSET_CLOSED); 1502 Assert(pVCpu->pgm.s.AutoSet.iSubset == UINT32_MAX); 1500 1503 pVCpu->pgm.s.AutoSet.cEntries = 0; 1501 1504 pVCpu->pgm.s.AutoSet.iCpu = RTMpCpuIdToSetIndex(RTMpCpuId()); … … 1557 1560 AssertMsg(cEntries <= RT_ELEMENTS(pSet->aEntries), ("%#x (%u)\n", cEntries, cEntries)); 1558 1561 pSet->cEntries = PGMMAPSET_CLOSED; 1562 pSet->iSubset = UINT32_MAX; 1559 1563 pSet->iCpu = -1; 1560 1564 … … 1587 1591 } 1588 1592 } 1589 1590 1593 1591 1594 … … 1616 1619 { 1617 1620 PPGMR0DYNMAP pThis = g_pPGMR0DynMap; 1621 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; 1622 RTSpinlockAcquire(pThis->hSpinlock, &Tmp); 1623 1618 1624 while (i-- > 0) 1619 1625 { … … 1624 1630 { 1625 1631 RTCpuSetDelByIndex(&pThis->paPages[iPage].PendingSet, iRealCpu); 1632 RTSpinlockRelease(pThis->hSpinlock, &Tmp); 1633 1626 1634 ASMInvalidatePage(pThis->paPages[iPage].pvPage); 1627 1635 STAM_COUNTER_INC(&pVCpu->pVMR0->pgm.s.StatR0DynMapMigrateInvlPg); 1636 1637 RTSpinlockAcquire(pThis->hSpinlock, &Tmp); 1628 1638 } 1629 1639 } 1630 1640 1641 RTSpinlockRelease(pThis->hSpinlock, &Tmp); 1631 1642 } 1632 1643 } 1633 1644 pSet->iCpu = iRealCpu; 1634 1645 } 1646 } 1647 1648 1649 /** 1650 * Worker function that flushes the current subset. 1651 * 1652 * This is called when the set is popped or when the set 1653 * hash a too high load. As also pointed out elsewhere, the 1654 * whole subset thing is a hack for working around code that 1655 * accesses too many pages. Like PGMPool. 1656 * 1657 * @param pSet The set which subset to flush. 1658 */ 1659 static void pgmDynMapFlushSubset(PPGMMAPSET pSet) 1660 { 1661 uint32_t iSubset = pSet->iSubset; 1662 uint32_t i = pSet->cEntries; 1663 Assert(i <= RT_ELEMENTS(pSet->aEntries)); 1664 if ( i > iSubset 1665 && i <= RT_ELEMENTS(pSet->aEntries)) 1666 { 1667 pSet->cEntries = iSubset; 1668 1669 PPGMR0DYNMAP pThis = g_pPGMR0DynMap; 1670 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; 1671 RTSpinlockAcquire(pThis->hSpinlock, &Tmp); 1672 1673 while (i-- > iSubset) 1674 { 1675 uint32_t iPage = pSet->aEntries[i].iPage; 1676 Assert(iPage < pThis->cPages); 1677 int32_t cRefs = pSet->aEntries[i].cRefs; 1678 Assert(cRefs > 0); 1679 pgmR0DynMapReleasePageLocked(pThis, iPage, cRefs); 1680 1681 pSet->aEntries[i].iPage = UINT16_MAX; 1682 pSet->aEntries[i].cRefs = 0; 1683 } 1684 1685 RTSpinlockRelease(pThis->hSpinlock, &Tmp); 1686 } 1687 } 1688 1689 1690 /** 1691 * Creates a subset. 1692 * 1693 * A subset is a hack to avoid having to rewrite code that touches a lot of 1694 * pages. It prevents the mapping set from being overflowed by automatically 1695 * flushing previous mappings when a certain threshold is reached. 1696 * 1697 * Pages mapped after calling this function are only valid until the next page 1698 * is mapped. 1699 * 1700 * @returns The index of the previous subset. Pass this to 1701 * PGMDynMapPopAutoSubset when poping it. 1702 * @param pVCpu Pointer to the virtual cpu data. 1703 */ 1704 VMMDECL(uint32_t) PGMDynMapPushAutoSubset(PVMCPU pVCpu) 1705 { 1706 PPGMMAPSET pSet = &pVCpu->pgm.s.AutoSet; 1707 AssertReturn(pSet->cEntries != PGMMAPSET_CLOSED, UINT32_MAX); 1708 uint32_t iPrevSubset = pSet->iSubset; 1709 Assert(iPrevSubset == UINT32_MAX); 1710 pSet->iSubset = pSet->cEntries; 1711 STAM_COUNTER_INC(&pVCpu->pVMR0->pgm.s.StatR0DynMapSubsets); 1712 return iPrevSubset; 1713 } 1714 1715 1716 /** 1717 * Pops a subset created by a previous call to PGMDynMapPushAutoSubset. 1718 * 1719 * @param pVCpu Pointer to the virtual cpu data. 1720 * @param iPrevSubset What PGMDynMapPushAutoSubset returned. 1721 */ 1722 VMMDECL(void) PGMDynMapPopAutoSubset(PVMCPU pVCpu, uint32_t iPrevSubset) 1723 { 1724 PPGMMAPSET pSet = &pVCpu->pgm.s.AutoSet; 1725 AssertReturnVoid(pSet->cEntries != PGMMAPSET_CLOSED); 1726 AssertReturnVoid(pSet->iSubset <= iPrevSubset || iPrevSubset == UINT32_MAX); 1727 Assert(iPrevSubset == UINT32_MAX); 1728 if ( pSet->cEntries >= RT_ELEMENTS(pSet->aEntries) / 2 1729 && pSet->cEntries != pSet->iSubset) 1730 { 1731 STAM_COUNTER_INC(&pVCpu->pVMR0->pgm.s.StatR0DynMapPopFlushes); 1732 pgmDynMapFlushSubset(pSet); 1733 } 1734 pSet->iSubset = iPrevSubset; 1635 1735 } 1636 1736 … … 1774 1874 { 1775 1875 STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapSetSearchMisses); 1876 if (pSet->iSubset < pSet->cEntries) 1877 { 1878 STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapSetSearchFlushes); 1879 pgmDynMapFlushSubset(pSet); 1880 } 1881 1776 1882 if (RT_UNLIKELY(pSet->cEntries >= RT_ELEMENTS(pSet->aEntries))) 1777 1883 { … … 1779 1885 pgmDynMapOptimizeAutoSet(pSet); 1780 1886 } 1887 1781 1888 if (RT_LIKELY(pSet->cEntries < RT_ELEMENTS(pSet->aEntries))) 1782 1889 {
Note:
See TracChangeset
for help on using the changeset viewer.