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