Commit a0b5b414 authored by Johannes Weiner's avatar Johannes Weiner Committed by Linus Torvalds

mm: memcontrol: update page->mem_cgroup stability rules

The previous patches have simplified the access rules around
page->mem_cgroup somewhat:

1. We never change page->mem_cgroup while the page is isolated by
   somebody else.  This was by far the biggest exception to our rules and
   it didn't stop at lock_page() or lock_page_memcg().

2. We charge pages before they get put into page tables now, so the
   somewhat fishy rule about "can be in page table as long as it's still
   locked" is now gone and boiled down to having an exclusive reference to
   the page.

Document the new rules.  Any of the following will stabilize the
page->mem_cgroup association:

- the page lock
- LRU isolation
- lock_page_memcg()
- exclusive access to the page
Signed-off-by: default avatarJohannes Weiner <hannes@cmpxchg.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Reviewed-by: default avatarAlex Shi <alex.shi@linux.alibaba.com>
Reviewed-by: default avatarJoonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: "Kirill A. Shutemov" <kirill@shutemov.name>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Roman Gushchin <guro@fb.com>
Cc: Shakeel Butt <shakeelb@google.com>
Cc: Balbir Singh <bsingharora@gmail.com>
Link: http://lkml.kernel.org/r/20200508183105.225460-20-hannes@cmpxchg.orgSigned-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent d9eb1ea2
...@@ -1201,9 +1201,8 @@ int mem_cgroup_scan_tasks(struct mem_cgroup *memcg, ...@@ -1201,9 +1201,8 @@ int mem_cgroup_scan_tasks(struct mem_cgroup *memcg,
* @page: the page * @page: the page
* @pgdat: pgdat of the page * @pgdat: pgdat of the page
* *
* This function is only safe when following the LRU page isolation * This function relies on page->mem_cgroup being stable - see the
* and putback protocol: the LRU lock must be held, and the page must * access rules in commit_charge().
* either be PageLRU() or the caller must have isolated/allocated it.
*/ */
struct lruvec *mem_cgroup_page_lruvec(struct page *page, struct pglist_data *pgdat) struct lruvec *mem_cgroup_page_lruvec(struct page *page, struct pglist_data *pgdat)
{ {
...@@ -2659,18 +2658,12 @@ static void commit_charge(struct page *page, struct mem_cgroup *memcg) ...@@ -2659,18 +2658,12 @@ static void commit_charge(struct page *page, struct mem_cgroup *memcg)
{ {
VM_BUG_ON_PAGE(page->mem_cgroup, page); VM_BUG_ON_PAGE(page->mem_cgroup, page);
/* /*
* Nobody should be changing or seriously looking at * Any of the following ensures page->mem_cgroup stability:
* page->mem_cgroup at this point:
*
* - the page is uncharged
*
* - the page is off-LRU
*
* - an anonymous fault has exclusive page access, except for
* a locked page table
* *
* - a page cache insertion, a swapin fault, or a migration * - the page lock
* have the page locked * - LRU isolation
* - lock_page_memcg()
* - exclusive reference
*/ */
page->mem_cgroup = memcg; page->mem_cgroup = memcg;
} }
......
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