[Devel] [PATCH RHEL7 COMMIT] mm: Drop alloc_kmem_pages and friends

Konstantin Khorenko khorenko at virtuozzo.com
Tue May 31 02:14:07 PDT 2016


The commit is pushed to "branch-rh7-3.10.0-327.18.2.vz7.14.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-327.18.2.vz7.14.9
------>
commit 3813b61da45aff9ce1324dd0201ae9e59b1e5a26
Author: Vladimir Davydov <vdavydov at virtuozzo.com>
Date:   Tue May 31 13:14:07 2016 +0400

    mm: Drop alloc_kmem_pages and friends
    
    Patchset description:
    Some kmemcg related fixes
    
    This patch set backports some changes from the following patch set
    submitted upstream:
    
      lkml.kernel.org/r/cover.1464079537.git.vdavydov at virtuozzo.com
    
    [hasn't been merged yet]
    
    namely:
     - move kmemcg charge/uncharge to generic allocator paths
     - fix pipe buffer stealing
     - avoid charging kernel page tables
     - account unix socket buffers to kmemcg (PSBM-34562)
    
    Vladimir Davydov (7):
      Drop alloc_kmem_pages and friends
      mm: memcontrol: drop memcg_kmem_commit_charge
      Move PageBalloon and PageBuddy helpers to page-flags.h
      mm: charge/uncharge kmemcg from generic page allocator paths
      af_unix: charge buffers to kmemcg
      pipe: uncharge page on ->steal
      arch: x86: don't charge kernel page tables to kmemcg
    
    =======================
    This patch description:
    
    These functions work exactly like alloc_pages and others except they
    will charge allocated page to current memcg if __GFP_ACCOUNT is passed.
    In the next patch I'm going to move charge/uncharge to generic
    allocation paths, so that these special helpers won't be necessary.
    
    Signed-off-by: Vladimir Davydov <vdavydov at virtuozzo.com>
---
 arch/x86/include/asm/pgalloc.h    | 14 ++++-----
 arch/x86/kernel/ldt.c             |  6 ++--
 arch/x86/mm/pgtable.c             | 19 +++++-------
 fs/pipe.c                         | 11 +++----
 include/linux/gfp.h               |  8 -----
 kernel/fork.c                     |  6 ++--
 mm/memcontrol.c                   |  1 -
 mm/page_alloc.c                   | 65 ---------------------------------------
 mm/slab_common.c                  |  2 +-
 mm/slub.c                         |  4 +--
 mm/vmalloc.c                      |  6 ++--
 net/netfilter/nf_conntrack_core.c |  6 ++--
 net/packet/af_packet.c            |  8 ++---
 13 files changed, 38 insertions(+), 118 deletions(-)

diff --git a/arch/x86/include/asm/pgalloc.h b/arch/x86/include/asm/pgalloc.h
index f589758..58e4567 100644
--- a/arch/x86/include/asm/pgalloc.h
+++ b/arch/x86/include/asm/pgalloc.h
@@ -48,7 +48,7 @@ static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
 static inline void pte_free(struct mm_struct *mm, struct page *pte)
 {
 	pgtable_page_dtor(pte);
-	__free_kmem_pages(pte, 0);
+	__free_page(pte);
 }
 
 extern void ___pte_free_tlb(struct mmu_gather *tlb, struct page *pte);
@@ -81,11 +81,11 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
 static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
 {
 	struct page *page;
-	page = alloc_kmem_pages(GFP_KERNEL_ACCOUNT | __GFP_REPEAT | __GFP_ZERO, 0);
+	page = alloc_pages(GFP_KERNEL_ACCOUNT | __GFP_REPEAT | __GFP_ZERO, 0);
 	if (!page)
 		return NULL;
 	if (!pgtable_pmd_page_ctor(page)) {
-		__free_kmem_pages(page, 0);
+		__free_page(page);
 		return NULL;
 	}
 	return (pmd_t *)page_address(page);
@@ -95,7 +95,7 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
 {
 	BUG_ON((unsigned long)pmd & (PAGE_SIZE-1));
 	pgtable_pmd_page_dtor(virt_to_page(pmd));
-	free_kmem_pages((unsigned long)pmd, 0);
+	free_page((unsigned long)pmd);
 }
 
 extern void ___pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd);
@@ -125,14 +125,14 @@ static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud)
 
 static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
 {
-	return (pud_t *)__get_free_kmem_pages(GFP_KERNEL_ACCOUNT|__GFP_REPEAT|
-					      __GFP_ZERO, 0);
+	return (pud_t *)__get_free_page(GFP_KERNEL_ACCOUNT|__GFP_REPEAT|
+					__GFP_ZERO);
 }
 
 static inline void pud_free(struct mm_struct *mm, pud_t *pud)
 {
 	BUG_ON((unsigned long)pud & (PAGE_SIZE-1));
-	free_kmem_pages((unsigned long)pud, 0);
+	free_page((unsigned long)pud);
 }
 
 extern void ___pud_free_tlb(struct mmu_gather *tlb, pud_t *pud);
diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c
index 4a6c8fe..942b0a4 100644
--- a/arch/x86/kernel/ldt.c
+++ b/arch/x86/kernel/ldt.c
@@ -44,7 +44,7 @@ static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
 	if (mincount * LDT_ENTRY_SIZE > PAGE_SIZE)
 		newldt = vmalloc_account(mincount * LDT_ENTRY_SIZE);
 	else
-		newldt = (void *)__get_free_kmem_pages(GFP_KERNEL_ACCOUNT, 0);
+		newldt = (void *)__get_free_page(GFP_KERNEL_ACCOUNT);
 
 	if (!newldt)
 		return -ENOMEM;
@@ -83,7 +83,7 @@ static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
 		if (oldsize * LDT_ENTRY_SIZE > PAGE_SIZE)
 			vfree(oldldt);
 		else
-			__free_kmem_pages(virt_to_page(oldldt), 0);
+			__free_page(virt_to_page(oldldt));
 	}
 	return 0;
 }
@@ -138,7 +138,7 @@ void destroy_context(struct mm_struct *mm)
 		if (mm->context.size * LDT_ENTRY_SIZE > PAGE_SIZE)
 			vfree(mm->context.ldt);
 		else
-			__free_kmem_pages(virt_to_page(mm->context.ldt), 0);
+			__free_page(virt_to_page(mm->context.ldt));
 		mm->context.size = 0;
 	}
 }
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
index 02ec624..ba13ef8 100644
--- a/arch/x86/mm/pgtable.c
+++ b/arch/x86/mm/pgtable.c
@@ -25,11 +25,11 @@ pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address)
 {
 	struct page *pte;
 
-	pte = alloc_kmem_pages(__userpte_alloc_gfp, 0);
+	pte = alloc_pages(__userpte_alloc_gfp, 0);
 	if (!pte)
 		return NULL;
 	if (!pgtable_page_ctor(pte)) {
-		__free_kmem_pages(pte, 0);
+		__free_page(pte);
 		return NULL;
 	}
 	return pte;
@@ -56,7 +56,6 @@ void ___pte_free_tlb(struct mmu_gather *tlb, struct page *pte)
 {
 	pgtable_page_dtor(pte);
 	paravirt_release_pte(page_to_pfn(pte));
-	memcg_kmem_uncharge_pages(pte, 0);
 	tlb_remove_page(tlb, pte);
 }
 
@@ -73,7 +72,6 @@ void ___pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd)
 	tlb->need_flush_all = 1;
 #endif
 	pgtable_pmd_page_dtor(page);
-	memcg_kmem_uncharge_pages(page, 0);
 	tlb_remove_page(tlb, page);
 }
 
@@ -83,7 +81,6 @@ void ___pud_free_tlb(struct mmu_gather *tlb, pud_t *pud)
 	struct page *page = virt_to_page(pud);
 
 	paravirt_release_pud(__pa(pud) >> PAGE_SHIFT);
-	memcg_kmem_uncharge_pages(page, 0);
 	tlb_remove_page(tlb, page);
 }
 #endif	/* PAGETABLE_LEVELS > 3 */
@@ -203,7 +200,7 @@ static void free_pmds(pmd_t *pmds[])
 	for(i = 0; i < PREALLOCATED_PMDS; i++)
 		if (pmds[i]) {
 			pgtable_pmd_page_dtor(virt_to_page(pmds[i]));
-			free_kmem_pages((unsigned long)pmds[i], 0);
+			free_page((unsigned long)pmds[i]);
 		}
 }
 
