Commit c09ff089 authored by Hugh Dickins's avatar Hugh Dickins Committed by Linus Torvalds

page_cgroup: fix horrid swap accounting regression

Why is memcg's swap accounting so broken? Insane counts, wrong
ownership, unfreeable structures, which later get freed and then
accessed after free.

Turns out to be a tiny a little 3.3-rc1 regression in 9fb4b7cc
"page_cgroup: add helper function to get swap_cgroup": the helper
function (actually named lookup_swap_cgroup()) returns an address using
void* arithmetic, but the structure in question is a short.
Signed-off-by: default avatarHugh Dickins <hughd@google.com>
Reviewed-by: default avatarBob Liu <lliubbo@gmail.com>
Cc: Michal Hocko <mhocko@suse.cz>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Johannes Weiner <jweiner@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent f3969bf7
...@@ -379,13 +379,15 @@ static struct swap_cgroup *lookup_swap_cgroup(swp_entry_t ent, ...@@ -379,13 +379,15 @@ static struct swap_cgroup *lookup_swap_cgroup(swp_entry_t ent,
pgoff_t offset = swp_offset(ent); pgoff_t offset = swp_offset(ent);
struct swap_cgroup_ctrl *ctrl; struct swap_cgroup_ctrl *ctrl;
struct page *mappage; struct page *mappage;
struct swap_cgroup *sc;
ctrl = &swap_cgroup_ctrl[swp_type(ent)]; ctrl = &swap_cgroup_ctrl[swp_type(ent)];
if (ctrlp) if (ctrlp)
*ctrlp = ctrl; *ctrlp = ctrl;
mappage = ctrl->map[offset / SC_PER_PAGE]; mappage = ctrl->map[offset / SC_PER_PAGE];
return page_address(mappage) + offset % SC_PER_PAGE; sc = page_address(mappage);
return sc + offset % SC_PER_PAGE;
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment