pgalloc.h 2.2 KB
Newer Older
H
Haavard Skinnemoen 已提交
1 2 3 4 5 6 7 8 9 10
/*
 * Copyright (C) 2004-2006 Atmel Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#ifndef __ASM_AVR32_PGALLOC_H
#define __ASM_AVR32_PGALLOC_H

11 12 13 14 15
#include <linux/quicklist.h>
#include <asm/page.h>
#include <asm/pgtable.h>

#define QUICK_PGD	0	/* Preserve kernel mappings over free */
16
#define QUICK_PT	1	/* Zero on free */
H
Haavard Skinnemoen 已提交
17

18 19 20 21 22
static inline void pmd_populate_kernel(struct mm_struct *mm,
				       pmd_t *pmd, pte_t *pte)
{
	set_pmd(pmd, __pmd((unsigned long)pte));
}
H
Haavard Skinnemoen 已提交
23

24
static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
25
				    pgtable_t pte)
H
Haavard Skinnemoen 已提交
26
{
27
	set_pmd(pmd, __pmd((unsigned long)page_address(pte)));
H
Haavard Skinnemoen 已提交
28
}
29
#define pmd_pgtable(pmd) pmd_page(pmd)
H
Haavard Skinnemoen 已提交
30

31 32 33 34 35 36 37 38 39
static inline void pgd_ctor(void *x)
{
	pgd_t *pgd = x;

	memcpy(pgd + USER_PTRS_PER_PGD,
		swapper_pg_dir + USER_PTRS_PER_PGD,
		(PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
}

H
Haavard Skinnemoen 已提交
40 41 42
/*
 * Allocate and free page tables
 */
43
static inline pgd_t *pgd_alloc(struct mm_struct *mm)
H
Haavard Skinnemoen 已提交
44
{
45
	return quicklist_alloc(QUICK_PGD, GFP_KERNEL | __GFP_REPEAT, pgd_ctor);
H
Haavard Skinnemoen 已提交
46 47
}

48
static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
H
Haavard Skinnemoen 已提交
49
{
50
	quicklist_free(QUICK_PGD, NULL, pgd);
H
Haavard Skinnemoen 已提交
51 52 53 54 55
}

static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
					  unsigned long address)
{
56
	return quicklist_alloc(QUICK_PT, GFP_KERNEL | __GFP_REPEAT, NULL);
H
Haavard Skinnemoen 已提交
57 58
}

59
static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
H
Haavard Skinnemoen 已提交
60 61
					 unsigned long address)
{
62 63
	struct page *page;
	void *pg;
H
Haavard Skinnemoen 已提交
64

65 66
	pg = quicklist_alloc(QUICK_PT, GFP_KERNEL | __GFP_REPEAT, NULL);
	if (!pg)
67
		return NULL;
68 69 70 71 72

	page = virt_to_page(pg);
	pgtable_page_ctor(page);

	return page;
H
Haavard Skinnemoen 已提交
73 74
}

75
static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
H
Haavard Skinnemoen 已提交
76
{
77
	quicklist_free(QUICK_PT, NULL, pte);
H
Haavard Skinnemoen 已提交
78 79
}

80
static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
H
Haavard Skinnemoen 已提交
81
{
82
	pgtable_page_dtor(pte);
83
	quicklist_free_page(QUICK_PT, NULL, pte);
H
Haavard Skinnemoen 已提交
84 85
}

86
#define __pte_free_tlb(tlb,pte,addr)			\
87 88 89 90
do {							\
	pgtable_page_dtor(pte);				\
	tlb_remove_page((tlb), pte);			\
} while (0)
H
Haavard Skinnemoen 已提交
91

92 93 94
static inline void check_pgt_cache(void)
{
	quicklist_trim(QUICK_PGD, NULL, 25, 16);
95
	quicklist_trim(QUICK_PT, NULL, 25, 16);
96
}
H
Haavard Skinnemoen 已提交
97 98

#endif /* __ASM_AVR32_PGALLOC_H */