@@ -213,11 +210,11 @@ static int preallocate_pmds(pmd_t *pmds[])
 	bool failed = false;
 
 	for(i = 0; i < PREALLOCATED_PMDS; i++) {
-		pmd_t *pmd = (pmd_t *)__get_free_kmem_pages(PGALLOC_GFP, 0);
+		pmd_t *pmd = (pmd_t *)__get_free_page(PGALLOC_GFP);
 		if (!pmd)
 			failed = true;
 		if (pmd && !pgtable_pmd_page_ctor(virt_to_page(pmd))) {
-			free_kmem_pages((unsigned long)pmd, 0);
+			free_page((unsigned long)pmd);
 			pmd = NULL;
 			failed = true;
 		}
@@ -284,7 +281,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
 	pgd_t *pgd;
 	pmd_t *pmds[PREALLOCATED_PMDS];
 
-	pgd = (pgd_t *)__get_free_kmem_pages(PGALLOC_GFP, 0);
+	pgd = (pgd_t *)__get_free_page(PGALLOC_GFP);
 
 	if (pgd == NULL)
 		goto out;
@@ -314,7 +311,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
 out_free_pmds:
 	free_pmds(pmds);
 out_free_pgd:
-	free_kmem_pages((unsigned long)pgd, 0);
+	free_page((unsigned long)pgd);
 out:
 	return NULL;
 }
@@ -324,7 +321,7 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd)
 	pgd_mop_up_pmds(mm, pgd);
 	pgd_dtor(pgd);
 	paravirt_pgd_free(mm, pgd);
-	free_kmem_pages((unsigned long)pgd, 0);
+	free_page((unsigned long)pgd);
 }
 
 /*
diff --git a/fs/pipe.c b/fs/pipe.c
index d038ff8..975fe3f 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -223,11 +223,8 @@ static void anon_pipe_buf_release(struct pipe_inode_info *pipe,
 	 * temporary page, let's keep track of it as a one-deep
 	 * allocation cache. (Otherwise just release our reference to it)
 	 */
-	if (page_count(page) == 1) {
-		if (!pipe->tmp_page)
-			pipe->tmp_page = page;
-		else
-			__free_kmem_pages(page, 0);
+	if (page_count(page) == 1 && !pipe->tmp_page) {
+		pipe->tmp_page = page;
 	} else
 		page_cache_release(page);
 }
@@ -590,7 +587,7 @@ redo1:
 			size_t remaining;
 
 			if (!page) {
-				page = alloc_kmem_pages(GFP_HIGHUSER | __GFP_ACCOUNT, 0);
+				page = alloc_pages(GFP_HIGHUSER | __GFP_ACCOUNT, 0);
 				if (unlikely(!page)) {
 					ret = ret ? : -ENOMEM;
 					break;
@@ -827,7 +824,7 @@ void free_pipe_info(struct pipe_inode_info *pipe)
 			buf->ops->release(pipe, buf);
 	}
 	if (pipe->tmp_page)
-		__free_kmem_pages(pipe->tmp_page, 0);
+		__free_page(pipe->tmp_page);
 	kfree(pipe->bufs);
 	kfree(pipe);
 }
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index b454948..8452f50 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -354,12 +354,7 @@ extern struct page *alloc_pages_vma(gfp_t gfp_mask, int order,
 #define alloc_page_vma_node(gfp_mask, vma, addr, node)		\
 	alloc_pages_vma(gfp_mask, 0, vma, addr, node)
 
-extern struct page *alloc_kmem_pages(gfp_t gfp_mask, unsigned int order);
-extern struct page *alloc_kmem_pages_node(int nid, gfp_t gfp_mask,
-					  unsigned int order);
-
 extern unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order);
-extern unsigned long __get_free_kmem_pages(gfp_t gfp_mask, unsigned int order);
 extern unsigned long get_zeroed_page(gfp_t gfp_mask);
 
 void *alloc_pages_exact(size_t size, gfp_t gfp_mask);
@@ -378,9 +373,6 @@ extern void free_pages(unsigned long addr, unsigned int order);
 extern void free_hot_cold_page(struct page *page, bool cold);
 extern void free_hot_cold_page_list(struct list_head *list, bool cold);
 
-extern void __free_kmem_pages(struct page *page, unsigned int order);
-extern void free_kmem_pages(unsigned long addr, unsigned int order);
-
 #define __free_page(page) __free_pages((page), 0)
 #define free_page(addr) free_pages((addr), 0)
 
