Re: [RFC PATCH] mm: remove quicklist page table caches

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu 11-07-19 13:03:39, Nicholas Piggin wrote:
> Remove page table allocator "quicklists". These have been around for a
> long time, but have not got much traction in the last decade and are
> only used on ia64 and sh architectures.
> 
> The numbers in the initial commit look interesting but probably don't
> apply anymore. If anybody wants to resurrect this it's in the git
> history, but it's unhelpful to have this code and divergent allocator
> behaviour for minor archs.
> 
> Also it might be better to instead make more general improvements to
> page allocator if this is still so slow.

Agreed. And if that is not possible for whatever reason then we have a
proper justification for the revert at least.

Acked-by: Michal Hocko <mhocko@xxxxxxxx>

> ---
>  arch/alpha/include/asm/pgalloc.h      |   2 -
>  arch/arc/include/asm/pgalloc.h        |   1 -
>  arch/arm/include/asm/pgalloc.h        |   2 -
>  arch/arm64/include/asm/pgalloc.h      |   2 -
>  arch/csky/include/asm/pgalloc.h       |   2 -
>  arch/hexagon/include/asm/pgalloc.h    |   2 -
>  arch/ia64/Kconfig                     |   4 -
>  arch/ia64/include/asm/pgalloc.h       |  32 +++-----
>  arch/m68k/include/asm/pgtable_mm.h    |   2 -
>  arch/m68k/include/asm/pgtable_no.h    |   2 -
>  arch/microblaze/include/asm/pgalloc.h |  89 ++--------------------
>  arch/microblaze/mm/pgtable.c          |   4 -
>  arch/mips/include/asm/pgalloc.h       |   2 -
>  arch/nds32/include/asm/pgalloc.h      |   2 -
>  arch/nios2/include/asm/pgalloc.h      |   2 -
>  arch/openrisc/include/asm/pgalloc.h   |   2 -
>  arch/parisc/include/asm/pgalloc.h     |   2 -
>  arch/powerpc/include/asm/pgalloc.h    |   2 -
>  arch/riscv/include/asm/pgalloc.h      |   4 -
>  arch/s390/include/asm/pgtable.h       |   1 -
>  arch/sh/include/asm/pgalloc.h         |  22 ++----
>  arch/sh/mm/Kconfig                    |   3 -
>  arch/sparc/include/asm/pgalloc_32.h   |   2 -
>  arch/sparc/include/asm/pgalloc_64.h   |   2 -
>  arch/sparc/mm/init_32.c               |   1 -
>  arch/um/include/asm/pgalloc.h         |   2 -
>  arch/unicore32/include/asm/pgalloc.h  |   2 -
>  arch/x86/include/asm/pgtable_32.h     |   1 -
>  arch/x86/include/asm/pgtable_64.h     |   1 -
>  arch/xtensa/include/asm/tlbflush.h    |   3 -
>  fs/proc/meminfo.c                     |   4 -
>  include/asm-generic/pgalloc.h         |   2 -
>  include/linux/quicklist.h             |  94 -----------------------
>  kernel/sched/idle.c                   |   1 -
>  lib/show_mem.c                        |   5 --
>  mm/Kconfig                            |   5 --
>  mm/Makefile                           |   1 -
>  mm/mmu_gather.c                       |   2 -
>  mm/quicklist.c                        | 103 --------------------------
>  39 files changed, 25 insertions(+), 392 deletions(-)
>  delete mode 100644 include/linux/quicklist.h
>  delete mode 100644 mm/quicklist.c
> 
> diff --git a/arch/alpha/include/asm/pgalloc.h b/arch/alpha/include/asm/pgalloc.h
> index 02f9f91bb4f0..0912e37c3a56 100644
> --- a/arch/alpha/include/asm/pgalloc.h
> +++ b/arch/alpha/include/asm/pgalloc.h
> @@ -87,6 +87,4 @@ pte_free(struct mm_struct *mm, pgtable_t page)
>  	__free_page(page);
>  }
>  
> -#define check_pgt_cache()	do { } while (0)
> -
>  #endif /* _ALPHA_PGALLOC_H */
> diff --git a/arch/arc/include/asm/pgalloc.h b/arch/arc/include/asm/pgalloc.h
> index 9c9b5a5ebf2e..e35b00e8cc4c 100644
> --- a/arch/arc/include/asm/pgalloc.h
> +++ b/arch/arc/include/asm/pgalloc.h
> @@ -132,7 +132,6 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t ptep)
>  
>  #define __pte_free_tlb(tlb, pte, addr)  pte_free((tlb)->mm, pte)
>  
> -#define check_pgt_cache()   do { } while (0)
>  #define pmd_pgtable(pmd)	((pgtable_t) pmd_page_vaddr(pmd))
>  
>  #endif /* _ASM_ARC_PGALLOC_H */
> diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h
> index 17ab72f0cc4e..5e2ec767de8e 100644
> --- a/arch/arm/include/asm/pgalloc.h
> +++ b/arch/arm/include/asm/pgalloc.h
> @@ -18,8 +18,6 @@
>  #include <asm/cacheflush.h>
>  #include <asm/tlbflush.h>
>  
> -#define check_pgt_cache()		do { } while (0)
> -
>  #ifdef CONFIG_MMU
>  
>  #define _PAGE_USER_TABLE	(PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_USER))
> diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
> index dabba4b2c61f..6554426d4953 100644
> --- a/arch/arm64/include/asm/pgalloc.h
> +++ b/arch/arm64/include/asm/pgalloc.h
> @@ -24,8 +24,6 @@
>  #include <asm/cacheflush.h>
>  #include <asm/tlbflush.h>
>  
> -#define check_pgt_cache()		do { } while (0)
> -
>  #define PGALLOC_GFP	(GFP_KERNEL | __GFP_ZERO)
>  #define PGD_SIZE	(PTRS_PER_PGD * sizeof(pgd_t))
>  
> diff --git a/arch/csky/include/asm/pgalloc.h b/arch/csky/include/asm/pgalloc.h
> index d213bb47b717..21533eb04747 100644
> --- a/arch/csky/include/asm/pgalloc.h
> +++ b/arch/csky/include/asm/pgalloc.h
> @@ -99,8 +99,6 @@ do {							\
>  	tlb_remove_page(tlb, pte);			\
>  } while (0)
>  
> -#define check_pgt_cache()	do {} while (0)
> -
>  extern void pagetable_init(void);
>  extern void pre_mmu_init(void);
>  extern void pre_trap_init(void);
> diff --git a/arch/hexagon/include/asm/pgalloc.h b/arch/hexagon/include/asm/pgalloc.h
> index d36183887b60..1ee911d79bad 100644
> --- a/arch/hexagon/include/asm/pgalloc.h
> +++ b/arch/hexagon/include/asm/pgalloc.h
> @@ -24,8 +24,6 @@
>  #include <asm/mem-layout.h>
>  #include <asm/atomic.h>
>  
> -#define check_pgt_cache() do {} while (0)
> -
>  extern unsigned long long kmap_generation;
>  
>  /*
> diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
> index 73a26f04644e..e910cc44e1c3 100644
> --- a/arch/ia64/Kconfig
> +++ b/arch/ia64/Kconfig
> @@ -69,10 +69,6 @@ config ZONE_DMA32
>  	def_bool y
>  	depends on !IA64_SGI_SN2
>  
> -config QUICKLIST
> -	bool
> -	default y
> -
>  config MMU
>  	bool
>  	default y
> diff --git a/arch/ia64/include/asm/pgalloc.h b/arch/ia64/include/asm/pgalloc.h
> index c9e481023c25..ffd58bab8a76 100644
> --- a/arch/ia64/include/asm/pgalloc.h
> +++ b/arch/ia64/include/asm/pgalloc.h
> @@ -19,18 +19,17 @@
>  #include <linux/mm.h>
>  #include <linux/page-flags.h>
>  #include <linux/threads.h>
> -#include <linux/quicklist.h>
>  
>  #include <asm/mmu_context.h>
>  
>  static inline pgd_t *pgd_alloc(struct mm_struct *mm)
>  {
> -	return quicklist_alloc(0, GFP_KERNEL, NULL);
> +	return (pgd_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
>  }
>  
>  static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
>  {
> -	quicklist_free(0, NULL, pgd);
> +	__free_page(pgd);
>  }
>  
>  #if CONFIG_PGTABLE_LEVELS == 4
> @@ -42,12 +41,12 @@ pgd_populate(struct mm_struct *mm, pgd_t * pgd_entry, pud_t * pud)
>  
>  static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
>  {
> -	return quicklist_alloc(0, GFP_KERNEL, NULL);
> +	return (pud_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
>  }
>  
>  static inline void pud_free(struct mm_struct *mm, pud_t *pud)
>  {
> -	quicklist_free(0, NULL, pud);
> +	__free_page(pud);
>  }
>  #define __pud_free_tlb(tlb, pud, address)	pud_free((tlb)->mm, pud)
>  #endif /* CONFIG_PGTABLE_LEVELS == 4 */
> @@ -60,12 +59,12 @@ pud_populate(struct mm_struct *mm, pud_t * pud_entry, pmd_t * pmd)
>  
>  static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
>  {
> -	return quicklist_alloc(0, GFP_KERNEL, NULL);
> +	return (pmd_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
>  }
>  
>  static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
>  {
> -	quicklist_free(0, NULL, pmd);
> +	__free_page(pmd);
>  }
>  
>  #define __pmd_free_tlb(tlb, pmd, address)	pmd_free((tlb)->mm, pmd)
> @@ -86,14 +85,12 @@ pmd_populate_kernel(struct mm_struct *mm, pmd_t * pmd_entry, pte_t * pte)
>  static inline pgtable_t pte_alloc_one(struct mm_struct *mm)
>  {
>  	struct page *page;
> -	void *pg;
>  
> -	pg = quicklist_alloc(0, GFP_KERNEL, NULL);
> -	if (!pg)
> +	page = alloc_page(GFP_KERNEL | __GFP_ZERO);
> +	if (!page)
>  		return NULL;
> -	page = virt_to_page(pg);
>  	if (!pgtable_page_ctor(page)) {
> -		quicklist_free(0, NULL, pg);
> +		free_page(page);
>  		return NULL;
>  	}
>  	return page;
> @@ -101,23 +98,18 @@ static inline pgtable_t pte_alloc_one(struct mm_struct *mm)
>  
>  static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
>  {
> -	return quicklist_alloc(0, GFP_KERNEL, NULL);
> +	return (pte_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
>  }
>  
>  static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
>  {
>  	pgtable_page_dtor(pte);
> -	quicklist_free_page(0, NULL, pte);
> +	__free_page(pte);
>  }
>  
>  static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
>  {
> -	quicklist_free(0, NULL, pte);
> -}
> -
> -static inline void check_pgt_cache(void)
> -{
> -	quicklist_trim(0, NULL, 25, 16);
> +	free_page(pte);
>  }
>  
>  #define __pte_free_tlb(tlb, pte, address)	pte_free((tlb)->mm, pte)
> diff --git a/arch/m68k/include/asm/pgtable_mm.h b/arch/m68k/include/asm/pgtable_mm.h
> index fe3ddd73a0cc..b5269f1ce313 100644
> --- a/arch/m68k/include/asm/pgtable_mm.h
> +++ b/arch/m68k/include/asm/pgtable_mm.h
> @@ -178,6 +178,4 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
>   */
>  #define pgtable_cache_init()	do { } while (0)
>  
> -#define check_pgt_cache()	do { } while (0)
> -
>  #endif /* _M68K_PGTABLE_H */
> diff --git a/arch/m68k/include/asm/pgtable_no.h b/arch/m68k/include/asm/pgtable_no.h
> index fc3a96c77bd8..69e271101223 100644
> --- a/arch/m68k/include/asm/pgtable_no.h
> +++ b/arch/m68k/include/asm/pgtable_no.h
> @@ -60,6 +60,4 @@ extern void paging_init(void);
>  
>  #include <asm-generic/pgtable.h>
>  
> -#define check_pgt_cache()	do { } while (0)
> -
>  #endif /* _M68KNOMMU_PGTABLE_H */
> diff --git a/arch/microblaze/include/asm/pgalloc.h b/arch/microblaze/include/asm/pgalloc.h
> index f4cc9ffc449e..c62837073c14 100644
> --- a/arch/microblaze/include/asm/pgalloc.h
> +++ b/arch/microblaze/include/asm/pgalloc.h
> @@ -21,83 +21,20 @@
>  #include <asm/cache.h>
>  #include <asm/pgtable.h>
>  
> -#define PGDIR_ORDER	0
> -
> -/*
> - * This is handled very differently on MicroBlaze since out page tables
> - * are all 0's and I want to be able to use these zero'd pages elsewhere
> - * as well - it gives us quite a speedup.
> - * -- Cort
> - */
> -extern struct pgtable_cache_struct {
> -	unsigned long *pgd_cache;
> -	unsigned long *pte_cache;
> -	unsigned long pgtable_cache_sz;
> -} quicklists;
> -
> -#define pgd_quicklist		(quicklists.pgd_cache)
> -#define pmd_quicklist		((unsigned long *)0)
> -#define pte_quicklist		(quicklists.pte_cache)
> -#define pgtable_cache_size	(quicklists.pgtable_cache_sz)
> -
> -extern unsigned long *zero_cache; /* head linked list of pre-zero'd pages */
> -extern atomic_t zero_sz; /* # currently pre-zero'd pages */
> -extern atomic_t zeropage_hits; /* # zero'd pages request that we've done */
> -extern atomic_t zeropage_calls; /* # zero'd pages request that've been made */
> -extern atomic_t zerototal; /* # pages zero'd over time */
> -
> -#define zero_quicklist		(zero_cache)
> -#define zero_cache_sz	 	(zero_sz)
> -#define zero_cache_calls	(zeropage_calls)
> -#define zero_cache_hits		(zeropage_hits)
> -#define zero_cache_total	(zerototal)
> -
> -/*
> - * return a pre-zero'd page from the list,
> - * return NULL if none available -- Cort
> - */
> -extern unsigned long get_zero_page_fast(void);
> -
>  extern void __bad_pte(pmd_t *pmd);
>  
> -static inline pgd_t *get_pgd_slow(void)
> +static inline pgd_t *get_pgd(void)
>  {
> -	pgd_t *ret;
> -
> -	ret = (pgd_t *)__get_free_pages(GFP_KERNEL, PGDIR_ORDER);
> -	if (ret != NULL)
> -		clear_page(ret);
> -	return ret;
> +	return (pgd_t *)__get_free_pages(GFP_KERNEL|GFP_ZERO, 0);
>  }
>  
> -static inline pgd_t *get_pgd_fast(void)
> -{
> -	unsigned long *ret;
> -
> -	ret = pgd_quicklist;
> -	if (ret != NULL) {
> -		pgd_quicklist = (unsigned long *)(*ret);
> -		ret[0] = 0;
> -		pgtable_cache_size--;
> -	} else
> -		ret = (unsigned long *)get_pgd_slow();
> -	return (pgd_t *)ret;
> -}
> -
> -static inline void free_pgd_fast(pgd_t *pgd)
> -{
> -	*(unsigned long **)pgd = pgd_quicklist;
> -	pgd_quicklist = (unsigned long *) pgd;
> -	pgtable_cache_size++;
> -}
> -
> -static inline void free_pgd_slow(pgd_t *pgd)
> +static inline void free_pgd(pgd_t *pgd)
>  {
>  	free_page((unsigned long)pgd);
>  }
>  
> -#define pgd_free(mm, pgd)        free_pgd_fast(pgd)
> -#define pgd_alloc(mm)		get_pgd_fast()
> +#define pgd_free(mm, pgd)	free_pgd(pgd)
> +#define pgd_alloc(mm)		get_pgd()
>  
>  #define pmd_pgtable(pmd)	pmd_page(pmd)
>  
> @@ -115,15 +52,14 @@ static inline struct page *pte_alloc_one(struct mm_struct *mm)
>  	struct page *ptepage;
>  
>  #ifdef CONFIG_HIGHPTE
> -	int flags = GFP_KERNEL | __GFP_HIGHMEM;
> +	int flags = GFP_KERNEL | GFP_ZERO | __GFP_HIGHMEM;
>  #else
> -	int flags = GFP_KERNEL;
> +	int flags = GFP_KERNEL | GFP_ZERO;
>  #endif
>  
>  	ptepage = alloc_pages(flags, 0);
>  	if (!ptepage)
>  		return NULL;
> -	clear_highpage(ptepage);
>  	if (!pgtable_page_ctor(ptepage)) {
>  		__free_page(ptepage);
>  		return NULL;
> @@ -131,13 +67,6 @@ static inline struct page *pte_alloc_one(struct mm_struct *mm)
>  	return ptepage;
>  }
>  
> -static inline void pte_free_fast(pte_t *pte)
> -{
> -	*(unsigned long **)pte = pte_quicklist;
> -	pte_quicklist = (unsigned long *) pte;
> -	pgtable_cache_size++;
> -}
> -
>  static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
>  {
>  	free_page((unsigned long)pte);
> @@ -171,10 +100,6 @@ static inline void pte_free(struct mm_struct *mm, struct page *ptepage)
>  #define __pmd_free_tlb(tlb, x, addr)	pmd_free((tlb)->mm, x)
>  #define pgd_populate(mm, pmd, pte)	BUG()
>  
> -extern int do_check_pgt_cache(int, int);
> -
>  #endif /* CONFIG_MMU */
>  
> -#define check_pgt_cache()		do { } while (0)
> -
>  #endif /* _ASM_MICROBLAZE_PGALLOC_H */
> diff --git a/arch/microblaze/mm/pgtable.c b/arch/microblaze/mm/pgtable.c
> index 8fe54fda31dc..010bb9cee2e4 100644
> --- a/arch/microblaze/mm/pgtable.c
> +++ b/arch/microblaze/mm/pgtable.c
> @@ -44,10 +44,6 @@ unsigned long ioremap_base;
>  unsigned long ioremap_bot;
>  EXPORT_SYMBOL(ioremap_bot);
>  
> -#ifndef CONFIG_SMP
> -struct pgtable_cache_struct quicklists;
> -#endif
> -
>  static void __iomem *__ioremap(phys_addr_t addr, unsigned long size,
>  		unsigned long flags)
>  {
> diff --git a/arch/mips/include/asm/pgalloc.h b/arch/mips/include/asm/pgalloc.h
> index 27808d9461f4..fbaddb12ea2b 100644
> --- a/arch/mips/include/asm/pgalloc.h
> +++ b/arch/mips/include/asm/pgalloc.h
> @@ -134,8 +134,6 @@ static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud)
>  
>  #endif /* __PAGETABLE_PUD_FOLDED */
>  
> -#define check_pgt_cache()	do { } while (0)
> -
>  extern void pagetable_init(void);
>  
>  #endif /* _ASM_PGALLOC_H */
> diff --git a/arch/nds32/include/asm/pgalloc.h b/arch/nds32/include/asm/pgalloc.h
> index 3c5fee5b5759..95fee5f930c0 100644
> --- a/arch/nds32/include/asm/pgalloc.h
> +++ b/arch/nds32/include/asm/pgalloc.h
> @@ -20,8 +20,6 @@
>  extern pgd_t *pgd_alloc(struct mm_struct *mm);
>  extern void pgd_free(struct mm_struct *mm, pgd_t * pgd);
>  
> -#define check_pgt_cache()		do { } while (0)
> -
>  static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
>  {
>  	pte_t *pte;
> diff --git a/arch/nios2/include/asm/pgalloc.h b/arch/nios2/include/asm/pgalloc.h
> index 3a149ead1207..58417affacbc 100644
> --- a/arch/nios2/include/asm/pgalloc.h
> +++ b/arch/nios2/include/asm/pgalloc.h
> @@ -78,6 +78,4 @@ static inline void pte_free(struct mm_struct *mm, struct page *pte)
>  		tlb_remove_page((tlb), (pte));			\
>  	} while (0)
>  
> -#define check_pgt_cache()	do { } while (0)
> -
>  #endif /* _ASM_NIOS2_PGALLOC_H */
> diff --git a/arch/openrisc/include/asm/pgalloc.h b/arch/openrisc/include/asm/pgalloc.h
> index 149c82ee4b8b..dafc6f5aee6a 100644
> --- a/arch/openrisc/include/asm/pgalloc.h
> +++ b/arch/openrisc/include/asm/pgalloc.h
> @@ -105,6 +105,4 @@ do {					\
>  
>  #define pmd_pgtable(pmd) pmd_page(pmd)
>  
> -#define check_pgt_cache()          do { } while (0)
> -
>  #endif
> diff --git a/arch/parisc/include/asm/pgalloc.h b/arch/parisc/include/asm/pgalloc.h
> index ea75cc966dae..ee042753fbb4 100644
> --- a/arch/parisc/include/asm/pgalloc.h
> +++ b/arch/parisc/include/asm/pgalloc.h
> @@ -153,6 +153,4 @@ static inline void pte_free(struct mm_struct *mm, struct page *pte)
>  	pte_free_kernel(mm, page_address(pte));
>  }
>  
> -#define check_pgt_cache()	do { } while (0)
> -
>  #endif
> diff --git a/arch/powerpc/include/asm/pgalloc.h b/arch/powerpc/include/asm/pgalloc.h
> index 2b2c60a1a66d..6dd78a2dc03a 100644
> --- a/arch/powerpc/include/asm/pgalloc.h
> +++ b/arch/powerpc/include/asm/pgalloc.h
> @@ -64,8 +64,6 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
>  extern struct kmem_cache *pgtable_cache[];
>  #define PGT_CACHE(shift) pgtable_cache[shift]
>  
> -static inline void check_pgt_cache(void) { }
> -
>  #ifdef CONFIG_PPC_BOOK3S
>  #include <asm/book3s/pgalloc.h>
>  #else
> diff --git a/arch/riscv/include/asm/pgalloc.h b/arch/riscv/include/asm/pgalloc.h
> index 94043cf83c90..5b6a4a07d130 100644
> --- a/arch/riscv/include/asm/pgalloc.h
> +++ b/arch/riscv/include/asm/pgalloc.h
> @@ -115,8 +115,4 @@ do {                                    \
>  	tlb_remove_page((tlb), pte);    \
>  } while (0)
>  
> -static inline void check_pgt_cache(void)
> -{
> -}
> -
>  #endif /* _ASM_RISCV_PGALLOC_H */
> diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
> index 9f0195d5fa16..938472aa084c 100644
> --- a/arch/s390/include/asm/pgtable.h
> +++ b/arch/s390/include/asm/pgtable.h
> @@ -1691,7 +1691,6 @@ extern void s390_reset_cmma(struct mm_struct *mm);
>   * No page table caches to initialise
>   */
>  static inline void pgtable_cache_init(void) { }
> -static inline void check_pgt_cache(void) { }
>  
>  #include <asm-generic/pgtable.h>
>  
> diff --git a/arch/sh/include/asm/pgalloc.h b/arch/sh/include/asm/pgalloc.h
> index b56f908b1395..160308a35fa3 100644
> --- a/arch/sh/include/asm/pgalloc.h
> +++ b/arch/sh/include/asm/pgalloc.h
> @@ -2,11 +2,8 @@
>  #ifndef __ASM_SH_PGALLOC_H
>  #define __ASM_SH_PGALLOC_H
>  
> -#include <linux/quicklist.h>
>  #include <asm/page.h>
>  
> -#define QUICK_PT 0	/* 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);
>  
> @@ -34,20 +31,18 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
>   */
>  static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
>  {
> -	return quicklist_alloc(QUICK_PT, GFP_KERNEL, NULL);
> +	return (pte_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
>  }
>  
>  static inline pgtable_t pte_alloc_one(struct mm_struct *mm)
>  {
>  	struct page *page;
> -	void *pg;
>  
> -	pg = quicklist_alloc(QUICK_PT, GFP_KERNEL, NULL);
> -	if (!pg)
> +	page = alloc_page(GFP_KERNEL | __GFP_ZERO);
> +	if (!page)
>  		return NULL;
> -	page = virt_to_page(pg);
>  	if (!pgtable_page_ctor(page)) {
> -		quicklist_free(QUICK_PT, NULL, pg);
> +		free_page(page);
>  		return NULL;
>  	}
>  	return page;
> @@ -55,13 +50,13 @@ static inline pgtable_t pte_alloc_one(struct mm_struct *mm)
>  
>  static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
>  {
> -	quicklist_free(QUICK_PT, NULL, pte);
> +	free_page(pte);
>  }
>  
>  static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
>  {
>  	pgtable_page_dtor(pte);
> -	quicklist_free_page(QUICK_PT, NULL, pte);
> +	__free_page(pte);
>  }
>  
>  #define __pte_free_tlb(tlb,pte,addr)			\
> @@ -79,9 +74,4 @@ do {							\
>  } while (0);
>  #endif
>  
> -static inline void check_pgt_cache(void)
> -{
> -	quicklist_trim(QUICK_PT, NULL, 25, 16);
> -}
> -
>  #endif /* __ASM_SH_PGALLOC_H */
> diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig
> index 02ed2df25a54..5c8a2ebfc720 100644
> --- a/arch/sh/mm/Kconfig
> +++ b/arch/sh/mm/Kconfig
> @@ -1,9 +1,6 @@
>  # SPDX-License-Identifier: GPL-2.0
>  menu "Memory management options"
>  
> -config QUICKLIST
> -	def_bool y
> -
>  config MMU
>          bool "Support for memory management hardware"
>  	depends on !CPU_SH2
> diff --git a/arch/sparc/include/asm/pgalloc_32.h b/arch/sparc/include/asm/pgalloc_32.h
> index 282be50a4adf..10538a4d1a1e 100644
> --- a/arch/sparc/include/asm/pgalloc_32.h
> +++ b/arch/sparc/include/asm/pgalloc_32.h
> @@ -17,8 +17,6 @@ void srmmu_free_nocache(void *addr, int size);
>  
>  extern struct resource sparc_iomap;
>  
> -#define check_pgt_cache()	do { } while (0)
> -
>  pgd_t *get_pgd_fast(void);
>  static inline void free_pgd_fast(pgd_t *pgd)
>  {
> diff --git a/arch/sparc/include/asm/pgalloc_64.h b/arch/sparc/include/asm/pgalloc_64.h
> index 48abccba4991..9d3e5cc95bbb 100644
> --- a/arch/sparc/include/asm/pgalloc_64.h
> +++ b/arch/sparc/include/asm/pgalloc_64.h
> @@ -69,8 +69,6 @@ void pte_free(struct mm_struct *mm, pgtable_t ptepage);
>  #define pmd_populate(MM, PMD, PTE)		pmd_set(MM, PMD, PTE)
>  #define pmd_pgtable(PMD)			((pte_t *)__pmd_page(PMD))
>  
> -#define check_pgt_cache()	do { } while (0)
> -
>  void pgtable_free(void *table, bool is_page);
>  
>  #ifdef CONFIG_SMP
> diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c
> index a8ff29821bdb..5f482e6e2ad1 100644
> --- a/arch/sparc/mm/init_32.c
> +++ b/arch/sparc/mm/init_32.c
> @@ -31,7 +31,6 @@
>  #include <asm/page.h>
>  #include <asm/pgtable.h>
>  #include <asm/vaddrs.h>
> -#include <asm/pgalloc.h>	/* bug in asm-generic/tlb.h: check_pgt_cache */
>  #include <asm/setup.h>
>  #include <asm/tlb.h>
>  #include <asm/prom.h>
> diff --git a/arch/um/include/asm/pgalloc.h b/arch/um/include/asm/pgalloc.h
> index 99eb5682792a..d601937b632b 100644
> --- a/arch/um/include/asm/pgalloc.h
> +++ b/arch/um/include/asm/pgalloc.h
> @@ -55,7 +55,5 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
>  #define __pmd_free_tlb(tlb,x, address)   tlb_remove_page((tlb),virt_to_page(x))
>  #endif
>  
> -#define check_pgt_cache()	do { } while (0)
> -
>  #endif
>  
> diff --git a/arch/unicore32/include/asm/pgalloc.h b/arch/unicore32/include/asm/pgalloc.h
> index 7cceabecf4e3..56056e2369a4 100644
> --- a/arch/unicore32/include/asm/pgalloc.h
> +++ b/arch/unicore32/include/asm/pgalloc.h
> @@ -17,8 +17,6 @@
>  #include <asm/cacheflush.h>
>  #include <asm/tlbflush.h>
>  
> -#define check_pgt_cache()		do { } while (0)
> -
>  #define _PAGE_USER_TABLE	(PMD_TYPE_TABLE | PMD_PRESENT)
>  #define _PAGE_KERNEL_TABLE	(PMD_TYPE_TABLE | PMD_PRESENT)
>  
> diff --git a/arch/x86/include/asm/pgtable_32.h b/arch/x86/include/asm/pgtable_32.h
> index 4fe9e7fc74d3..7d0c8cac88a8 100644
> --- a/arch/x86/include/asm/pgtable_32.h
> +++ b/arch/x86/include/asm/pgtable_32.h
> @@ -30,7 +30,6 @@ extern pgd_t initial_page_table[1024];
>  extern pmd_t initial_pg_pmd[];
>  
>  static inline void pgtable_cache_init(void) { }
> -static inline void check_pgt_cache(void) { }
>  void paging_init(void);
>  void sync_initial_page_table(void);
>  
> diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h
> index 0bb566315621..08b1106834eb 100644
> --- a/arch/x86/include/asm/pgtable_64.h
> +++ b/arch/x86/include/asm/pgtable_64.h
> @@ -242,7 +242,6 @@ extern void cleanup_highmap(void);
>  #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
>  
>  #define pgtable_cache_init()   do { } while (0)
> -#define check_pgt_cache()      do { } while (0)
>  
>  #define PAGE_AGP    PAGE_KERNEL_NOCACHE
>  #define HAVE_PAGE_AGP 1
> diff --git a/arch/xtensa/include/asm/tlbflush.h b/arch/xtensa/include/asm/tlbflush.h
> index 06875feb27c2..856e2da2e397 100644
> --- a/arch/xtensa/include/asm/tlbflush.h
> +++ b/arch/xtensa/include/asm/tlbflush.h
> @@ -160,9 +160,6 @@ static inline void invalidate_dtlb_mapping (unsigned address)
>  		invalidate_dtlb_entry(tlb_entry);
>  }
>  
> -#define check_pgt_cache()	do { } while (0)
> -
> -
>  /*
>   * DO NOT USE THESE FUNCTIONS.  These instructions aren't part of the Xtensa
>   * ISA and exist only for test purposes..
> diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c
> index 568d90e17c17..131bca8db1a1 100644
> --- a/fs/proc/meminfo.c
> +++ b/fs/proc/meminfo.c
> @@ -8,7 +8,6 @@
>  #include <linux/mmzone.h>
>  #include <linux/proc_fs.h>
>  #include <linux/percpu.h>
> -#include <linux/quicklist.h>
>  #include <linux/seq_file.h>
>  #include <linux/swap.h>
>  #include <linux/vmstat.h>
> @@ -106,9 +105,6 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
>  		   global_zone_page_state(NR_KERNEL_STACK_KB));
>  	show_val_kb(m, "PageTables:     ",
>  		    global_zone_page_state(NR_PAGETABLE));
> -#ifdef CONFIG_QUICKLIST
> -	show_val_kb(m, "Quicklists:     ", quicklist_total_size());
> -#endif
>  
>  	show_val_kb(m, "NFS_Unstable:   ",
>  		    global_node_page_state(NR_UNSTABLE_NFS));
> diff --git a/include/asm-generic/pgalloc.h b/include/asm-generic/pgalloc.h
> index 948714c1535a..500feb7b838a 100644
> --- a/include/asm-generic/pgalloc.h
> +++ b/include/asm-generic/pgalloc.h
> @@ -8,6 +8,4 @@
>  #error need to implement an architecture specific asm/pgalloc.h
>  #endif
>  
> -#define check_pgt_cache()          do { } while (0)
> -
>  #endif /* __ASM_GENERIC_PGALLOC_H */
> diff --git a/include/linux/quicklist.h b/include/linux/quicklist.h
> deleted file mode 100644
> index 034982c98c8b..000000000000
> --- a/include/linux/quicklist.h
> +++ /dev/null
> @@ -1,94 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0 */
> -#ifndef LINUX_QUICKLIST_H
> -#define LINUX_QUICKLIST_H
> -/*
> - * Fast allocations and disposal of pages. Pages must be in the condition
> - * as needed after allocation when they are freed. Per cpu lists of pages
> - * are kept that only contain node local pages.
> - *
> - * (C) 2007, SGI. Christoph Lameter <cl@xxxxxxxxx>
> - */
> -#include <linux/kernel.h>
> -#include <linux/gfp.h>
> -#include <linux/percpu.h>
> -
> -#ifdef CONFIG_QUICKLIST
> -
> -struct quicklist {
> -	void *page;
> -	int nr_pages;
> -};
> -
> -DECLARE_PER_CPU(struct quicklist, quicklist)[CONFIG_NR_QUICK];
> -
> -/*
> - * The two key functions quicklist_alloc and quicklist_free are inline so
> - * that they may be custom compiled for the platform.
> - * Specifying a NULL ctor can remove constructor support. Specifying
> - * a constant quicklist allows the determination of the exact address
> - * in the per cpu area.
> - *
> - * The fast patch in quicklist_alloc touched only a per cpu cacheline and
> - * the first cacheline of the page itself. There is minmal overhead involved.
> - */
> -static inline void *quicklist_alloc(int nr, gfp_t flags, void (*ctor)(void *))
> -{
> -	struct quicklist *q;
> -	void **p = NULL;
> -
> -	q =&get_cpu_var(quicklist)[nr];
> -	p = q->page;
> -	if (likely(p)) {
> -		q->page = p[0];
> -		p[0] = NULL;
> -		q->nr_pages--;
> -	}
> -	put_cpu_var(quicklist);
> -	if (likely(p))
> -		return p;
> -
> -	p = (void *)__get_free_page(flags | __GFP_ZERO);
> -	if (ctor && p)
> -		ctor(p);
> -	return p;
> -}
> -
> -static inline void __quicklist_free(int nr, void (*dtor)(void *), void *p,
> -	struct page *page)
> -{
> -	struct quicklist *q;
> -
> -	q = &get_cpu_var(quicklist)[nr];
> -	*(void **)p = q->page;
> -	q->page = p;
> -	q->nr_pages++;
> -	put_cpu_var(quicklist);
> -}
> -
> -static inline void quicklist_free(int nr, void (*dtor)(void *), void *pp)
> -{
> -	__quicklist_free(nr, dtor, pp, virt_to_page(pp));
> -}
> -
> -static inline void quicklist_free_page(int nr, void (*dtor)(void *),
> -							struct page *page)
> -{
> -	__quicklist_free(nr, dtor, page_address(page), page);
> -}
> -
> -void quicklist_trim(int nr, void (*dtor)(void *),
> -	unsigned long min_pages, unsigned long max_free);
> -
> -unsigned long quicklist_total_size(void);
> -
> -#else
> -
> -static inline unsigned long quicklist_total_size(void)
> -{
> -	return 0;
> -}
> -
> -#endif
> -
> -#endif /* LINUX_QUICKLIST_H */
> -
> diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c
> index f5516bae0c1b..8fb03bc55e69 100644
> --- a/kernel/sched/idle.c
> +++ b/kernel/sched/idle.c
> @@ -237,7 +237,6 @@ static void do_idle(void)
>  	tick_nohz_idle_enter();
>  
>  	while (!need_resched()) {
> -		check_pgt_cache();
>  		rmb();
>  
>  		if (cpu_is_offline(cpu)) {
> diff --git a/lib/show_mem.c b/lib/show_mem.c
> index 6a042f53e7bb..b0950ab534ab 100644
> --- a/lib/show_mem.c
> +++ b/lib/show_mem.c
> @@ -6,7 +6,6 @@
>   */
>  
>  #include <linux/mm.h>
> -#include <linux/quicklist.h>
>  #include <linux/cma.h>
>  
>  void show_mem(unsigned int filter, nodemask_t *nodemask)
> @@ -39,10 +38,6 @@ void show_mem(unsigned int filter, nodemask_t *nodemask)
>  #ifdef CONFIG_CMA
>  	printk("%lu pages cma reserved\n", totalcma_pages);
>  #endif
> -#ifdef CONFIG_QUICKLIST
> -	printk("%lu pages in pagetable cache\n",
> -		quicklist_total_size());
> -#endif
>  #ifdef CONFIG_MEMORY_FAILURE
>  	printk("%lu pages hwpoisoned\n", atomic_long_read(&num_poisoned_pages));
>  #endif
> diff --git a/mm/Kconfig b/mm/Kconfig
> index 25c71eb8a7db..971cc961453e 100644
> --- a/mm/Kconfig
> +++ b/mm/Kconfig
> @@ -271,11 +271,6 @@ config BOUNCE
>  	  by default when ZONE_DMA or HIGHMEM is selected, but you
>  	  may say n to override this.
>  
> -config NR_QUICK
> -	int
> -	depends on QUICKLIST
> -	default "1"
> -
>  config VIRT_TO_BUS
>  	bool
>  	help
> diff --git a/mm/Makefile b/mm/Makefile
> index d210cc9d6f80..f6ea80fd9329 100644
> --- a/mm/Makefile
> +++ b/mm/Makefile
> @@ -67,7 +67,6 @@ obj-$(CONFIG_FAILSLAB) += failslab.o
>  obj-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o
>  obj-$(CONFIG_MEMTEST)		+= memtest.o
>  obj-$(CONFIG_MIGRATION) += migrate.o
> -obj-$(CONFIG_QUICKLIST) += quicklist.o
>  obj-$(CONFIG_TRANSPARENT_HUGEPAGE) += huge_memory.o khugepaged.o
>  obj-$(CONFIG_PAGE_COUNTER) += page_counter.o
>  obj-$(CONFIG_MEMCG) += memcontrol.o vmpressure.o
> diff --git a/mm/mmu_gather.c b/mm/mmu_gather.c
> index 99740e1dd273..093196839b6e 100644
> --- a/mm/mmu_gather.c
> +++ b/mm/mmu_gather.c
> @@ -257,8 +257,6 @@ void tlb_finish_mmu(struct mmu_gather *tlb,
>  
>  	tlb_flush_mmu(tlb);
>  
> -	/* keep the page table cache within bounds */
> -	check_pgt_cache();
>  #ifndef CONFIG_HAVE_MMU_GATHER_NO_GATHER
>  	tlb_batch_list_free(tlb);
>  #endif
> diff --git a/mm/quicklist.c b/mm/quicklist.c
> deleted file mode 100644
> index 5e98ac78e410..000000000000
> --- a/mm/quicklist.c
> +++ /dev/null
> @@ -1,103 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0
> -/*
> - * Quicklist support.
> - *
> - * Quicklists are light weight lists of pages that have a defined state
> - * on alloc and free. Pages must be in the quicklist specific defined state
> - * (zero by default) when the page is freed. It seems that the initial idea
> - * for such lists first came from Dave Miller and then various other people
> - * improved on it.
> - *
> - * Copyright (C) 2007 SGI,
> - * 	Christoph Lameter <cl@xxxxxxxxx>
> - * 		Generalized, added support for multiple lists and
> - * 		constructors / destructors.
> - */
> -#include <linux/kernel.h>
> -
> -#include <linux/gfp.h>
> -#include <linux/mm.h>
> -#include <linux/mmzone.h>
> -#include <linux/quicklist.h>
> -
> -DEFINE_PER_CPU(struct quicklist [CONFIG_NR_QUICK], quicklist);
> -
> -#define FRACTION_OF_NODE_MEM	16
> -
> -static unsigned long max_pages(unsigned long min_pages)
> -{
> -	unsigned long node_free_pages, max;
> -	int node = numa_node_id();
> -	struct zone *zones = NODE_DATA(node)->node_zones;
> -	int num_cpus_on_node;
> -
> -	node_free_pages =
> -#ifdef CONFIG_ZONE_DMA
> -		zone_page_state(&zones[ZONE_DMA], NR_FREE_PAGES) +
> -#endif
> -#ifdef CONFIG_ZONE_DMA32
> -		zone_page_state(&zones[ZONE_DMA32], NR_FREE_PAGES) +
> -#endif
> -		zone_page_state(&zones[ZONE_NORMAL], NR_FREE_PAGES);
> -
> -	max = node_free_pages / FRACTION_OF_NODE_MEM;
> -
> -	num_cpus_on_node = cpumask_weight(cpumask_of_node(node));
> -	max /= num_cpus_on_node;
> -
> -	return max(max, min_pages);
> -}
> -
> -static long min_pages_to_free(struct quicklist *q,
> -	unsigned long min_pages, long max_free)
> -{
> -	long pages_to_free;
> -
> -	pages_to_free = q->nr_pages - max_pages(min_pages);
> -
> -	return min(pages_to_free, max_free);
> -}
> -
> -/*
> - * Trim down the number of pages in the quicklist
> - */
> -void quicklist_trim(int nr, void (*dtor)(void *),
> -	unsigned long min_pages, unsigned long max_free)
> -{
> -	long pages_to_free;
> -	struct quicklist *q;
> -
> -	q = &get_cpu_var(quicklist)[nr];
> -	if (q->nr_pages > min_pages) {
> -		pages_to_free = min_pages_to_free(q, min_pages, max_free);
> -
> -		while (pages_to_free > 0) {
> -			/*
> -			 * We pass a gfp_t of 0 to quicklist_alloc here
> -			 * because we will never call into the page allocator.
> -			 */
> -			void *p = quicklist_alloc(nr, 0, NULL);
> -
> -			if (dtor)
> -				dtor(p);
> -			free_page((unsigned long)p);
> -			pages_to_free--;
> -		}
> -	}
> -	put_cpu_var(quicklist);
> -}
> -
> -unsigned long quicklist_total_size(void)
> -{
> -	unsigned long count = 0;
> -	int cpu;
> -	struct quicklist *ql, *q;
> -
> -	for_each_online_cpu(cpu) {
> -		ql = per_cpu(quicklist, cpu);
> -		for (q = ql; q < ql + CONFIG_NR_QUICK; q++)
> -			count += q->nr_pages;
> -	}
> -	return count;
> -}
> -
> -- 
> 2.20.1

-- 
Michal Hocko
SUSE Labs



[Index of Archives]     [Linux Kernel]     [Sparc Linux]     [DCCP]     [Linux ARM]     [Yosemite News]     [Linux SCSI]     [Linux x86_64]     [Linux for Ham Radio]

  Powered by Linux