Skip to content

Commit 6f19121

Browse files
committed
mm/slub: cleanup and repurpose some stat items
A number of stat items related to cpu slabs became unused, remove them. Two of those were ALLOC_FASTPATH and FREE_FASTPATH. But instead of removing those, use them instead of ALLOC_PCS and FREE_PCS, since sheaves are the new (and only) fastpaths, Remove the recently added _PCS variants instead. Change where FREE_SLOWPATH is counted so that it only counts freeing of objects by slab users that (for whatever reason) do not go to a percpu sheaf, and not all (including internal) callers of __slab_free(). Thus sheaf flushing (already counted by SHEAF_FLUSH) does not affect FREE_SLOWPATH anymore. This matches how ALLOC_SLOWPATH doesn't count sheaf refills (counted by SHEAF_REFILL). Reviewed-by: Hao Li <hao.li@linux.dev> Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
1 parent fb016a5 commit 6f19121

1 file changed

Lines changed: 26 additions & 57 deletions

File tree

mm/slub.c

Lines changed: 26 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -335,33 +335,19 @@ enum add_mode {
335335
};
336336

337337
enum stat_item {
338-
ALLOC_PCS, /* Allocation from percpu sheaf */
339-
ALLOC_FASTPATH, /* Allocation from cpu slab */
340-
ALLOC_SLOWPATH, /* Allocation by getting a new cpu slab */
341-
FREE_PCS, /* Free to percpu sheaf */
338+
ALLOC_FASTPATH, /* Allocation from percpu sheaves */
339+
ALLOC_SLOWPATH, /* Allocation from partial or new slab */
342340
FREE_RCU_SHEAF, /* Free to rcu_free sheaf */
343341
FREE_RCU_SHEAF_FAIL, /* Failed to free to a rcu_free sheaf */
344-
FREE_FASTPATH, /* Free to cpu slab */
345-
FREE_SLOWPATH, /* Freeing not to cpu slab */
342+
FREE_FASTPATH, /* Free to percpu sheaves */
343+
FREE_SLOWPATH, /* Free to a slab */
346344
FREE_ADD_PARTIAL, /* Freeing moves slab to partial list */
347345
FREE_REMOVE_PARTIAL, /* Freeing removes last object */
348-
ALLOC_FROM_PARTIAL, /* Cpu slab acquired from node partial list */
349-
ALLOC_SLAB, /* Cpu slab acquired from page allocator */
350-
ALLOC_REFILL, /* Refill cpu slab from slab freelist */
351-
ALLOC_NODE_MISMATCH, /* Switching cpu slab */
346+
ALLOC_SLAB, /* New slab acquired from page allocator */
347+
ALLOC_NODE_MISMATCH, /* Requested node different from cpu sheaf */
352348
FREE_SLAB, /* Slab freed to the page allocator */
353-
CPUSLAB_FLUSH, /* Abandoning of the cpu slab */
354-
DEACTIVATE_FULL, /* Cpu slab was full when deactivated */
355-
DEACTIVATE_EMPTY, /* Cpu slab was empty when deactivated */
356-
DEACTIVATE_REMOTE_FREES,/* Slab contained remotely freed objects */
357-
DEACTIVATE_BYPASS, /* Implicit deactivation */
358349
ORDER_FALLBACK, /* Number of times fallback was necessary */
359-
CMPXCHG_DOUBLE_CPU_FAIL,/* Failures of this_cpu_cmpxchg_double */
360350
CMPXCHG_DOUBLE_FAIL, /* Failures of slab freelist update */
361-
CPU_PARTIAL_ALLOC, /* Used cpu partial on alloc */
362-
CPU_PARTIAL_FREE, /* Refill cpu partial on free */
363-
CPU_PARTIAL_NODE, /* Refill cpu partial from node partial */
364-
CPU_PARTIAL_DRAIN, /* Drain cpu partial to node partial */
365351
SHEAF_FLUSH, /* Objects flushed from a sheaf */
366352
SHEAF_REFILL, /* Objects refilled to a sheaf */
367353
SHEAF_ALLOC, /* Allocation of an empty sheaf */
@@ -4350,8 +4336,10 @@ void *alloc_from_pcs(struct kmem_cache *s, gfp_t gfp, int node)
43504336
* We assume the percpu sheaves contain only local objects although it's
43514337
* not completely guaranteed, so we verify later.
43524338
*/
4353-
if (unlikely(node_requested && node != numa_mem_id()))
4339+
if (unlikely(node_requested && node != numa_mem_id())) {
4340+
stat(s, ALLOC_NODE_MISMATCH);
43544341
return NULL;
4342+
}
43554343

43564344
if (!local_trylock(&s->cpu_sheaves->lock))
43574345
return NULL;
@@ -4374,6 +4362,7 @@ void *alloc_from_pcs(struct kmem_cache *s, gfp_t gfp, int node)
43744362
*/
43754363
if (page_to_nid(virt_to_page(object)) != node) {
43764364
local_unlock(&s->cpu_sheaves->lock);
4365+
stat(s, ALLOC_NODE_MISMATCH);
43774366
return NULL;
43784367
}
43794368
}
@@ -4382,7 +4371,7 @@ void *alloc_from_pcs(struct kmem_cache *s, gfp_t gfp, int node)
43824371