diff --git a/kernel/fork.c b/kernel/fork.c
index 1c84066..2fcde98 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -154,15 +154,15 @@ void __weak arch_release_thread_info(struct thread_info *ti)
 static struct thread_info *alloc_thread_info_node(struct task_struct *tsk,
 						  int node)
 {
-	struct page *page = alloc_kmem_pages_node(node, THREADINFO_GFP,
-						  THREAD_SIZE_ORDER);
+	struct page *page = alloc_pages_node(node, THREADINFO_GFP,
+					     THREAD_SIZE_ORDER);
 
 	return page ? page_address(page) : NULL;
 }
 
 static inline void free_thread_info(struct thread_info *ti)
 {
-	free_kmem_pages((unsigned long)ti, THREAD_SIZE_ORDER);
+	free_pages((unsigned long)ti, THREAD_SIZE_ORDER);
 }
 # else
 static struct kmem_cache *thread_info_cache;
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index af2c14b..50154da 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -3617,7 +3617,6 @@ struct mem_cgroup *__mem_cgroup_from_kmem(void *ptr)
 		if (!is_root_cache(cachep))
 			memcg = cachep->memcg_params.memcg;
 	} else {
-		/* page allocated by alloc_kmem_pages */
 		pc = lookup_page_cgroup(page);
 		if (PageCgroupUsed(pc))
 			memcg = pc->mem_cgroup;
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 1ae4ab3..9f02d80 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2828,19 +2828,6 @@ unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order)
 }
 EXPORT_SYMBOL(__get_free_pages);
 
-unsigned long __get_free_kmem_pages(gfp_t gfp_mask, unsigned int order)
-{
-	struct page *page;
-
-	VM_BUG_ON((gfp_mask & __GFP_HIGHMEM) != 0);
-
-	page = alloc_kmem_pages(gfp_mask, order);
-	if (!page)
-		return 0;
-	return (unsigned long) page_address(page);
-}
-EXPORT_SYMBOL(__get_free_kmem_pages);
-
 unsigned long get_zeroed_page(gfp_t gfp_mask)
 {
 	return __get_free_pages(gfp_mask | __GFP_ZERO, 0);
@@ -2869,58 +2856,6 @@ void free_pages(unsigned long addr, unsigned int order)
 
 EXPORT_SYMBOL(free_pages);
 
-/*
- * alloc_kmem_pages charges newly allocated pages to the kmem resource counter
- * of the current memory cgroup if __GFP_ACCOUNT is set, other than that it is
- * equivalent to alloc_pages.
- *
- * It should be used when the caller would like to use kmalloc, but since the
- * allocation is large, it has to fall back to the page allocator.
- */
-struct page *alloc_kmem_pages(gfp_t gfp_mask, unsigned int order)
-{
-	struct page *page;
-	struct mem_cgroup *memcg = NULL;
-
-	if (!memcg_kmem_newpage_charge(gfp_mask, &memcg, order))
-		return NULL;
-	page = alloc_pages(gfp_mask, order);
-	memcg_kmem_commit_charge(page, memcg, order);
-	return page;
-}
-
-struct page *alloc_kmem_pages_node(int nid, gfp_t gfp_mask, unsigned int order)
-{
-	struct page *page;
-	struct mem_cgroup *memcg = NULL;
-
-	if (!memcg_kmem_newpage_charge(gfp_mask, &memcg, order))
-		return NULL;
-	page = alloc_pages_node(nid, gfp_mask, order);
-	memcg_kmem_commit_charge(page, memcg, order);
-	return page;
-}
-
-/*
- * __free_kmem_pages and free_kmem_pages will free pages allocated with
- * alloc_kmem_pages.
- */
-void __free_kmem_pages(struct page *page, unsigned int order)
-{
-	memcg_kmem_uncharge_pages(page, order);
-	__free_pages(page, order);
-}
-EXPORT_SYMBOL(__free_kmem_pages);
-
-void free_kmem_pages(unsigned long addr, unsigned int order)
-{
-	if (addr != 0) {
-		VM_BUG_ON(!virt_addr_valid((void *)addr));
-		__free_kmem_pages(virt_to_page((void *)addr), order);
-	}
-}
-EXPORT_SYMBOL(free_kmem_pages);
-
 static void *make_alloc_exact(unsigned long addr, unsigned order, size_t size)
 {
 	if (addr) {
diff --git a/mm/slab_common.c b/mm/slab_common.c
index 18226a6..abad07d 100644
--- a/mm/slab_common.c
+++ b/mm/slab_common.c
@@ -784,7 +784,7 @@ void *kmalloc_order(size_t size, gfp_t flags, unsigned int order)
 	struct page *page;
 
 	flags |= __GFP_COMP;
-	page = alloc_kmem_pages(flags, order);
+	page = alloc_pages(flags, order);
 	ret = page ? page_address(page) : NULL;
 	kmemleak_alloc(ret, size, 1, flags);
 	kasan_kmalloc_large(ret, size);
diff --git a/mm/slub.c b/mm/slub.c
index c62e381..da1dbca 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -3308,7 +3308,7 @@ static void *kmalloc_large_node(size_t size, gfp_t flags, int node)
 	void *ptr = NULL;
 
 	flags |= __GFP_COMP | __GFP_NOTRACK;
-	page = alloc_kmem_pages_node(node, flags, get_order(size));
+	page = alloc_pages_node(node, flags, get_order(size));
 	if (page)
 		ptr = page_address(page);
 
@@ -3426,7 +3426,7 @@ void kfree(const void *x)
 		BUG_ON(!PageCompound(page));
 		kmemleak_free(x);
 		kasan_kfree_large(x);
-		__free_kmem_pages(page, compound_order(page));
+		__free_pages(page, compound_order(page));
 		return;
 	}
 	slab_free(page->slab_cache, page, object, _RET_IP_);
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index a8c2b28..b74bc34 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -1496,7 +1496,7 @@ static void __vunmap(const void *addr, int deallocate_pages)
 			struct page *page = area->pages[i];
 
 			BUG_ON(!page);
-			__free_kmem_pages(page, 0);
+			__free_page(page);
 		}
 
 		if (area->flags & VM_VPAGES)
@@ -1629,9 +1629,9 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
 		gfp_t tmp_mask = gfp_mask | __GFP_NOWARN;
 
 		if (node < 0)
-			page = alloc_kmem_pages(tmp_mask, order);
+			page = alloc_pages(tmp_mask, order);
 		else
-			page = alloc_kmem_pages_node(node, tmp_mask, order);
+			page = alloc_pages_node(node, tmp_mask, order);
 
 		if (unlikely(!page)) {
 			/* Successfully allocated i pages, free them in __vunmap() */
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index a59a108..0c94c3a 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -1469,8 +1469,8 @@ void nf_ct_free_hashtable(void *hash, unsigned int size)
 	if (is_vmalloc_addr(hash))
 		vfree(hash);
 	else
-		free_kmem_pages((unsigned long)hash,
-				get_order(sizeof(struct hlist_head) * size));
+		free_pages((unsigned long)hash,
+			   get_order(sizeof(struct hlist_head) * size));
 }
 EXPORT_SYMBOL_GPL(nf_ct_free_hashtable);
 
@@ -1597,7 +1597,7 @@ void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls)
 	BUILD_BUG_ON(sizeof(struct hlist_nulls_head) != sizeof(struct hlist_head));
 	nr_slots = *sizep = roundup(*sizep, PAGE_SIZE / sizeof(struct hlist_nulls_head));
 	sz = nr_slots * sizeof(struct hlist_nulls_head);
