On Tue, Jan 14, 2025 at 06:17:43PM -0800, Alexei Starovoitov wrote: > From: Alexei Starovoitov <ast@xxxxxxxxxx> > > Teach memcg to operate under trylock conditions when spinning locks > cannot be used. > > local_trylock might fail and this would lead to charge cache bypass if > the calling context doesn't allow spinning (gfpflags_allow_spinning). > In those cases charge the memcg counter directly and fail early if > that is not possible. This might cause a pre-mature charge failing > but it will allow an opportunistic charging that is safe from > try_alloc_pages path. > > Acked-by: Michal Hocko <mhocko@xxxxxxxx> > Signed-off-by: Alexei Starovoitov <ast@xxxxxxxxxx> Acked-by: Shakeel Butt <shakeel.butt@xxxxxxxxx> > @@ -1851,7 +1856,14 @@ static void refill_stock(struct mem_cgroup *memcg, unsigned int nr_pages) > { > unsigned long flags; > > - local_lock_irqsave(&memcg_stock.stock_lock, flags); > + if (!local_trylock_irqsave(&memcg_stock.stock_lock, flags)) { > + /* > + * In case of unlikely failure to lock percpu stock_lock > + * uncharge memcg directly. > + */ > + mem_cgroup_cancel_charge(memcg, nr_pages); mem_cgroup_cancel_charge() has been removed by a patch in mm-tree. Maybe we can either revive mem_cgroup_cancel_charge() or simply inline it here. > + return; > + } > __refill_stock(memcg, nr_pages); > local_unlock_irqrestore(&memcg_stock.stock_lock, flags); > }