43834372
local_unlock(&s->cpu_sheaves->lock);
43844373

4385-
stat(s, ALLOC_PCS);
4374+
stat(s, ALLOC_FASTPATH);
43864375

43874376
return object;
43884377
}
@@ -4454,7 +4443,7 @@ unsigned int alloc_from_pcs_bulk(struct kmem_cache *s, gfp_t gfp, size_t size,
44544443

44554444
local_unlock(&s->cpu_sheaves->lock);
44564445

4457-
stat_add(s, ALLOC_PCS, batch);
4446+
stat_add(s, ALLOC_FASTPATH, batch);
44584447

44594448
allocated += batch;
44604449

@@ -5117,8 +5106,6 @@ static void __slab_free(struct kmem_cache *s, struct slab *slab,
51175106
unsigned long flags;
51185107
bool on_node_partial;
51195108

5120-
stat(s, FREE_SLOWPATH);
5121-
51225109
if (IS_ENABLED(CONFIG_SLUB_TINY) || kmem_cache_debug(s)) {
51235110
free_to_partial_list(s, slab, head, tail, cnt, addr);
51245111
return;
@@ -5422,7 +5409,7 @@ bool free_to_pcs(struct kmem_cache *s, void *object, bool allow_spin)
54225409

54235410
local_unlock(&s->cpu_sheaves->lock);
54245411

5425-
stat(s, FREE_PCS);
5412+
stat(s, FREE_FASTPATH);
54265413

54275414
return true;
54285415
}
@@ -5690,7 +5677,7 @@ static void free_to_pcs_bulk(struct kmem_cache *s, size_t size, void **p)
56905677

56915678
local_unlock(&s->cpu_sheaves->lock);
56925679

5693-
stat_add(s, FREE_PCS, batch);
5680+
stat_add(s, FREE_FASTPATH, batch);
56945681

56955682
if (batch < size) {
56965683
p += batch;
@@ -5712,10 +5699,12 @@ static void free_to_pcs_bulk(struct kmem_cache *s, size_t size, void **p)
57125699
*/
57135700
fallback:
57145701
__kmem_cache_free_bulk(s, size, p);
5702+
stat_add(s, FREE_SLOWPATH, size);
57155703

57165704
flush_remote:
57175705
if (remote_nr) {
57185706
__kmem_cache_free_bulk(s, remote_nr, &remote_objects[0]);
5707+
stat_add(s, FREE_SLOWPATH, remote_nr);
57195708
if (i < size) {
57205709
remote_nr = 0;
57215710
goto next_remote_batch;
@@ -5769,6 +5758,7 @@ static void free_deferred_objects(struct irq_work *work)
57695758
set_freepointer(s, x, NULL);
57705759

57715760
__slab_free(s, slab, x, x, 1, _THIS_IP_);
5761+
stat(s, FREE_SLOWPATH);
57725762
}
57735763
}
57745764

@@ -5810,6 +5800,7 @@ void slab_free(struct kmem_cache *s, struct slab *slab, void *object,
58105800
}
58115801

58125802
__slab_free(s, slab, object, object, 1, addr);
5803+
stat(s, FREE_SLOWPATH);
58135804
}
58145805

58155806
#ifdef CONFIG_MEMCG
@@ -5832,8 +5823,10 @@ void slab_free_bulk(struct kmem_cache *s, struct slab *slab, void *head,
58325823
* With KASAN enabled slab_free_freelist_hook modifies the freelist
58335824
* to remove objects, whose reuse must be delayed.
58345825
*/
5835-
if (likely(slab_free_freelist_hook(s, &head, &tail, &cnt)))
5826+
if (likely(slab_free_freelist_hook(s, &head, &tail, &cnt))) {
58365827
__slab_free(s, slab, head, tail, cnt, addr);
5828+
stat_add(s, FREE_SLOWPATH, cnt);
5829+
}
58375830
}
58385831

58395832
#ifdef CONFIG_SLUB_RCU_DEBUG
@@ -5858,15 +5851,18 @@ static void slab_free_after_rcu_debug(struct rcu_head *rcu_head)
58585851
return;
58595852

58605853
/* resume freeing */
5861-
if (slab_free_hook(s, object, slab_want_init_on_free(s), true))
5854+
if (slab_free_hook(s, object, slab_want_init_on_free(s), true)) {
58625855
__slab_free(s, slab, object, object, 1, _THIS_IP_);
5856+
stat(s, FREE_SLOWPATH);
5857+
}
58635858
}
58645859
#endif /* CONFIG_SLUB_RCU_DEBUG */
58655860

58665861
#ifdef CONFIG_KASAN_GENERIC
58675862
void ___cache_free(struct kmem_cache *cache, void *x, unsigned long addr)
58685863
{
58695864
__slab_free(cache, virt_to_slab(x), x, x, 1, addr);
5865+
stat(cache, FREE_SLOWPATH);
58705866
}
58715867
#endif
58725868

@@ -6746,6 +6742,7 @@ int __kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size,
67466742
i = refill_objects(s, p, flags, size, size);
67476743
if (i < size)
67486744
goto error;
6745+
stat_add(s, ALLOC_SLOWPATH, i);
67496746
}
67506747

