2005-04-17 02:20:36 +04:00
# ifndef __ASM_SH_PGALLOC_H
# define __ASM_SH_PGALLOC_H
2007-05-08 06:55:21 +04:00
# include <linux/quicklist.h>
# include <asm/page.h>
# define QUICK_PGD 0 /* We preserve special mappings over free */
# define QUICK_PT 1 /* Other page table pages that are zero on free */
2006-11-21 09:38:05 +03:00
static inline void pmd_populate_kernel ( struct mm_struct * mm , pmd_t * pmd ,
pte_t * pte )
{
set_pmd ( pmd , __pmd ( ( unsigned long ) pte ) ) ;
}
2005-04-17 02:20:36 +04:00
static inline void pmd_populate ( struct mm_struct * mm , pmd_t * pmd ,
struct page * pte )
{
2006-11-21 09:38:05 +03:00
set_pmd ( pmd , __pmd ( ( unsigned long ) page_address ( pte ) ) ) ;
2005-04-17 02:20:36 +04:00
}
2007-05-08 06:55:21 +04:00
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 ) ) ;
}
2005-04-17 02:20:36 +04:00
/*
* Allocate and free page tables .
*/
static inline pgd_t * pgd_alloc ( struct mm_struct * mm )
{
2007-05-08 06:55:21 +04:00
return quicklist_alloc ( QUICK_PGD , GFP_KERNEL | __GFP_REPEAT , pgd_ctor ) ;
2005-04-17 02:20:36 +04:00
}
2008-02-05 09:29:14 +03:00
static inline void pgd_free ( struct mm_struct * mm , pgd_t * pgd )
2005-04-17 02:20:36 +04:00
{
2007-05-08 06:55:21 +04:00
quicklist_free ( QUICK_PGD , NULL , pgd ) ;
2005-04-17 02:20:36 +04:00
}
static inline pte_t * pte_alloc_one_kernel ( struct mm_struct * mm ,
unsigned long address )
{
2007-05-08 07:07:21 +04:00
return quicklist_alloc ( QUICK_PT , GFP_KERNEL | __GFP_REPEAT , NULL ) ;
2005-04-17 02:20:36 +04:00
}
static inline struct page * pte_alloc_one ( struct mm_struct * mm ,
unsigned long address )
{
2007-05-08 07:07:21 +04:00
void * pg = quicklist_alloc ( QUICK_PT , GFP_KERNEL | __GFP_REPEAT , NULL ) ;
2007-05-08 06:55:21 +04:00
return pg ? virt_to_page ( pg ) : NULL ;
2005-04-17 02:20:36 +04:00
}
2008-02-05 09:29:14 +03:00
static inline void pte_free_kernel ( struct mm_struct * mm , pte_t * pte )
2005-04-17 02:20:36 +04:00
{
2007-05-08 06:55:21 +04:00
quicklist_free ( QUICK_PT , NULL , pte ) ;
2005-04-17 02:20:36 +04:00
}
2008-02-05 09:29:14 +03:00
static inline void pte_free ( struct mm_struct * mm , struct page * pte )
2005-04-17 02:20:36 +04:00
{
2007-05-08 06:55:21 +04:00
quicklist_free_page ( QUICK_PT , NULL , pte ) ;
2005-04-17 02:20:36 +04:00
}
# define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte))
/*
* allocating and freeing a pmd is trivial : the 1 - entry pmd is
* inside the pgd , so has no extra memory associated with it .
*/
2008-02-05 09:29:14 +03:00
# define pmd_free(mm, x) do { } while (0)
2005-04-17 02:20:36 +04:00
# define __pmd_free_tlb(tlb,x) do { } while (0)
2007-05-08 06:55:21 +04:00
static inline void check_pgt_cache ( void )
{
quicklist_trim ( QUICK_PGD , NULL , 25 , 16 ) ;
quicklist_trim ( QUICK_PT , NULL , 25 , 16 ) ;
}
2005-04-17 02:20:36 +04:00
# endif /* __ASM_SH_PGALLOC_H */