* We are in a serious low memory condition. Resort to * drastic measures to free some pages so we can allocate * another pv entry chunk. */
| 1435 | * another pv entry chunk. |
| 1436 | */ |
| 1437 | static vm_page_t |
| 1438 | pmap_pv_reclaim(pmap_t locked_pmap) |
| 1439 | { |
| 1440 | struct pch newtail; |
| 1441 | struct pv_chunk *pc; |
| 1442 | pd_entry_t *pde; |
| 1443 | pmap_t pmap; |
| 1444 | pt_entry_t *pte, oldpte; |
| 1445 | pv_entry_t pv; |
| 1446 | vm_offset_t va; |
| 1447 | vm_page_t m, m_pc; |
| 1448 | u_long inuse; |
| 1449 | int bit, field, freed, idx; |
| 1450 | |
| 1451 | PMAP_LOCK_ASSERT(locked_pmap, MA_OWNED); |
| 1452 | pmap = NULL; |
| 1453 | m_pc = NULL; |
| 1454 | TAILQ_INIT(&newtail); |
| 1455 | while ((pc = TAILQ_FIRST(&pv_chunks)) != NULL) { |
| 1456 | TAILQ_REMOVE(&pv_chunks, pc, pc_lru); |
| 1457 | if (pmap != pc->pc_pmap) { |
| 1458 | if (pmap != NULL) { |
| 1459 | pmap_invalidate_all(pmap); |
| 1460 | if (pmap != locked_pmap) |
| 1461 | PMAP_UNLOCK(pmap); |
| 1462 | } |
| 1463 | pmap = pc->pc_pmap; |
| 1464 | /* Avoid deadlock and lock recursion. */ |
| 1465 | if (pmap > locked_pmap) |
| 1466 | PMAP_LOCK(pmap); |
| 1467 | else if (pmap != locked_pmap && !PMAP_TRYLOCK(pmap)) { |
| 1468 | pmap = NULL; |
| 1469 | TAILQ_INSERT_TAIL(&newtail, pc, pc_lru); |
| 1470 | continue; |
| 1471 | } |
| 1472 | } |
| 1473 | |
| 1474 | /* |
| 1475 | * Destroy every non-wired, 4 KB page mapping in the chunk. |
| 1476 | */ |
| 1477 | freed = 0; |
| 1478 | for (field = 0; field < _NPCM; field++) { |
| 1479 | for (inuse = ~pc->pc_map[field] & pc_freemask[field]; |
| 1480 | inuse != 0; inuse &= ~(1UL << bit)) { |
| 1481 | bit = ffsl(inuse) - 1; |
| 1482 | idx = field * sizeof(inuse) * NBBY + bit; |
| 1483 | pv = &pc->pc_pventry[idx]; |
| 1484 | va = pv->pv_va; |
| 1485 | pde = pmap_pde(pmap, va); |
| 1486 | KASSERT(pde != NULL && *pde != 0, |
| 1487 | ("pmap_pv_reclaim: pde")); |
| 1488 | pte = pmap_pde_to_pte(pde, va); |
| 1489 | oldpte = *pte; |
| 1490 | if (pte_test(&oldpte, PTE_W)) |
| 1491 | continue; |
| 1492 | if (is_kernel_pmap(pmap)) |
| 1493 | *pte = PTE_G; |
| 1494 | else |
no test coverage detected