67516748
return i;
@@ -8749,33 +8746,19 @@ static ssize_t text##_store(struct kmem_cache *s, \
87498746
} \
87508747
SLAB_ATTR(text); \
87518748

8752-
STAT_ATTR(ALLOC_PCS, alloc_cpu_sheaf);
87538749
STAT_ATTR(ALLOC_FASTPATH, alloc_fastpath);
87548750
STAT_ATTR(ALLOC_SLOWPATH, alloc_slowpath);
8755-
STAT_ATTR(FREE_PCS, free_cpu_sheaf);
87568751
STAT_ATTR(FREE_RCU_SHEAF, free_rcu_sheaf);
87578752
STAT_ATTR(FREE_RCU_SHEAF_FAIL, free_rcu_sheaf_fail);
87588753
STAT_ATTR(FREE_FASTPATH, free_fastpath);
87598754
STAT_ATTR(FREE_SLOWPATH, free_slowpath);
87608755
STAT_ATTR(FREE_ADD_PARTIAL, free_add_partial);
87618756
STAT_ATTR(FREE_REMOVE_PARTIAL, free_remove_partial);
8762-
STAT_ATTR(ALLOC_FROM_PARTIAL, alloc_from_partial);
87638757
STAT_ATTR(ALLOC_SLAB, alloc_slab);
8764-
STAT_ATTR(ALLOC_REFILL, alloc_refill);
87658758
STAT_ATTR(ALLOC_NODE_MISMATCH, alloc_node_mismatch);
87668759
STAT_ATTR(FREE_SLAB, free_slab);
8767-
STAT_ATTR(CPUSLAB_FLUSH, cpuslab_flush);
8768-
STAT_ATTR(DEACTIVATE_FULL, deactivate_full);
8769-
STAT_ATTR(DEACTIVATE_EMPTY, deactivate_empty);
8770-
STAT_ATTR(DEACTIVATE_REMOTE_FREES, deactivate_remote_frees);
8771-
STAT_ATTR(DEACTIVATE_BYPASS, deactivate_bypass);
87728760
STAT_ATTR(ORDER_FALLBACK, order_fallback);
8773-
STAT_ATTR(CMPXCHG_DOUBLE_CPU_FAIL, cmpxchg_double_cpu_fail);
87748761
STAT_ATTR(CMPXCHG_DOUBLE_FAIL, cmpxchg_double_fail);
8775-
STAT_ATTR(CPU_PARTIAL_ALLOC, cpu_partial_alloc);
8776-
STAT_ATTR(CPU_PARTIAL_FREE, cpu_partial_free);
8777-
STAT_ATTR(CPU_PARTIAL_NODE, cpu_partial_node);
8778-
STAT_ATTR(CPU_PARTIAL_DRAIN, cpu_partial_drain);
87798762
STAT_ATTR(SHEAF_FLUSH, sheaf_flush);
87808763
STAT_ATTR(SHEAF_REFILL, sheaf_refill);
87818764
STAT_ATTR(SHEAF_ALLOC, sheaf_alloc);
@@ -8851,33 +8834,19 @@ static struct attribute *slab_attrs[] = {
88518834
&remote_node_defrag_ratio_attr.attr,
88528835
#endif
88538836
#ifdef CONFIG_SLUB_STATS
8854-
&alloc_cpu_sheaf_attr.attr,
88558837
&alloc_fastpath_attr.attr,
88568838
&alloc_slowpath_attr.attr,
8857-
&free_cpu_sheaf_attr.attr,
88588839
&free_rcu_sheaf_attr.attr,
88598840
&free_rcu_sheaf_fail_attr.attr,
88608841
&free_fastpath_attr.attr,
88618842
&free_slowpath_attr.attr,
88628843
&free_add_partial_attr.attr,
88638844
&free_remove_partial_attr.attr,
8864-
&alloc_from_partial_attr.attr,
88658845
&alloc_slab_attr.attr,
8866-
&alloc_refill_attr.attr,
88678846
&alloc_node_mismatch_attr.attr,
88688847
&free_slab_attr.attr,
8869-
&cpuslab_flush_attr.attr,
8870-
&deactivate_full_attr.attr,
8871-
&deactivate_empty_attr.attr,
8872-
&deactivate_remote_frees_attr.attr,
8873-
&deactivate_bypass_attr.attr,
88748848
&order_fallback_attr.attr,
88758849
&cmpxchg_double_fail_attr.attr,
8876-
&cmpxchg_double_cpu_fail_attr.attr,
8877-
&cpu_partial_alloc_attr.attr,
8878-
&cpu_partial_free_attr.attr,
8879-
&cpu_partial_node_attr.attr,
8880-
&cpu_partial_drain_attr.attr,
88818850
&sheaf_flush_attr.attr,
88828851
&sheaf_refill_attr.attr,
88838852
&sheaf_alloc_attr.attr,

0 commit comments

Comments
 (0)