Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mm: memcg: factor out trylock_stock() and unlock_stock()

Patch series "memcg: obj stock and slab stat caching cleanups".

This is a follow-up to `[PATCH] memcg: fix slab accounting in
refill_obj_stock() trylock path`. The way the slab stat cache and the
objcg charge cache interact appears a bit too fragile. This series
factors those paths apart as much as practical.


This patch (of 5):

Consolidate the local lock acquisition and the local stock lookup. This
allows subsequent patches to use !!stock as an easy way to disambiguate
the locked vs. contended cases through the callstack.

Link: https://lkml.kernel.org/r/20260302195305.620713-1-hannes@cmpxchg.org
Link: https://lkml.kernel.org/r/20260302195305.620713-2-hannes@cmpxchg.org
Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
Acked-by: Shakeel Butt <shakeel.butt@linux.dev>
Acked-by: Roman Gushchin <roman.gushchin@linux.dev>
Reviewed-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
Reviewed-by: Hao Li <hao.li@linux.dev>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Muchun Song <muchun.song@linux.dev>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Johannes Weiner and committed by
Andrew Morton
9f2541d9 9970a9a2

+19 -6
+19 -6
mm/memcontrol.c
··· 2950 2950 obj_cgroup_put(objcg); 2951 2951 } 2952 2952 2953 + static struct obj_stock_pcp *trylock_stock(void) 2954 + { 2955 + if (local_trylock(&obj_stock.lock)) 2956 + return this_cpu_ptr(&obj_stock); 2957 + 2958 + return NULL; 2959 + } 2960 + 2961 + static void unlock_stock(struct obj_stock_pcp *stock) 2962 + { 2963 + local_unlock(&obj_stock.lock); 2964 + } 2965 + 2953 2966 static void __account_obj_stock(struct obj_cgroup *objcg, 2954 2967 struct obj_stock_pcp *stock, int nr, 2955 2968 struct pglist_data *pgdat, enum node_stat_item idx) ··· 3018 3005 struct obj_stock_pcp *stock; 3019 3006 bool ret = false; 3020 3007 3021 - if (!local_trylock(&obj_stock.lock)) 3008 + stock = trylock_stock(); 3009 + if (!stock) 3022 3010 return ret; 3023 3011 3024 - stock = this_cpu_ptr(&obj_stock); 3025 3012 if (objcg == READ_ONCE(stock->cached_objcg) && stock->nr_bytes >= nr_bytes) { 3026 3013 stock->nr_bytes -= nr_bytes; 3027 3014 ret = true; ··· 3030 3017 __account_obj_stock(objcg, stock, nr_bytes, pgdat, idx); 3031 3018 } 3032 3019 3033 - local_unlock(&obj_stock.lock); 3020 + unlock_stock(stock); 3034 3021 3035 3022 return ret; 3036 3023 } ··· 3121 3108 struct obj_stock_pcp *stock; 3122 3109 unsigned int nr_pages = 0; 3123 3110 3124 - if (!local_trylock(&obj_stock.lock)) { 3111 + stock = trylock_stock(); 3112 + if (!stock) { 3125 3113 if (pgdat) 3126 3114 mod_objcg_mlstate(objcg, pgdat, idx, nr_acct); 3127 3115 nr_pages = nr_bytes >> PAGE_SHIFT; ··· 3131 3117 goto out; 3132 3118 } 3133 3119 3134 - stock = this_cpu_ptr(&obj_stock); 3135 3120 if (READ_ONCE(stock->cached_objcg) != objcg) { /* reset if necessary */ 3136 3121 drain_obj_stock(stock); 3137 3122 obj_cgroup_get(objcg); ··· 3150 3137 stock->nr_bytes &= (PAGE_SIZE - 1); 3151 3138 } 3152 3139 3153 - local_unlock(&obj_stock.lock); 3140 + unlock_stock(stock); 3154 3141 out: 3155 3142 if (nr_pages) 3156 3143 obj_cgroup_uncharge_pages(objcg, nr_pages);