Changeset 14850 in vbox
- Timestamp:
- Dec 1, 2008 11:16:13 AM (16 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/PGM.cpp
r14755 r14850 1595 1595 STAM_REG(pVM, &pPGM->StatR3DynRamTotal, STAMTYPE_COUNTER, "/PGM/DynAlloc/TotalAlloc", STAMUNIT_MEGABYTES, "Allocated MBs of guest ram."); 1596 1596 STAM_REG(pVM, &pPGM->StatR3DynRamGrow, STAMTYPE_COUNTER, "/PGM/DynAlloc/Grow", STAMUNIT_OCCURENCES, "Nr of pgmr3PhysGrowRange calls."); 1597 1598 /* R0 only: */ 1599 STAM_REG(pVM, &pPGM->StatR0DynMapPage, STAMTYPE_COUNTER, "/PGM/R0/DynMapPage" , STAMUNIT_OCCURENCES, "Calls to pgmR0DynMapPage"); 1600 STAM_REG(pVM, &pPGM->StatR0DynMapPageSlow, STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/Slow" , STAMUNIT_OCCURENCES, "Calls to pgmR0DynMapPageSlow - subtract this from pgmR0DynMapPage to get 1st level hits."); 1601 STAM_REG(pVM, &pPGM->StatR0DynMapPageSlowLoopHits, STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/SlowLoopHits" , STAMUNIT_OCCURENCES, "Hits in the loop path."); 1602 STAM_REG(pVM, &pPGM->StatR0DynMapPageSlowLoopMisses, STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/SlowLoopMisses", STAMUNIT_OCCURENCES, "Misses in the loop path. NonLoopMisses = Slow - SlowLoopHit - SlowLoopMisses"); 1603 STAM_REG(pVM, &pPGM->StatR0DynMapHCPage, STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/HCPage", STAMUNIT_OCCURENCES, "Calls to PGMDynMapHCPage (ring-0)."); 1604 STAM_REG(pVM, &pPGM->StatR0DynMapHCPageSetOptimize, STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/HCPageSetOptimize", STAMUNIT_OCCURENCES, "Calls to pgmDynMapOptimizeAutoSet."); 1605 STAM_REG(pVM, &pPGM->StatR0DynMapHCPageSetSearchHits, STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/HCPageSetSearchHits", STAMUNIT_OCCURENCES, "Set search hits."); 1606 STAM_REG(pVM, &pPGM->StatR0DynMapHCPageSetSearchMisses, STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/HCPageSetSearchMisses", STAMUNIT_OCCURENCES, "Set search misses."); 1597 1607 1598 1608 /* GC only: */ -
trunk/src/VBox/VMM/PGMInternal.h
r14755 r14850 2560 2560 STAMCOUNTER StatR3DynRamGrow; /**< R3: Nr of pgmr3PhysGrowRange calls. */ 2561 2561 2562 /* R0 only: */ 2563 STAMCOUNTER StatR0DynMapPage; /**< R0: Calls to pgmR0DynMapPage. */ 2564 STAMCOUNTER StatR0DynMapPageSlow; /**< R0: Calls to pgmR0DynMapPageSlow. */ 2565 STAMCOUNTER StatR0DynMapPageSlowLoopHits; /**< R0: Hits in the pgmR0DynMapPageSlow search loop. */ 2566 STAMCOUNTER StatR0DynMapPageSlowLoopMisses; /**< R0: Misses in the pgmR0DynMapPageSlow search loop. */ 2567 STAMCOUNTER StatR0DynMapHCPage; /**< R0: Calls to PGMDynMapHCPage. */ 2568 STAMCOUNTER StatR0DynMapHCPageSetOptimize; /**< R0: Calls to pgmDynMapOptimizeAutoSet. */ 2569 STAMCOUNTER StatR0DynMapHCPageSetSearchHits; /**< R0: Set search hits. */ 2570 STAMCOUNTER StatR0DynMapHCPageSetSearchMisses; /**< R0: Set search misses. */ 2571 2562 2572 /* RC only: */ 2563 2573 STAMCOUNTER StatRCDynMapCacheMisses; /**< RC: The number of dynamic page mapping cache hits */ -
trunk/src/VBox/VMM/VMMR0/PGMR0DynMap.cpp
r14826 r14850 1166 1166 * @param HCPhys The address of the page to be mapped. 1167 1167 * @param iPage The page index pgmR0DynMapPage hashed HCPhys to. 1168 */ 1169 static uint32_t pgmR0DynMapPageSlow(PPGMR0DYNMAP pThis, RTHCPHYS HCPhys, uint32_t iPage) 1170 { 1168 * @param pVM The shared VM structure, for statistics only. 1169 */ 1170 static uint32_t pgmR0DynMapPageSlow(PPGMR0DYNMAP pThis, RTHCPHYS HCPhys, uint32_t iPage, PVM pVM) 1171 { 1172 STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapPageSlow); 1173 1171 1174 /* 1172 1175 * Check if any of the first 5 pages are unreferenced since the caller … … 1195 1198 { 1196 1199 if (paPages[iFreePage].HCPhys == HCPhys) 1200 { 1201 STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapPageSlowLoopHits); 1197 1202 return iFreePage; 1203 } 1198 1204 if (!paPages[iFreePage].cRefs) 1199 1205 break; … … 1204 1210 return UINT32_MAX; 1205 1211 } 1212 STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapPageSlowLoopMisses); 1206 1213 } 1207 1214 Assert(iFreePage < cPages); … … 1246 1253 * @param pThis The dynamic mapping cache instance. 1247 1254 * @param HCPhys The address of the page to be mapped. 1248 * @param ppvPage Where to the page address. 1249 */ 1250 DECLINLINE(uint32_t) pgmR0DynMapPage(PPGMR0DYNMAP pThis, RTHCPHYS HCPhys, void **ppvPage) 1255 * @param pVM The shared VM structure, for statistics only. 1256 * @param ppvPage Where to the page address. 1257 */ 1258 DECLINLINE(uint32_t) pgmR0DynMapPage(PPGMR0DYNMAP pThis, RTHCPHYS HCPhys, PVM pVM, void **ppvPage) 1251 1259 { 1252 1260 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; 1253 1261 RTSpinlockAcquire(pThis->hSpinlock, &Tmp); 1254 1262 AssertMsg(!(HCPhys & PAGE_OFFSET_MASK), ("HCPhys=%RHp\n", HCPhys)); 1263 STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapPage); 1255 1264 1256 1265 /* … … 1279 1288 if (paPages[iPage2].HCPhys != HCPhys) 1280 1289 { 1281 iPage = pgmR0DynMapPageSlow(pThis, HCPhys, iPage );1290 iPage = pgmR0DynMapPageSlow(pThis, HCPhys, iPage, pVM); 1282 1291 if (RT_UNLIKELY(iPage == UINT32_MAX)) 1283 1292 { … … 1620 1629 * Validate state. 1621 1630 */ 1631 STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapHCPage); 1622 1632 AssertPtr(ppv); 1623 1633 *ppv = NULL; … … 1635 1645 * Map it. 1636 1646 */ 1637 uint32_t const iPage = pgmR0DynMapPage(g_pPGMR0DynMap, HCPhys, p pv);1647 uint32_t const iPage = pgmR0DynMapPage(g_pPGMR0DynMap, HCPhys, pVM, ppv); 1638 1648 if (RT_UNLIKELY(iPage == UINT32_MAX)) 1639 1649 { … … 1647 1657 /* 1648 1658 * Add the page to the auto reference set. 1649 * If it's less than half full, don't bother looking for duplicates. 1650 */ 1651 if (pSet->cEntries < RT_ELEMENTS(pSet->aEntries) / 2) 1659 * 1660 * The typical usage pattern means that the same pages will be mapped 1661 * several times in the same set. We can catch most of these 1662 * remappings by looking a few pages back into the set. (The searching 1663 * and set optimizing path will hardly ever be used when doing this.) 1664 */ 1665 AssertCompile(RT_ELEMENTS(pSet->aEntries) >= 8); 1666 int32_t i = pSet->cEntries; 1667 if (i-- < 5) 1652 1668 { 1653 1669 pSet->aEntries[pSet->cEntries].cRefs = 1; … … 1655 1671 pSet->cEntries++; 1656 1672 } 1673 /* Any of the last 5 pages? */ 1674 else if ( pSet->aEntries[i - 0].iPage == iPage 1675 && pSet->aEntries[i - 0].cRefs < UINT16_MAX - 1) 1676 pSet->aEntries[i - 0].cRefs++; 1677 else if ( pSet->aEntries[i - 1].iPage == iPage 1678 && pSet->aEntries[i - 1].cRefs < UINT16_MAX - 1) 1679 pSet->aEntries[i - 1].cRefs++; 1680 else if ( pSet->aEntries[i - 2].iPage == iPage 1681 && pSet->aEntries[i - 2].cRefs < UINT16_MAX - 1) 1682 pSet->aEntries[i - 2].cRefs++; 1683 else if ( pSet->aEntries[i - 3].iPage == iPage 1684 && pSet->aEntries[i - 3].cRefs < UINT16_MAX - 1) 1685 pSet->aEntries[i - 3].cRefs++; 1686 else if ( pSet->aEntries[i - 4].iPage == iPage 1687 && pSet->aEntries[i - 4].cRefs < UINT16_MAX - 1) 1688 pSet->aEntries[i - 4].cRefs++; 1689 /* Don't bother searching unless we're above a 75% load. */ 1690 else if (i <= (int32_t)RT_ELEMENTS(pSet->aEntries) / 4 * 3) 1691 { 1692 pSet->aEntries[pSet->cEntries].cRefs = 1; 1693 pSet->aEntries[pSet->cEntries].iPage = iPage; 1694 pSet->cEntries++; 1695 } 1657 1696 else 1658 1697 { 1698 /* Search the rest of the set. */ 1659 1699 Assert(pSet->cEntries <= RT_ELEMENTS(pSet->aEntries)); 1660 i nt32_t i = pSet->cEntries;1700 i -= 4; 1661 1701 while (i-- > 0) 1662 1702 if ( pSet->aEntries[i].iPage == iPage … … 1664 1704 { 1665 1705 pSet->aEntries[i].cRefs++; 1706 STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapHCPageSetSearchHits); 1666 1707 break; 1667 1708 } 1668 1709 if (i < 0) 1669 1710 { 1711 STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapHCPageSetSearchMisses); 1670 1712 if (RT_UNLIKELY(pSet->cEntries >= RT_ELEMENTS(pSet->aEntries))) 1713 { 1714 STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapHCPageSetOptimize); 1671 1715 pgmDynMapOptimizeAutoSet(pSet); 1716 } 1672 1717 if (RT_LIKELY(pSet->cEntries < RT_ELEMENTS(pSet->aEntries))) 1673 1718 { … … 1770 1815 LogRel(("Test #2\n")); 1771 1816 ASMIntDisable(); 1772 for (i = 0 ; i < UINT16_MAX*2 + RT_ELEMENTS(pSet->aEntries) / 2&& RT_SUCCESS(rc) && pv2 == pv; i++)1817 for (i = 0 ; i < UINT16_MAX*2 - 1 && RT_SUCCESS(rc) && pv2 == pv; i++) 1773 1818 { 1774 1819 pv2 = (void *)(intptr_t)-4; … … 1781 1826 if (RT_SUCCESS(rc)) rc = VERR_INTERNAL_ERROR; 1782 1827 } 1783 else if (pSet->cEntries != RT_ELEMENTS(pSet->aEntries) / 2)1828 else if (pSet->cEntries != 5) 1784 1829 { 1785 1830 LogRel(("failed(%d): cEntries=%d expected %d\n", __LINE__, pSet->cEntries, RT_ELEMENTS(pSet->aEntries) / 2)); 1786 1831 rc = VERR_INTERNAL_ERROR; 1787 1832 } 1788 else if ( pSet->aEntries[(RT_ELEMENTS(pSet->aEntries) / 2) - 1].cRefs != UINT16_MAX - 1 1789 || pSet->aEntries[(RT_ELEMENTS(pSet->aEntries) / 2) - 2].cRefs != UINT16_MAX - 1 1790 || pSet->aEntries[(RT_ELEMENTS(pSet->aEntries) / 2) - 3].cRefs != 2+2+3 1791 || pSet->aEntries[(RT_ELEMENTS(pSet->aEntries) / 2) - 4].cRefs != 1) 1833 else if ( pSet->aEntries[4].cRefs != UINT16_MAX - 1 1834 || pSet->aEntries[3].cRefs != UINT16_MAX - 1 1835 || pSet->aEntries[2].cRefs != 1 1836 || pSet->aEntries[1].cRefs != 1 1837 || pSet->aEntries[0].cRefs != 1) 1792 1838 { 1793 1839 LogRel(("failed(%d): bad set dist: ", __LINE__)); … … 1807 1853 ASMIntDisable(); 1808 1854 pv2 = NULL; 1809 for (i = 0 ; i < RT_ELEMENTS(pSet->aEntries) / 2&& RT_SUCCESS(rc) && pv2 != pv; i++)1855 for (i = 0 ; i < RT_ELEMENTS(pSet->aEntries) - 5 && RT_SUCCESS(rc) && pv2 != pv; i++) 1810 1856 { 1811 1857 pv2 = (void *)(intptr_t)(-5 - i); … … 1833 1879 LogRel(("Test #4\n")); 1834 1880 ASMIntDisable(); 1835 for (i = 0 ; i < RT_ELEMENTS(pSet->aEntries) / 2 - 3 + 1 && pv2 != pv; i++)1881 for (i = 0 ; i < RT_ELEMENTS(pSet->aEntries) + 2; i++) 1836 1882 { 1837 1883 rc = PGMDynMapHCPage(pVM, cr3 - PAGE_SIZE * (i + 5), &pv2);
Note:
See TracChangeset
for help on using the changeset viewer.