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 <[email protected]> Cc: Johannes Weiner <[email protected]> Cc: Michal Hocko <[email protected]> Cc: Vladimir Davydov <[email protected]> Cc: Roman Gushchin <[email protected]> Cc: Shakeel Butt <[email protected]> Cc: Chris Down <[email protected]> Cc: Kirill Tkhai <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Andrew Morton <[email protected]> Cc: Tejun Heo <[email protected]> Cc: [email protected] Cc: [email protected] Cc: [email protected] --- 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

