void pte_fragment_free(unsigned long *table, int kernel) { struct page *page = virt_to_page(table); if (put_page_testzero(page)) { if (!kernel) pgtable_page_dtor(page); free_hot_cold_page(page, 0); } }
void __homecache_free_pages(struct page *page, unsigned int order) { if (put_page_testzero(page)) { homecache_change_page_home(page, order, PAGE_HOME_HASH); if (order == 0) { free_hot_cold_page(page, false); } else { init_page_count(page); __free_pages(page, order); } } }
/* * This path almost never happens for VM activity - pages are normally * freed via pagevecs. But it gets used by networking. */ static void __page_cache_release(struct page *page) { if (PageLRU(page)) { unsigned long flags; struct zone *zone = page_zone(page); spin_lock_irqsave(&zone->lru_lock, flags); VM_BUG_ON(!PageLRU(page)); __ClearPageLRU(page); del_page_from_lru(zone, page); spin_unlock_irqrestore(&zone->lru_lock, flags); } free_hot_cold_page(page, 0); }
static void destroy_pagetable_page(struct mm_struct *mm) { int count; void *pte_frag; struct page *page; pte_frag = mm->context.pte_frag; if (!pte_frag) return; page = virt_to_page(pte_frag); /* drop all the pending references */ count = ((unsigned long)pte_frag & ~PAGE_MASK) >> PTE_FRAG_SIZE_SHIFT; /* We allow PTE_FRAG_NR fragments from a PTE page */ if (page_ref_sub_and_test(page, PTE_FRAG_NR - count)) { pgtable_page_dtor(page); free_hot_cold_page(page, 0); } }
static void __put_single_page(struct page *page) { __page_cache_release(page); free_hot_cold_page(page, 0); }