Skip to content

Commit

Permalink
sh: Move page table allocation out of line
Browse files Browse the repository at this point in the history
We also switched away from quicklists and instead moved to slab
caches. After benchmarking both implementations the difference is
negligible. The slab caches suit us better though because the size of a
pgd table is just 4 entries when we're using a 3-level page table layout
and quicklists always deal with pages.

Signed-off-by: Matt Fleming <matt@console-pimps.org>
  • Loading branch information
Matt Fleming committed Jan 2, 2010
1 parent b4c8927 commit 2a5eacc
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 78 deletions.
10 changes: 6 additions & 4 deletions arch/sh/include/asm/pgalloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@

#define QUICK_PT 1 /* Other page table pages that are zero on free */

extern pgd_t *pgd_alloc(struct mm_struct *);
extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);

#ifdef CONFIG_PGTABLE_LEVELS_3
#include <asm/pgalloc_pmd.h>
#else
#include <asm/pgalloc_nopmd.h>
extern void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd);
extern pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address);
extern void pmd_free(struct mm_struct *mm, pmd_t *pmd);
#endif

static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
Expand Down Expand Up @@ -67,7 +70,6 @@ do { \

static inline void check_pgt_cache(void)
{
__check_pgt_cache();
quicklist_trim(QUICK_PT, NULL, 25, 16);
}

Expand Down
30 changes: 0 additions & 30 deletions arch/sh/include/asm/pgalloc_nopmd.h

This file was deleted.

41 changes: 0 additions & 41 deletions arch/sh/include/asm/pgalloc_pmd.h

This file was deleted.

4 changes: 2 additions & 2 deletions arch/sh/include/asm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,9 @@ typedef pte_t *pte_addr_t;
#define pte_pfn(x) ((unsigned long)(((x).pte_low >> PAGE_SHIFT)))

/*
* No page table caches to initialise
* Initialise the page table caches
*/
#define pgtable_cache_init() do { } while (0)
extern void pgtable_cache_init(void);

struct vm_area_struct;

Expand Down
2 changes: 1 addition & 1 deletion arch/sh/mm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ obj-y += $(cacheops-y)

mmu-y := nommu.o extable_32.o
mmu-$(CONFIG_MMU) := extable_$(BITS).o fault_$(BITS).o \
ioremap_$(BITS).o kmap.o tlbflush_$(BITS).o
ioremap_$(BITS).o kmap.o pgtable.o tlbflush_$(BITS).o

obj-y += $(mmu-y)
obj-$(CONFIG_DEBUG_FS) += asids-debugfs.o
Expand Down
57 changes: 57 additions & 0 deletions arch/sh/mm/pgtable.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#include <linux/mm.h>

#define PGALLOC_GFP GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO

static struct kmem_cache *pgd_cachep;

#ifdef CONFIG_PGTABLE_LEVELS_3
static struct kmem_cache *pmd_cachep;
#endif

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));
}

void pgtable_cache_init(void)
{
pgd_cachep = kmem_cache_create("pgd_cache",
PTRS_PER_PGD * (1<<PTE_MAGNITUDE),
PAGE_SIZE, SLAB_PANIC, pgd_ctor);
#ifdef CONFIG_PGTABLE_LEVELS_3
pmd_cachep = kmem_cache_create("pmd_cache",
PTRS_PER_PMD * (1<<PTE_MAGNITUDE),
PAGE_SIZE, SLAB_PANIC, NULL);
#endif
}

pgd_t *pgd_alloc(struct mm_struct *mm)
{
return kmem_cache_alloc(pgd_cachep, PGALLOC_GFP);
}

void pgd_free(struct mm_struct *mm, pgd_t *pgd)
{
kmem_cache_free(pgd_cachep, pgd);
}

#ifdef CONFIG_PGTABLE_LEVELS_3
void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
{
set_pud(pud, __pud((unsigned long)pmd));
}

pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
{
return kmem_cache_alloc(pmd_cachep, PGALLOC_GFP);
}

void pmd_free(struct mm_struct *mm, pmd_t *pmd)
{
kmem_cache_free(pmd_cachep, pmd);
}
#endif /* CONFIG_PGTABLE_LEVELS_3 */

0 comments on commit 2a5eacc

Please sign in to comment.