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

Function reclaim_pv_chunk

freebsd/arm64/arm64/pmap.c:2289–2467  ·  view source on GitHub ↗

* We are in a serious low memory condition. Resort to * drastic measures to free some pages so we can allocate * another pv entry chunk. * * Returns NULL if PV entries were reclaimed from the specified pmap. * * We do not, however, unmap 2mpages because subsequent accesses will * allocate per-page pv entries until repromotion occurs, thereby * exacerbating the shortage of free pv entries.

Source from the content-addressed store, hash-verified

2287 * exacerbating the shortage of free pv entries.
2288 */
2289static vm_page_t
2290reclaim_pv_chunk(pmap_t locked_pmap, struct rwlock **lockp)
2291{
2292 struct pv_chunk *pc, *pc_marker, *pc_marker_end;
2293 struct pv_chunk_header pc_marker_b, pc_marker_end_b;
2294 struct md_page *pvh;
2295 pd_entry_t *pde;
2296 pmap_t next_pmap, pmap;
2297 pt_entry_t *pte, tpte;
2298 pv_entry_t pv;
2299 vm_offset_t va;
2300 vm_page_t m, m_pc;
2301 struct spglist free;
2302 uint64_t inuse;
2303 int bit, field, freed, lvl;
2304 static int active_reclaims = 0;
2305
2306 PMAP_LOCK_ASSERT(locked_pmap, MA_OWNED);
2307 KASSERT(lockp != NULL, ("reclaim_pv_chunk: lockp is NULL"));
2308
2309 pmap = NULL;
2310 m_pc = NULL;
2311 SLIST_INIT(&free);
2312 bzero(&pc_marker_b, sizeof(pc_marker_b));
2313 bzero(&pc_marker_end_b, sizeof(pc_marker_end_b));
2314 pc_marker = (struct pv_chunk *)&pc_marker_b;
2315 pc_marker_end = (struct pv_chunk *)&pc_marker_end_b;
2316
2317 mtx_lock(&pv_chunks_mutex);
2318 active_reclaims++;
2319 TAILQ_INSERT_HEAD(&pv_chunks, pc_marker, pc_lru);
2320 TAILQ_INSERT_TAIL(&pv_chunks, pc_marker_end, pc_lru);
2321 while ((pc = TAILQ_NEXT(pc_marker, pc_lru)) != pc_marker_end &&
2322 SLIST_EMPTY(&free)) {
2323 next_pmap = pc->pc_pmap;
2324 if (next_pmap == NULL) {
2325 /*
2326 * The next chunk is a marker. However, it is
2327 * not our marker, so active_reclaims must be
2328 * > 1. Consequently, the next_chunk code
2329 * will not rotate the pv_chunks list.
2330 */
2331 goto next_chunk;
2332 }
2333 mtx_unlock(&pv_chunks_mutex);
2334
2335 /*
2336 * A pv_chunk can only be removed from the pc_lru list
2337 * when both pv_chunks_mutex is owned and the
2338 * corresponding pmap is locked.
2339 */
2340 if (pmap != next_pmap) {
2341 if (pmap != NULL && pmap != locked_pmap)
2342 PMAP_UNLOCK(pmap);
2343 pmap = next_pmap;
2344 /* Avoid deadlock and lock recursion. */
2345 if (pmap > locked_pmap) {
2346 RELEASE_PV_LIST_LOCK(lockp);

Callers 2

get_pv_entryFunction · 0.70
reserve_pv_entriesFunction · 0.70

Calls 15

bzeroFunction · 0.85
pmap_l2_to_l3Function · 0.85
PHYS_TO_VM_PAGEFunction · 0.85
pmap_pte_dirtyFunction · 0.85
vm_page_dirtyFunction · 0.85
vm_page_aflag_setFunction · 0.85
page_to_pvhFunction · 0.85
vm_page_aflag_clearFunction · 0.85
atomic_add_longFunction · 0.85
atomic_subtract_longFunction · 0.85
dump_drop_pageFunction · 0.85
vm_page_free_pages_toqFunction · 0.85

Tested by

no test coverage detected