-	hash = (void *)__get_free_kmem_pages(GFP_KERNEL_ACCOUNT | __GFP_NOWARN | __GFP_ZERO,
+	hash = (void *)__get_free_pages(GFP_KERNEL_ACCOUNT | __GFP_NOWARN | __GFP_ZERO,
 					get_order(sz));
 	if (!hash) {
 		printk(KERN_WARNING "nf_conntrack: falling back to vmalloc.\n");
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 52d0d42..ecb5464 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -3701,8 +3701,8 @@ static void free_pg_vec(struct pgv *pg_vec, unsigned int order,
 			if (is_vmalloc_addr(pg_vec[i].buffer))
 				vfree(pg_vec[i].buffer);
 			else
-				free_kmem_pages((unsigned long)pg_vec[i].buffer,
-						order);
+				free_pages((unsigned long)pg_vec[i].buffer,
+					   order);
 			pg_vec[i].buffer = NULL;
 		}
 	}
@@ -3715,7 +3715,7 @@ static char *alloc_one_pg_vec_page(unsigned long order)
 	gfp_t gfp_flags = GFP_KERNEL_ACCOUNT | __GFP_COMP |
 			  __GFP_ZERO | __GFP_NOWARN | __GFP_NORETRY;
 
-	buffer = (char *) __get_free_kmem_pages(gfp_flags, order);
+	buffer = (char *) __get_free_pages(gfp_flags, order);
 
 	if (buffer)
 		return buffer;
@@ -3732,7 +3732,7 @@ static char *alloc_one_pg_vec_page(unsigned long order)
 	 * vmalloc failed, lets dig into swap here
 	 */
 	gfp_flags &= ~__GFP_NORETRY;
-	buffer = (char *)__get_free_kmem_pages(gfp_flags, order);
+	buffer = (char *)__get_free_pages(gfp_flags, order);
 	if (buffer)
 		return buffer;
 


More information about the Devel mailing list