aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-x86_64/pgalloc.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-x86_64/pgalloc.h')
-rw-r--r--include/asm-x86_64/pgalloc.h28
1 files changed, 28 insertions, 0 deletions
diff --git a/include/asm-x86_64/pgalloc.h b/include/asm-x86_64/pgalloc.h
index 08cad2482bcb..43d4c333a8b1 100644
--- a/include/asm-x86_64/pgalloc.h
+++ b/include/asm-x86_64/pgalloc.h
@@ -45,12 +45,39 @@ static inline void pud_free (pud_t *pud)
45 free_page((unsigned long)pud); 45 free_page((unsigned long)pud);
46} 46}
47 47
48static inline void pgd_list_add(pgd_t *pgd)
49{
50 struct page *page = virt_to_page(pgd);
51
52 spin_lock(&pgd_lock);
53 page->index = (pgoff_t)pgd_list;
54 if (pgd_list)
55 pgd_list->private = (unsigned long)&page->index;
56 pgd_list = page;
57 page->private = (unsigned long)&pgd_list;
58 spin_unlock(&pgd_lock);
59}
60
61static inline void pgd_list_del(pgd_t *pgd)
62{
63 struct page *next, **pprev, *page = virt_to_page(pgd);
64
65 spin_lock(&pgd_lock);
66 next = (struct page *)page->index;
67 pprev = (struct page **)page->private;
68 *pprev = next;
69 if (next)
70 next->private = (unsigned long)pprev;
71 spin_unlock(&pgd_lock);
72}
73
48static inline pgd_t *pgd_alloc(struct mm_struct *mm) 74static inline pgd_t *pgd_alloc(struct mm_struct *mm)
49{ 75{
50 unsigned boundary; 76 unsigned boundary;
51 pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); 77 pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
52 if (!pgd) 78 if (!pgd)
53 return NULL; 79 return NULL;
80 pgd_list_add(pgd);
54 /* 81 /*
55 * Copy kernel pointers in from init. 82 * Copy kernel pointers in from init.
56 * Could keep a freelist or slab cache of those because the kernel 83 * Could keep a freelist or slab cache of those because the kernel
@@ -67,6 +94,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
67static inline void pgd_free(pgd_t *pgd) 94static inline void pgd_free(pgd_t *pgd)
68{ 95{
69 BUG_ON((unsigned long)pgd & (PAGE_SIZE-1)); 96 BUG_ON((unsigned long)pgd & (PAGE_SIZE-1));
97 pgd_list_del(pgd);
70 free_page((unsigned long)pgd); 98 free_page((unsigned long)pgd);
71} 99}
72 100