We are going to move lruvec getting out of lru_lock, the only unsafe part is lruvec->pgdat syncing when memory node hot pluging. Splitting out the lruvec->pgdat assignment now and will put it in lruvec lru_lock protection. No function changes in this patch now. Signed-off-by: Alex Shi <alex.shi@xxxxxxxxxxxxxxxxx> Cc: Johannes Weiner <hannes@xxxxxxxxxxx> Cc: Michal Hocko <mhocko@xxxxxxxxxx> Cc: Vladimir Davydov <vdavydov.dev@xxxxxxxxx> Cc: Roman Gushchin <guro@xxxxxx> Cc: Shakeel Butt <shakeelb@xxxxxxxxxx> Cc: Chris Down <chris@xxxxxxxxxxxxxx> Cc: Kirill Tkhai <ktkhai@xxxxxxxxxxxxx> Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx> Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> Cc: Tejun Heo <tj@xxxxxxxxxx> Cc: cgroups@xxxxxxxxxxxxxxx Cc: linux-kernel@xxxxxxxxxxxxxxx Cc: linux-mm@xxxxxxxxx --- include/linux/memcontrol.h | 24 +++++++++++++++++------- mm/memcontrol.c | 8 +------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 2cd4359cb38c..95b3d9885ab6 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -359,6 +359,17 @@ void mem_cgroup_cancel_charge(struct page *page, struct mem_cgroup *memcg, return memcg->nodeinfo[nid]; } +static void sync_lruvec_pgdat(struct lruvec *lruvec, struct pglist_data *pgdat) +{ + /* + * Since a node can be onlined after the mem_cgroup was created, + * we have to be prepared to initialize lruvec->pgdat here; + * and if offlined then reonlined, we need to reinitialize it. + */ + if (!mem_cgroup_disabled() && unlikely(lruvec->pgdat != pgdat)) + lruvec->pgdat = pgdat; +} + /** * mem_cgroup_lruvec - get the lru list vector for a node or a memcg zone * @node: node of the wanted lruvec @@ -382,13 +393,7 @@ static inline struct lruvec *mem_cgroup_lruvec(struct pglist_data *pgdat, mz = mem_cgroup_nodeinfo(memcg, pgdat->node_id); lruvec = &mz->lruvec; out: - /* - * Since a node can be onlined after the mem_cgroup was created, - * we have to be prepared to initialize lruvec->pgdat here; - * and if offlined then reonlined, we need to reinitialize it. - */ - if (unlikely(lruvec->pgdat != pgdat)) - lruvec->pgdat = pgdat; + sync_lruvec_pgdat(lruvec, pgdat); return lruvec; } @@ -857,6 +862,11 @@ static inline void mem_cgroup_migrate(struct page *old, struct page *new) { } +static inline void sync_lruvec_pgdat(struct lruvec *lruvec, + struct pglist_data *pgdat) +{ +} + static inline struct lruvec *mem_cgroup_lruvec(struct pglist_data *pgdat, struct mem_cgroup *memcg) { diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 2792b8ed405f..e8a1b0d95ba8 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -1257,13 +1257,7 @@ struct lruvec *mem_cgroup_page_lruvec(struct page *page, struct pglist_data *pgd mz = mem_cgroup_page_nodeinfo(memcg, page); lruvec = &mz->lruvec; out: - /* - * Since a node can be onlined after the mem_cgroup was created, - * we have to be prepared to initialize lruvec->zone here; - * and if offlined then reonlined, we need to reinitialize it. - */ - if (unlikely(lruvec->pgdat != pgdat)) - lruvec->pgdat = pgdat; + sync_lruvec_pgdat(lruvec, pgdat); return lruvec; } -- 1.8.3.1