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

Function get_pv_entry

freebsd/amd64/amd64/pmap.c:5211–5275  ·  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

5209 * The given PV list lock may be released.
5210 */
5211static pv_entry_t
5212get_pv_entry(pmap_t pmap, struct rwlock **lockp)
5213{
5214 struct pv_chunks_list *pvc;
5215 int bit, field;
5216 pv_entry_t pv;
5217 struct pv_chunk *pc;
5218 vm_page_t m;
5219
5220 PMAP_LOCK_ASSERT(pmap, MA_OWNED);
5221 PV_STAT(atomic_add_long(&pv_entry_allocs, 1));
5222retry:
5223 pc = TAILQ_FIRST(&pmap->pm_pvchunk);
5224 if (pc != NULL) {
5225 for (field = 0; field < _NPCM; field++) {
5226 if (pc->pc_map[field]) {
5227 bit = bsfq(pc->pc_map[field]);
5228 break;
5229 }
5230 }
5231 if (field < _NPCM) {
5232 pv = &pc->pc_pventry[field * 64 + bit];
5233 pc->pc_map[field] &= ~(1ul << bit);
5234 /* If this was the last item, move it to tail */
5235 if (pc->pc_map[0] == 0 && pc->pc_map[1] == 0 &&
5236 pc->pc_map[2] == 0) {
5237 TAILQ_REMOVE(&pmap->pm_pvchunk, pc, pc_list);
5238 TAILQ_INSERT_TAIL(&pmap->pm_pvchunk, pc,
5239 pc_list);
5240 }
5241 PV_STAT(atomic_add_long(&pv_entry_count, 1));
5242 PV_STAT(atomic_subtract_int(&pv_entry_spare, 1));
5243 return (pv);
5244 }
5245 }
5246 /* No free items, allocate another chunk */
5247 m = vm_page_alloc(NULL, 0, VM_ALLOC_NORMAL | VM_ALLOC_NOOBJ |
5248 VM_ALLOC_WIRED);
5249 if (m == NULL) {
5250 if (lockp == NULL) {
5251 PV_STAT(pc_chunk_tryfail++);
5252 return (NULL);
5253 }
5254 m = reclaim_pv_chunk(pmap, lockp);
5255 if (m == NULL)
5256 goto retry;
5257 }
5258 PV_STAT(atomic_add_int(&pc_chunk_count, 1));
5259 PV_STAT(atomic_add_int(&pc_chunk_allocs, 1));
5260 dump_add_page(m->phys_addr);
5261 pc = (void *)PHYS_TO_DMAP(m->phys_addr);
5262 pc->pc_pmap = pmap;
5263 pc->pc_map[0] = PC_FREE0 & ~1ul; /* preallocated bit 0 */
5264 pc->pc_map[1] = PC_FREE1;
5265 pc->pc_map[2] = PC_FREE2;
5266 pvc = &pv_chunks[vm_page_domain(m)];
5267 mtx_lock(&pvc->pvc_lock);
5268 TAILQ_INSERT_TAIL(&pvc->pvc_list, pc, pc_lru);

Callers 3

pmap_try_insert_pv_entryFunction · 0.70
pmap_pv_insert_pdeFunction · 0.70
pmap_enterFunction · 0.70

Calls 7

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

Tested by

no test coverage detected