diff options
Diffstat (limited to 'linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgalloc.h')
-rw-r--r-- | linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgalloc.h | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgalloc.h b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgalloc.h index 6a7f8de3ff..61cf7ec389 100644 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgalloc.h +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgalloc.h @@ -102,6 +102,32 @@ static inline void pud_free(pud_t *pud) free_page((unsigned long)pud); } +static inline void pgd_list_add(pgd_t *pgd) +{ + struct page *page = virt_to_page(pgd); + + spin_lock(&pgd_lock); + page->index = (pgoff_t)pgd_list; + if (pgd_list) + pgd_list->private = (unsigned long)&page->index; + pgd_list = page; + page->private = (unsigned long)&pgd_list; + spin_unlock(&pgd_lock); +} + +static inline void pgd_list_del(pgd_t *pgd) +{ + struct page *next, **pprev, *page = virt_to_page(pgd); + + spin_lock(&pgd_lock); + next = (struct page *)page->index; + pprev = (struct page **)page->private; + *pprev = next; + if (next) + next->private = (unsigned long)pprev; + spin_unlock(&pgd_lock); +} + static inline pgd_t *pgd_alloc(struct mm_struct *mm) { /* @@ -109,9 +135,9 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm) */ unsigned boundary; pgd_t *pgd = (pgd_t *)__get_free_pages(GFP_KERNEL|__GFP_REPEAT, 1); - if (!pgd) return NULL; + pgd_list_add(pgd); /* * Copy kernel pointers in from init. * Could keep a freelist or slab cache of those because the kernel @@ -155,6 +181,7 @@ static inline void pgd_free(pgd_t *pgd) 0)); } + pgd_list_del(pgd); free_pages((unsigned long)pgd, 1); } |