On 03.10.2022 16:32, Michal Hocko wrote: > On Mon 03-10-22 15:47:10, Alexander Fedorov wrote: >> @@ -3197,17 +3197,30 @@ static void drain_obj_stock(struct memcg_stock_pcp *stock) >> stock->nr_bytes = 0; >> } >> >> - obj_cgroup_put(old); >> + /* >> + * Clear pointer before freeing memory so that >> + * drain_all_stock() -> obj_stock_flush_required() >> + * does not see a freed pointer. >> + */ >> stock->cached_objcg = NULL; >> + obj_cgroup_put(old); > > Do we need barrier() or something else to ensure there is no reordering? > I am not reallyu sure what kind of barriers are implied by the pcp ref > counting. obj_cgroup_put() -> kfree_rcu() -> synchronize_rcu() should take care of this: 3670 * Furthermore, if CPU A invoked synchronize_rcu(), which returned 3671 * to its caller on CPU B, then both CPU A and CPU B are guaranteed 3672 * to have executed a full memory barrier during the execution of 3673 * synchronize_rcu() -- even if CPU A and CPU B are the same CPU (but 3674 * again only if the system has more than one CPU). 3675 */ 3676 void synchronize_rcu(void) If I'm reading this correctly: - on SMP A==B and there will be a full memory barrier; - on UP we instead rely on the guarantee that schedule() implies a full memory barrier (and if there is no schedule() then there is no race).