memcg: return -EINTR at bypassing try_charge()

This patch is a fix for memcg-simplify-lru-handling-by-new-rule.patch
When running testprogram and stop it by Ctrl-C, add_lru/del_lru
will find pc->mem_cgroup is NULL and get panic. The reason
is bypass code in try_charge().

At try_charge(), it checks the thread is fatal or not as..
fatal_signal_pending() or TIF_MEMDIE. In this case, __try_charge()
returns 0(success) with setting *ptr as NULL.

Now, lruvec are deteremined by pc->mem_cgroup. So, it's better
to reset pc->mem_cgroup as root_mem_cgroup. This patch does
following change in try_charge()
  1. return -EINTR at bypassing.
  2. set *ptr = root_mem_cgroup at bypassing.

By this change, in page fault / radix-tree-insert path,
the page will be charged against root_mem_cgroup and the thread's
operations will go ahead without trouble. In other path,
migration or move_account etc..., -EINTR will stop the operation.
(may need some cleanup later..)

After this change, pc->mem_cgroup will have valid pointer if
the page is used.

Changelog: v2 -> v3
 - handle !mm case in another way.
 - removed redundant commments
 - fixed move_parent bug of uninitialized pointer
Changelog: v1 -> v2
 - returns -EINTR at bypassing.
 - change error code handling at callers.
 - changed the name of patch.

Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Michal Hocko <mhocko@suse.cz>
Cc: Miklos Szeredi <mszeredi@suse.cz>
Cc: Ying Han <yinghan@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
1 file changed