memcg: fix memory migration of shmem swapcache

In the current implementation mem_cgroup_end_migration() decides whether
the page migration has succeeded or not by checking "oldpage->mapping".

But if we are tring to migrate a shmem swapcache, the page->mapping of it
is NULL from the begining, so the check would be invalid. As a result,
mem_cgroup_end_migration() assumes the migration has succeeded even if
it's not, so "newpage" would be freed while it's not uncharged.

This patch fixes it by passing mem_cgroup_end_migration() the result of
the page migration.

Signed-off-by: Daisuke Nishimura <nishimura@mxp.nes.nec.co.jp>
Reviewed-by: Minchan Kim <minchan.kim@gmail.com>
Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Acked-by: Balbir Singh <balbir@linux.vnet.ibm.com>
Cc: Minchan Kim <minchan.kim@gmail.com>
Reviewed-by: Johannes Weiner <hannes@cmpxchg.org>
Cc: Hugh Dickins <hughd@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by Daisuke Nishimura and committed by Linus Torvalds 50de1dd9 17295c88

+5 -7
+2 -3
include/linux/memcontrol.h
··· 98 98 mem_cgroup_prepare_migration(struct page *page, 99 99 struct page *newpage, struct mem_cgroup **ptr); 100 100 extern void mem_cgroup_end_migration(struct mem_cgroup *mem, 101 - struct page *oldpage, struct page *newpage); 101 + struct page *oldpage, struct page *newpage, bool migration_ok); 102 102 103 103 /* 104 104 * For memory reclaim. ··· 251 251 } 252 252 253 253 static inline void mem_cgroup_end_migration(struct mem_cgroup *mem, 254 - struct page *oldpage, 255 - struct page *newpage) 254 + struct page *oldpage, struct page *newpage, bool migration_ok) 256 255 { 257 256 } 258 257
+2 -3
mm/memcontrol.c
··· 2896 2896 2897 2897 /* remove redundant charge if migration failed*/ 2898 2898 void mem_cgroup_end_migration(struct mem_cgroup *mem, 2899 - struct page *oldpage, struct page *newpage) 2899 + struct page *oldpage, struct page *newpage, bool migration_ok) 2900 2900 { 2901 2901 struct page *used, *unused; 2902 2902 struct page_cgroup *pc; ··· 2905 2905 return; 2906 2906 /* blocks rmdir() */ 2907 2907 cgroup_exclude_rmdir(&mem->css); 2908 - /* at migration success, oldpage->mapping is NULL. */ 2909 - if (oldpage->mapping) { 2908 + if (!migration_ok) { 2910 2909 used = oldpage; 2911 2910 unused = newpage; 2912 2911 } else {
+1 -1
mm/migrate.c
··· 768 768 769 769 uncharge: 770 770 if (!charge) 771 - mem_cgroup_end_migration(mem, page, newpage); 771 + mem_cgroup_end_migration(mem, page, newpage, rc == 0); 772 772 unlock: 773 773 unlock_page(page); 774 774