/* * Trim down the number of pages in the quicklist */ void quicklist_trim(int nr, void (*dtor)(void *), unsigned long min_pages, unsigned long max_free) { long pages_to_free; struct quicklist *q; q = &get_cpu_var(quicklist)[nr]; if (q->nr_pages > min_pages) { pages_to_free = min_pages_to_free(q, min_pages, max_free); while (pages_to_free > 0) { /* * We pass a gfp_t of 0 to quicklist_alloc here * because we will never call into the page allocator. */ void *p = quicklist_alloc(nr, 0, NULL); if (dtor) dtor(p); free_page((unsigned long)p); pages_to_free--; } } put_cpu_var(quicklist); }
pgd_t *pgd_alloc(struct mm_struct *mm) { int i; pgd_t *pgd = quicklist_alloc(0, GFP_KERNEL, pgd_ctor); if (PTRS_PER_PMD == 1 || !pgd) return pgd; for (i = 0; i < UNSHARED_PTRS_PER_PGD; ++i) { pmd_t *pmd = pmd_cache_alloc(i); if (!pmd) goto out_oom; paravirt_alloc_pd(__pa(pmd) >> PAGE_SHIFT); set_pgd(&pgd[i], __pgd(1 + __pa(pmd))); } return pgd; out_oom: for (i--; i >= 0; i--) { pgd_t pgdent = pgd[i]; void* pmd = (void *)__va(pgd_val(pgdent)-1); paravirt_release_pd(__pa(pmd) >> PAGE_SHIFT); pmd_cache_free(pmd, i); } quicklist_free(0, pgd_dtor, pgd); return NULL; }
pgd_t *pgd_alloc(struct mm_struct *mm) { pgd_t *pgd; pgd = quicklist_alloc(0, GFP_KERNEL, pgd_ctor); if (!pgd) return pgd; return pgd; }
void quicklist_trim(int nr, void (*dtor)(void *), unsigned long min_pages, unsigned long max_free) { long pages_to_free; struct quicklist *q; q = &get_cpu_var(quicklist)[nr]; if (q->nr_pages > min_pages) { pages_to_free = min_pages_to_free(q, min_pages, max_free); while (pages_to_free > 0) { void *p = quicklist_alloc(nr, 0, NULL); if (dtor) dtor(p); free_page((unsigned long)p); pages_to_free--; } } put_cpu_var(quicklist); }
pgd_t *pgd_alloc(struct mm_struct *mm) { return quicklist_alloc(0, GFP_KERNEL, pgd_ctor); }