On Mon, Jan 27, 2020 at 09:34:32AM -0800, Roman Gushchin wrote: > @@ -757,13 +757,12 @@ void __mod_lruvec_state(struct lruvec *lruvec, enum node_stat_item idx, > > void __mod_lruvec_slab_state(void *p, enum node_stat_item idx, int val) > { > - struct page *page = virt_to_head_page(p); > - pg_data_t *pgdat = page_pgdat(page); > + pg_data_t *pgdat = page_pgdat(virt_to_page(p)); > struct mem_cgroup *memcg; > struct lruvec *lruvec; > > rcu_read_lock(); > - memcg = memcg_from_slab_page(page); > + memcg = mem_cgroup_from_obj(p); > > /* Untracked pages have no memcg, no lruvec. Update only the node */ > if (!memcg || memcg == root_mem_cgroup) { This function is specifically for slab objects. Why does it need the indirection and additional branch here? If memcg_from_slab_page() is going away later, I think the conversion to this new helper should happen at that point in the series, not now.