aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm
diff options
context:
space:
mode:
authorVladimir Davydov <vdavydov@virtuozzo.com>2016-07-26 18:24:30 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-07-26 19:19:19 -0400
commit3e79ec7ddc33e5c69c20ce7f768d0e5c8b824f69 (patch)
treea53369a4d3b1cdc06be5b2e54ec7b47a4498ad86 /arch/x86/mm
parent5e8d35f849b1969b900695ae191326bfacf6bfc6 (diff)
arch: x86: charge page tables to kmemcg
Page tables can bite a relatively big chunk off system memory and their allocations are easy to trigger from userspace, so they should be accounted to kmemcg. This patch marks page table allocations as __GFP_ACCOUNT for x86. Note we must not charge allocations of kernel page tables, because they can be shared among processes from different cgroups so accounting them to a particular one can pin other cgroups for indefinitely long. So we clear __GFP_ACCOUNT flag if a page table is allocated for the kernel. Link: http://lkml.kernel.org/r/7d5c54f6a2bcbe76f03171689440003d87e6c742.1464079538.git.vdavydov@virtuozzo.com Signed-off-by: Vladimir Davydov <vdavydov@virtuozzo.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ingo Molnar <mingo@redhat.com> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Michal Hocko <mhocko@kernel.org> Cc: Eric Dumazet <eric.dumazet@gmail.com> Cc: Minchan Kim <minchan@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/x86/mm')
-rw-r--r--arch/x86/mm/pgtable.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
index aa0ff4b02a96..3feec5af4e67 100644
--- a/arch/x86/mm/pgtable.c
+++ b/arch/x86/mm/pgtable.c
@@ -6,7 +6,7 @@
6#include <asm/fixmap.h> 6#include <asm/fixmap.h>
7#include <asm/mtrr.h> 7#include <asm/mtrr.h>
8 8
9#define PGALLOC_GFP GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO 9#define PGALLOC_GFP (GFP_KERNEL_ACCOUNT | __GFP_NOTRACK | __GFP_ZERO)
10 10
11#ifdef CONFIG_HIGHPTE 11#ifdef CONFIG_HIGHPTE
12#define PGALLOC_USER_GFP __GFP_HIGHMEM 12#define PGALLOC_USER_GFP __GFP_HIGHMEM
@@ -18,7 +18,7 @@ gfp_t __userpte_alloc_gfp = PGALLOC_GFP | PGALLOC_USER_GFP;
18 18
19pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) 19pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
20{ 20{
21 return (pte_t *)__get_free_page(PGALLOC_GFP); 21 return (pte_t *)__get_free_page(PGALLOC_GFP & ~__GFP_ACCOUNT);
22} 22}
23 23
24pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address) 24pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address)
@@ -207,9 +207,13 @@ static int preallocate_pmds(struct mm_struct *mm, pmd_t *pmds[])
207{ 207{
208 int i; 208 int i;
209 bool failed = false; 209 bool failed = false;
210 gfp_t gfp = PGALLOC_GFP;
211
212 if (mm == &init_mm)
213 gfp &= ~__GFP_ACCOUNT;
210 214
211 for(i = 0; i < PREALLOCATED_PMDS; i++) { 215 for(i = 0; i < PREALLOCATED_PMDS; i++) {
212 pmd_t *pmd = (pmd_t *)__get_free_page(PGALLOC_GFP); 216 pmd_t *pmd = (pmd_t *)__get_free_page(gfp);
213 if (!pmd) 217 if (!pmd)
214 failed = true; 218 failed = true;
215 if (pmd && !pgtable_pmd_page_ctor(virt_to_page(pmd))) { 219 if (pmd && !pgtable_pmd_page_ctor(virt_to_page(pmd))) {