Re: regression caused by cgroups optimization in 3.17-rc2

From: Dave Hansen
Date: Tue Sep 02 2014 - 16:19:09 EST


On 09/02/2014 12:05 PM, Dave Hansen wrote:
> It does not revert cleanly because of the hunks below. The code in
> those hunks was removed, so I tried running without properly merging
> them and it spews warnings because counter->usage is seen going negative.
>
> So, it doesn't appear we can quickly revert this.

I'm fairly confident that I missed some of the cases (especially in the
charge-moving code), but the attached patch does at least work around
the regression for me. It restores the original performance, or at
least gets _close_ to it.




---

b/mm/memcontrol.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)

diff -puN mm/memcontrol.c~try-partial-revert-of-root-charge-regression-patch mm/memcontrol.c
--- a/mm/memcontrol.c~try-partial-revert-of-root-charge-regression-patch 2014-09-02 12:20:11.209527453 -0700
+++ b/mm/memcontrol.c 2014-09-02 13:10:28.756736862 -0700
@@ -2534,6 +2534,8 @@ static int try_charge(struct mem_cgroup
unsigned long long size;
int ret = 0;

+ if (mem_cgroup_is_root(memcg))
+ goto done;
retry:
if (consume_stock(memcg, nr_pages))
goto done;
@@ -2640,6 +2642,9 @@ static void __mem_cgroup_cancel_local_ch
{
unsigned long bytes = nr_pages * PAGE_SIZE;

+ if (mem_cgroup_is_root(memcg))
+ return;
+
res_counter_uncharge_until(&memcg->res, memcg->res.parent, bytes);
if (do_swap_account)
res_counter_uncharge_until(&memcg->memsw,
@@ -6440,6 +6445,9 @@ void mem_cgroup_commit_charge(struct pag
VM_BUG_ON_PAGE(!page->mapping, page);
VM_BUG_ON_PAGE(PageLRU(page) && !lrucare, page);

+ if (mem_cgroup_is_root(memcg))
+ return;
+
if (mem_cgroup_disabled())
return;
/*
@@ -6484,6 +6492,9 @@ void mem_cgroup_cancel_charge(struct pag
{
unsigned int nr_pages = 1;

+ if (mem_cgroup_is_root(memcg))
+ return;
+
if (mem_cgroup_disabled())
return;
/*
@@ -6509,6 +6520,9 @@ static void uncharge_batch(struct mem_cg
{
unsigned long flags;

+ if (mem_cgroup_is_root(memcg))
+ return;
+
if (nr_mem)
res_counter_uncharge(&memcg->res, nr_mem * PAGE_SIZE);
if (nr_memsw)
_