From: aarcange@redhat.com
To: linux-mm@kvack.org, akpm@linux-foundation.org
Cc: Marcelo Tosatti <mtosatti@redhat.com>,
Adam Litke <agl@us.ibm.com>, Avi Kivity <avi@redhat.com>,
Izik Eidus <ieidus@redhat.com>,
Hugh Dickins <hugh.dickins@tiscali.co.uk>,
Nick Piggin <npiggin@suse.de>, Rik van Riel <riel@redhat.com>,
Mel Gorman <mel@csn.ul.ie>, Dave Hansen <dave@linux.vnet.ibm.com>,
Benjamin Herrenschmidt <benh@kernel.crashing.org>,
Ingo Molnar <mingo@elte.hu>, Mike Travis <travis@sgi.com>,
KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>,
Christoph Lameter <cl@linux-foundation.org>,
Chris Wright <chrisw@sous-sol.org>,
bpicco@redhat.com,
KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>,
Balbir Singh <balbir@linux.vnet.ibm.com>,
Arnd Bergmann <arnd@arndb.de>,
"Michael S. Tsirkin" <mst@redhat.com>,
Peter Zijlstra <peterz@infradead.org>,
Andrea Arcangeli <aarcange@redhat.com>
Subject: [patch 32/35] memcg compound
Date: Tue, 09 Mar 2010 20:39:33 +0100 [thread overview]
Message-ID: <20100309194316.921051285@redhat.com> (raw)
In-Reply-To: 20100309193901.207868642@redhat.com
[-- Attachment #1: memcg_compound --]
[-- Type: text/plain, Size: 8757 bytes --]
From: Andrea Arcangeli <aarcange@redhat.com>
Teach memcg to charge/uncharge compound pages.
Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
Acked-by: Rik van Riel <riel@redhat.com>
---
Documentation/cgroups/memory.txt | 4 ++
mm/memcontrol.c | 76 +++++++++++++++++++++++----------------
2 files changed, 49 insertions(+), 31 deletions(-)
--- a/Documentation/cgroups/memory.txt
+++ b/Documentation/cgroups/memory.txt
@@ -4,6 +4,10 @@ NOTE: The Memory Resource Controller has
to as the memory controller in this document. Do not confuse memory controller
used here with the memory controller that is used in hardware.
+NOTE: When in this documentation we refer to PAGE_SIZE, we actually
+mean the real page size of the page being accounted which is bigger than
+PAGE_SIZE for compound pages.
+
Salient features
a. Enable control of Anonymous, Page Cache (mapped and unmapped) and
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1401,8 +1401,8 @@ static int __cpuinit memcg_stock_cpu_cal
* oom-killer can be invoked.
*/
static int __mem_cgroup_try_charge(struct mm_struct *mm,
- gfp_t gfp_mask, struct mem_cgroup **memcg,
- bool oom, struct page *page)
+ gfp_t gfp_mask, struct mem_cgroup **memcg,
+ bool oom, struct page *page, int page_size)
{
struct mem_cgroup *mem, *mem_over_limit;
int nr_retries = MEM_CGROUP_RECLAIM_RETRIES;
@@ -1415,6 +1415,9 @@ static int __mem_cgroup_try_charge(struc
return 0;
}
+ if (PageTransHuge(page))
+ csize = page_size;
+
/*
* We always charge the cgroup the mm_struct belongs to.
* The mm_struct's mem_cgroup changes on task migration if the
@@ -1439,8 +1442,9 @@ static int __mem_cgroup_try_charge(struc
int ret = 0;
unsigned long flags = 0;
- if (consume_stock(mem))
- goto charged;
+ if (!PageTransHuge(page))
+ if (consume_stock(mem))
+ goto charged;
ret = res_counter_charge(&mem->res, csize, &fail_res);
if (likely(!ret)) {
@@ -1460,7 +1464,7 @@ static int __mem_cgroup_try_charge(struc
res);
/* reduce request size and retry */
- if (csize > PAGE_SIZE) {
+ if (csize > page_size) {
csize = PAGE_SIZE;
continue;
}
@@ -1491,7 +1495,7 @@ static int __mem_cgroup_try_charge(struc
goto nomem;
}
}
- if (csize > PAGE_SIZE)
+ if (csize > page_size)
refill_stock(mem, csize - PAGE_SIZE);
charged:
/*
@@ -1512,12 +1516,12 @@ nomem:
* This function is for that and do uncharge, put css's refcnt.
* gotten by try_charge().
*/
-static void mem_cgroup_cancel_charge(struct mem_cgroup *mem)
+static void mem_cgroup_cancel_charge(struct mem_cgroup *mem, int page_size)
{
if (!mem_cgroup_is_root(mem)) {
- res_counter_uncharge(&mem->res, PAGE_SIZE);
+ res_counter_uncharge(&mem->res, page_size);
if (do_swap_account)
- res_counter_uncharge(&mem->memsw, PAGE_SIZE);
+ res_counter_uncharge(&mem->memsw, page_size);
}
css_put(&mem->css);
}
@@ -1575,8 +1579,9 @@ struct mem_cgroup *try_get_mem_cgroup_fr
*/
static void __mem_cgroup_commit_charge(struct mem_cgroup *mem,
- struct page_cgroup *pc,
- enum charge_type ctype)
+ struct page_cgroup *pc,
+ enum charge_type ctype,
+ int page_size)
{
/* try_charge() can return NULL to *memcg, taking care of it. */
if (!mem)
@@ -1585,7 +1590,7 @@ static void __mem_cgroup_commit_charge(s
lock_page_cgroup(pc);
if (unlikely(PageCgroupUsed(pc))) {
unlock_page_cgroup(pc);
- mem_cgroup_cancel_charge(mem);
+ mem_cgroup_cancel_charge(mem, page_size);
return;
}
@@ -1722,7 +1727,8 @@ static int mem_cgroup_move_parent(struct
goto put;
parent = mem_cgroup_from_cont(pcg);
- ret = __mem_cgroup_try_charge(NULL, gfp_mask, &parent, false, page);
+ ret = __mem_cgroup_try_charge(NULL, gfp_mask, &parent, false, page,
+ PAGE_SIZE);
if (ret || !parent)
goto put_back;
@@ -1730,7 +1736,7 @@ static int mem_cgroup_move_parent(struct
if (!ret)
css_put(&parent->css); /* drop extra refcnt by try_charge() */
else
- mem_cgroup_cancel_charge(parent); /* does css_put */
+ mem_cgroup_cancel_charge(parent, PAGE_SIZE); /* does css_put */
put_back:
putback_lru_page(page);
put:
@@ -1752,6 +1758,10 @@ static int mem_cgroup_charge_common(stru
struct mem_cgroup *mem;
struct page_cgroup *pc;
int ret;
+ int page_size = PAGE_SIZE;
+
+ if (PageTransHuge(page))
+ page_size <<= compound_order(page);
pc = lookup_page_cgroup(page);
/* can happen at boot */
@@ -1760,11 +1770,12 @@ static int mem_cgroup_charge_common(stru
prefetchw(pc);
mem = memcg;
- ret = __mem_cgroup_try_charge(mm, gfp_mask, &mem, true, page);
+ ret = __mem_cgroup_try_charge(mm, gfp_mask, &mem, true, page,
+ page_size);
if (ret || !mem)
return ret;
- __mem_cgroup_commit_charge(mem, pc, ctype);
+ __mem_cgroup_commit_charge(mem, pc, ctype, page_size);
return 0;
}
@@ -1773,8 +1784,6 @@ int mem_cgroup_newpage_charge(struct pag
{
if (mem_cgroup_disabled())
return 0;
- if (PageCompound(page))
- return 0;
/*
* If already mapped, we don't have to account.
* If page cache, page->mapping has address_space.
@@ -1787,7 +1796,7 @@ int mem_cgroup_newpage_charge(struct pag
if (unlikely(!mm))
mm = &init_mm;
return mem_cgroup_charge_common(page, mm, gfp_mask,
- MEM_CGROUP_CHARGE_TYPE_MAPPED, NULL);
+ MEM_CGROUP_CHARGE_TYPE_MAPPED, NULL);
}
static void
@@ -1880,14 +1889,14 @@ int mem_cgroup_try_charge_swapin(struct
if (!mem)
goto charge_cur_mm;
*ptr = mem;
- ret = __mem_cgroup_try_charge(NULL, mask, ptr, true, page);
+ ret = __mem_cgroup_try_charge(NULL, mask, ptr, true, page, PAGE_SIZE);
/* drop extra refcnt from tryget */
css_put(&mem->css);
return ret;
charge_cur_mm:
if (unlikely(!mm))
mm = &init_mm;
- return __mem_cgroup_try_charge(mm, mask, ptr, true, page);
+ return __mem_cgroup_try_charge(mm, mask, ptr, true, page, PAGE_SIZE);
}
static void
@@ -1903,7 +1912,7 @@ __mem_cgroup_commit_charge_swapin(struct
cgroup_exclude_rmdir(&ptr->css);
pc = lookup_page_cgroup(page);
mem_cgroup_lru_del_before_commit_swapcache(page);
- __mem_cgroup_commit_charge(ptr, pc, ctype);
+ __mem_cgroup_commit_charge(ptr, pc, ctype, PAGE_SIZE);
mem_cgroup_lru_add_after_commit_swapcache(page);
/*
* Now swap is on-memory. This means this page may be
@@ -1952,11 +1961,12 @@ void mem_cgroup_cancel_charge_swapin(str
return;
if (!mem)
return;
- mem_cgroup_cancel_charge(mem);
+ mem_cgroup_cancel_charge(mem, PAGE_SIZE);
}
static void
-__do_uncharge(struct mem_cgroup *mem, const enum charge_type ctype)
+__do_uncharge(struct mem_cgroup *mem, const enum charge_type ctype,
+ int page_size)
{
struct memcg_batch_info *batch = NULL;
bool uncharge_memsw = true;
@@ -1989,14 +1999,14 @@ __do_uncharge(struct mem_cgroup *mem, co
if (batch->memcg != mem)
goto direct_uncharge;
/* remember freed charge and uncharge it later */
- batch->bytes += PAGE_SIZE;
+ batch->bytes += page_size;
if (uncharge_memsw)
- batch->memsw_bytes += PAGE_SIZE;
+ batch->memsw_bytes += page_size;
return;
direct_uncharge:
- res_counter_uncharge(&mem->res, PAGE_SIZE);
+ res_counter_uncharge(&mem->res, page_size);
if (uncharge_memsw)
- res_counter_uncharge(&mem->memsw, PAGE_SIZE);
+ res_counter_uncharge(&mem->memsw, page_size);
return;
}
@@ -2009,6 +2019,10 @@ __mem_cgroup_uncharge_common(struct page
struct page_cgroup *pc;
struct mem_cgroup *mem = NULL;
struct mem_cgroup_per_zone *mz;
+ int page_size = PAGE_SIZE;
+
+ if (PageTransHuge(page))
+ page_size <<= compound_order(page);
if (mem_cgroup_disabled())
return NULL;
@@ -2048,7 +2062,7 @@ __mem_cgroup_uncharge_common(struct page
}
if (!mem_cgroup_is_root(mem))
- __do_uncharge(mem, ctype);
+ __do_uncharge(mem, ctype, page_size);
if (ctype == MEM_CGROUP_CHARGE_TYPE_SWAPOUT)
mem_cgroup_swap_statistics(mem, true);
mem_cgroup_charge_statistics(mem, pc, false);
@@ -2217,7 +2231,7 @@ int mem_cgroup_prepare_migration(struct
if (mem) {
ret = __mem_cgroup_try_charge(NULL, GFP_KERNEL, &mem, false,
- page);
+ page, PAGE_SIZE);
css_put(&mem->css);
}
*ptr = mem;
@@ -2260,7 +2274,7 @@ void mem_cgroup_end_migration(struct mem
* __mem_cgroup_commit_charge() check PCG_USED bit of page_cgroup.
* So, double-counting is effectively avoided.
*/
- __mem_cgroup_commit_charge(mem, pc, ctype);
+ __mem_cgroup_commit_charge(mem, pc, ctype, PAGE_SIZE);
/*
* Both of oldpage and newpage are still under lock_page().
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next prev parent reply other threads:[~2010-03-09 19:44 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-03-09 19:39 [patch 00/35] Transparent Hugepage support #13 aarcange
2010-03-09 19:39 ` [patch 01/35] define MADV_HUGEPAGE aarcange
2010-03-09 19:39 ` [patch 02/35] compound_lock aarcange
2010-03-09 19:39 ` [patch 03/35] alter compound get_page/put_page aarcange
2010-03-09 19:39 ` [patch 04/35] update futex compound knowledge aarcange
2010-03-09 19:39 ` [patch 05/35] fix bad_page to show the real reason the page is bad aarcange
2010-03-09 19:39 ` [patch 06/35] clear compound mapping aarcange
2010-03-09 19:39 ` [patch 07/35] add native_set_pmd_at aarcange
2010-03-09 19:39 ` [patch 08/35] add pmd paravirt ops aarcange
2010-03-09 19:39 ` [patch 09/35] no paravirt version of pmd ops aarcange
2010-03-09 19:39 ` [patch 10/35] export maybe_mkwrite aarcange
2010-03-09 19:39 ` [patch 11/35] comment reminder in destroy_compound_page aarcange
2010-03-09 19:39 ` [patch 12/35] config_transparent_hugepage aarcange
2010-03-09 19:39 ` [patch 13/35] special pmd_trans_* functions aarcange
2010-03-09 19:39 ` [patch 14/35] add pmd mangling generic functions aarcange
2010-03-09 19:39 ` [patch 15/35] add pmd mangling functions to x86 aarcange
2010-03-09 19:39 ` [patch 16/35] bail out gup_fast on splitting pmd aarcange
2010-03-09 19:39 ` [patch 17/35] pte alloc trans splitting aarcange
2010-03-09 19:39 ` [patch 18/35] add pmd mmu_notifier helpers aarcange
2010-03-09 19:39 ` [patch 19/35] clear page compound aarcange
2010-03-09 19:39 ` [patch 20/35] add pmd_huge_pte to mm_struct aarcange
2010-03-09 19:39 ` [patch 21/35] split_huge_page_mm/vma aarcange
2010-03-09 19:39 ` [patch 22/35] split_huge_page paging aarcange
2010-03-09 19:39 ` [patch 23/35] clear_copy_huge_page aarcange
2010-03-09 19:39 ` [patch 24/35] kvm mmu transparent hugepage support aarcange
2010-03-09 19:39 ` [patch 25/35] _GFP_NO_KSWAPD aarcange
2010-03-09 19:39 ` [patch 26/35] dont alloc harder for gfp nomemalloc even if nowait aarcange
2010-03-09 19:39 ` [patch 27/35] transparent hugepage core aarcange
2010-03-09 19:39 ` [patch 28/35] adapt to mm_counter in -mm aarcange
2010-03-09 19:39 ` [patch 29/35] verify pmd_trans_huge isnt leaking aarcange
2010-03-09 19:39 ` [patch 30/35] madvise(MADV_HUGEPAGE) aarcange
2010-03-09 19:39 ` [patch 31/35] pmd_trans_huge migrate bugcheck aarcange
2010-03-09 19:39 ` aarcange [this message]
2010-03-09 19:39 ` [patch 33/35] memcg huge memory aarcange
2010-03-09 19:39 ` [patch 34/35] transparent hugepage vmstat aarcange
2010-03-09 19:39 ` [patch 35/35] khugepaged aarcange
2010-03-11 0:55 ` [patch 00/35] Transparent Hugepage support #13 Andrea Arcangeli
-- strict thread matches above, loose matches on Subject: below --
2010-02-26 20:04 [patch 00/35] Transparent Hugepage support #12 aarcange
2010-02-26 20:05 ` [patch 32/35] memcg compound aarcange
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20100309194316.921051285@redhat.com \
--to=aarcange@redhat.com \
--cc=agl@us.ibm.com \
--cc=akpm@linux-foundation.org \
--cc=arnd@arndb.de \
--cc=avi@redhat.com \
--cc=balbir@linux.vnet.ibm.com \
--cc=benh@kernel.crashing.org \
--cc=bpicco@redhat.com \
--cc=chrisw@sous-sol.org \
--cc=cl@linux-foundation.org \
--cc=dave@linux.vnet.ibm.com \
--cc=hugh.dickins@tiscali.co.uk \
--cc=ieidus@redhat.com \
--cc=kamezawa.hiroyu@jp.fujitsu.com \
--cc=kosaki.motohiro@jp.fujitsu.com \
--cc=linux-mm@kvack.org \
--cc=mel@csn.ul.ie \
--cc=mingo@elte.hu \
--cc=mst@redhat.com \
--cc=mtosatti@redhat.com \
--cc=npiggin@suse.de \
--cc=peterz@infradead.org \
--cc=riel@redhat.com \
--cc=travis@sgi.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.