MCPcopy Create free account
hub / github.com/F-Stack/f-stack / get_pv_entry

Function get_pv_entry

freebsd/arm64/arm64/pmap.c:2526–2588  ·  view source on GitHub ↗

* Returns a new PV entry, allocating a new PV chunk from the system when * needed. If this PV chunk allocation fails and a PV list lock pointer was * given, a PV chunk is reclaimed from an arbitrary pmap. Otherwise, NULL is * returned. * * The given PV list lock may be released. */

Source from the content-addressed store, hash-verified

2524 * The given PV list lock may be released.
2525 */
2526static pv_entry_t
2527get_pv_entry(pmap_t pmap, struct rwlock **lockp)
2528{
2529 int bit, field;
2530 pv_entry_t pv;
2531 struct pv_chunk *pc;
2532 vm_page_t m;
2533
2534 PMAP_LOCK_ASSERT(pmap, MA_OWNED);
2535 PV_STAT(atomic_add_long(&pv_entry_allocs, 1));
2536retry:
2537 pc = TAILQ_FIRST(&pmap->pm_pvchunk);
2538 if (pc != NULL) {
2539 for (field = 0; field < _NPCM; field++) {
2540 if (pc->pc_map[field]) {
2541 bit = ffsl(pc->pc_map[field]) - 1;
2542 break;
2543 }
2544 }
2545 if (field < _NPCM) {
2546 pv = &pc->pc_pventry[field * 64 + bit];
2547 pc->pc_map[field] &= ~(1ul << bit);
2548 /* If this was the last item, move it to tail */
2549 if (pc->pc_map[0] == 0 && pc->pc_map[1] == 0 &&
2550 pc->pc_map[2] == 0) {
2551 TAILQ_REMOVE(&pmap->pm_pvchunk, pc, pc_list);
2552 TAILQ_INSERT_TAIL(&pmap->pm_pvchunk, pc,
2553 pc_list);
2554 }
2555 PV_STAT(atomic_add_long(&pv_entry_count, 1));
2556 PV_STAT(atomic_subtract_int(&pv_entry_spare, 1));
2557 return (pv);
2558 }
2559 }
2560 /* No free items, allocate another chunk */
2561 m = vm_page_alloc(NULL, 0, VM_ALLOC_NORMAL | VM_ALLOC_NOOBJ |
2562 VM_ALLOC_WIRED);
2563 if (m == NULL) {
2564 if (lockp == NULL) {
2565 PV_STAT(pc_chunk_tryfail++);
2566 return (NULL);
2567 }
2568 m = reclaim_pv_chunk(pmap, lockp);
2569 if (m == NULL)
2570 goto retry;
2571 }
2572 PV_STAT(atomic_add_int(&pc_chunk_count, 1));
2573 PV_STAT(atomic_add_int(&pc_chunk_allocs, 1));
2574 dump_add_page(m->phys_addr);
2575 pc = (void *)PHYS_TO_DMAP(m->phys_addr);
2576 pc->pc_pmap = pmap;
2577 pc->pc_map[0] = PC_FREE0 & ~1ul; /* preallocated bit 0 */
2578 pc->pc_map[1] = PC_FREE1;
2579 pc->pc_map[2] = PC_FREE2;
2580 mtx_lock(&pv_chunks_mutex);
2581 TAILQ_INSERT_TAIL(&pv_chunks, pc, pc_lru);
2582 mtx_unlock(&pv_chunks_mutex);
2583 pv = &pc->pc_pventry[0];

Callers 3

pmap_try_insert_pv_entryFunction · 0.70
pmap_pv_insert_l2Function · 0.70
pmap_enterFunction · 0.70

Calls 7

atomic_add_longFunction · 0.85
vm_page_allocFunction · 0.85
dump_add_pageFunction · 0.85
reclaim_pv_chunkFunction · 0.70
ffslFunction · 0.50
mtx_lockFunction · 0.50
mtx_unlockFunction · 0.50

Tested by

no test coverage detected