Skip to content

Commit bdc9282

Browse files
committed
slab: remove the do_slab_free() fastpath
We have removed cpu slab usage from allocation paths. Now remove do_slab_free() which was freeing objects to the cpu slab when the object belonged to it. Instead call __slab_free() directly, which was previously the fallback. This simplifies kfree_nolock() - when freeing to percpu sheaf fails, we can call defer_free() directly. Also remove functions that became unused. Reviewed-by: Harry Yoo <harry.yoo@oracle.com> Reviewed-by: Hao Li <hao.li@linux.dev> Reviewed-by: Suren Baghdasaryan <surenb@google.com> Acked-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
1 parent e323b52 commit bdc9282

1 file changed

Lines changed: 13 additions & 136 deletions

File tree

mm/slub.c

Lines changed: 13 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -3678,29 +3678,6 @@ static inline unsigned int init_tid(int cpu)
36783678
return cpu;
36793679
}
36803680

3681-
static inline void note_cmpxchg_failure(const char *n,
3682-
const struct kmem_cache *s, unsigned long tid)
3683-
{
3684-
#ifdef SLUB_DEBUG_CMPXCHG
3685-
unsigned long actual_tid = __this_cpu_read(s->cpu_slab->tid);
3686-
3687-
pr_info("%s %s: cmpxchg redo ", n, s->name);
3688-
3689-
if (IS_ENABLED(CONFIG_PREEMPTION) &&
3690-
tid_to_cpu(tid) != tid_to_cpu(actual_tid)) {
3691-
pr_warn("due to cpu change %d -> %d\n",
3692-
tid_to_cpu(tid), tid_to_cpu(actual_tid));
3693-
} else if (tid_to_event(tid) != tid_to_event(actual_tid)) {
3694-
pr_warn("due to cpu running other code. Event %ld->%ld\n",
3695-
tid_to_event(tid), tid_to_event(actual_tid));
3696-
} else {
3697-
pr_warn("for unknown reason: actual=%lx was=%lx target=%lx\n",
3698-
actual_tid, tid, next_tid(tid));
3699-
}
3700-
#endif
3701-
stat(s, CMPXCHG_DOUBLE_CPU_FAIL);
3702-
}
3703-
37043681
static void init_kmem_cache_cpus(struct kmem_cache *s)
37053682
{
37063683
#ifdef CONFIG_PREEMPT_RT
@@ -4239,18 +4216,6 @@ static inline bool pfmemalloc_match(struct slab *slab, gfp_t gfpflags)
42394216
return true;
42404217
}
42414218

4242-
static inline bool
4243-
__update_cpu_freelist_fast(struct kmem_cache *s,
4244-
void *freelist_old, void *freelist_new,
4245-
unsigned long tid)
4246-
{
4247-
struct freelist_tid old = { .freelist = freelist_old, .tid = tid };
4248-
struct freelist_tid new = { .freelist = freelist_new, .tid = next_tid(tid) };
4249-
4250-
return this_cpu_try_cmpxchg_freelist(s->cpu_slab->freelist_tid,
4251-
&old.freelist_tid, new.freelist_tid);
4252-
}
4253-
42544219
/*
42554220
* Get the slab's freelist and do not freeze it.
42564221
*
@@ -6188,99 +6153,6 @@ void defer_free_barrier(void)
61886153
irq_work_sync(&per_cpu_ptr(&defer_free_objects, cpu)->work);
61896154
}
61906155

6191-
/*
6192-
* Fastpath with forced inlining to produce a kfree and kmem_cache_free that
6193-
* can perform fastpath freeing without additional function calls.
6194-
*
6195-
* The fastpath is only possible if we are freeing to the current cpu slab
6196-
* of this processor. This typically the case if we have just allocated
6197-
* the item before.
6198-
*
6199-
* If fastpath is not possible then fall back to __slab_free where we deal
6200-
* with all sorts of special processing.
6201-
*
6202-
* Bulk free of a freelist with several objects (all pointing to the
6203-
* same slab) possible by specifying head and tail ptr, plus objects
6204-
* count (cnt). Bulk free indicated by tail pointer being set.
6205-
*/
6206-
static __always_inline void do_slab_free(struct kmem_cache *s,
6207-
struct slab *slab, void *head, void *tail,
6208-
int cnt, unsigned long addr)
6209-
{
6210-
/* cnt == 0 signals that it's called from kfree_nolock() */
6211-
bool allow_spin = cnt;
6212-
struct kmem_cache_cpu *c;
6213-
unsigned long tid;
6214-
void **freelist;
6215-
6216-
redo:
6217-
/*
6218-
* Determine the currently cpus per cpu slab.
6219-
* The cpu may change afterward. However that does not matter since
6220-
* data is retrieved via this pointer. If we are on the same cpu
6221-
* during the cmpxchg then the free will succeed.
6222-
*/
6223-
c = raw_cpu_ptr(s->cpu_slab);
6224-
tid = READ_ONCE(c->tid);
6225-
6226-
/* Same with comment on barrier() in __slab_alloc_node() */
6227-
barrier();
6228-
6229-
if (unlikely(slab != c->slab)) {
6230-
if (unlikely(!allow_spin)) {
6231-
/*
6232-
* __slab_free() can locklessly cmpxchg16 into a slab,
6233-
* but then it might need to take spin_lock
6234-
* for further processing.
6235-
* Avoid the complexity and simply add to a deferred list.
6236-
*/
6237-
defer_free(s, head);
6238-
} else {
6239-
__slab_free(s, slab, head, tail, cnt, addr);
6240-
}
6241-
return;
6242-
}
6243-
6244-
if (unlikely(!allow_spin)) {
6245-
if ((in_nmi() || !USE_LOCKLESS_FAST_PATH()) &&
6246-
local_lock_is_locked(&s->cpu_slab->lock)) {
6247-
defer_free(s, head);
6248-
return;
6249-
}
6250-
cnt = 1; /* restore cnt. kfree_nolock() frees one object at a time */
6251-
}
6252-
6253-
if (USE_LOCKLESS_FAST_PATH()) {
6254-
freelist = READ_ONCE(c->freelist);
6255-
6256-
set_freepointer(s, tail, freelist);
6257-
6258-
if (unlikely(!__update_cpu_freelist_fast(s, freelist, head, tid))) {
6259-
note_cmpxchg_failure("slab_free", s, tid);
6260-
goto redo;
6261-
}
6262-
} else {
6263-
__maybe_unused unsigned long flags = 0;
6264-
6265-
/* Update the free list under the local lock */
6266-
local_lock_cpu_slab(s, flags);
6267-
c = this_cpu_ptr(s->cpu_slab);
6268-
if (unlikely(slab != c->slab)) {
6269-
local_unlock_cpu_slab(s, flags);
6270-
goto redo;
6271-
}
6272-
tid = c->tid;
6273-
freelist = c->freelist;
6274-
6275-
set_freepointer(s, tail, freelist);
6276-
c->freelist = head;
6277-
c->tid = next_tid(tid);
6278-
6279-
local_unlock_cpu_slab(s, flags);
6280-
}
6281-
stat_add(s, FREE_FASTPATH, cnt);
6282-
}
6283-
62846156
static __fastpath_inline
62856157
void slab_free(struct kmem_cache *s, struct slab *slab, void *object,
62866158
unsigned long addr)
@@ -6297,7 +6169,7 @@ void slab_free(struct kmem_cache *s, struct slab *slab, void *object,
62976169
return;
62986170
}
62996171

6300-
do_slab_free(s, slab, object, object, 1, addr);
6172+
__slab_free(s, slab, object, object, 1, addr);
63016173
}
63026174

63036175
#ifdef CONFIG_MEMCG
@@ -6306,7 +6178,7 @@ static noinline
63066178
void memcg_alloc_abort_single(struct kmem_cache *s, void *object)
63076179
{
63086180
if (likely(slab_free_hook(s, object, slab_want_init_on_free(s), false)))
6309-
do_slab_free(s, virt_to_slab(object), object, object, 1, _RET_IP_);
6181+
__slab_free(s, virt_to_slab(object), object, object, 1, _RET_IP_);
63106182
}
63116183
#endif
63126184

@@ -6321,7 +6193,7 @@ void slab_free_bulk(struct kmem_cache *s, struct slab *slab, void *head,
63216193
* to remove objects, whose reuse must be delayed.
63226194
*/
63236195
if (likely(slab_free_freelist_hook(s, &head, &tail, &cnt)))
6324-
do_slab_free(s, slab, head, tail, cnt, addr);
6196+
__slab_free(s, slab, head, tail, cnt, addr);
63256197
}
63266198

63276199
#ifdef CONFIG_SLUB_RCU_DEBUG
@@ -6347,14 +6219,14 @@ static void slab_free_after_rcu_debug(struct rcu_head *rcu_head)
63476219

63486220
/* resume freeing */
63496221
if (slab_free_hook(s, object, slab_want_init_on_free(s), true))
6350-
do_slab_free(s, slab, object, object, 1, _THIS_IP_);
6222+
__slab_free(s, slab, object, object, 1, _THIS_IP_);
63516223
}
63526224
#endif /* CONFIG_SLUB_RCU_DEBUG */
63536225

63546226
#ifdef CONFIG_KASAN_GENERIC
63556227
void ___cache_free(struct kmem_cache *cache, void *x, unsigned long addr)
63566228
{
6357-
do_slab_free(cache, virt_to_slab(x), x, x, 1, addr);
6229+
__slab_free(cache, virt_to_slab(x), x, x, 1, addr);
63586230
}
63596231
#endif
63606232

@@ -6570,7 +6442,12 @@ void kfree_nolock(const void *object)
65706442
return;
65716443
}
65726444

6573-
do_slab_free(s, slab, x, x, 0, _RET_IP_);
6445+
/*
6446+
* __slab_free() can locklessly cmpxchg16 into a slab, but then it might
6447+
* need to take spin_lock for further processing.
6448+
* Avoid the complexity and simply add to a deferred list.
6449+
*/
6450+
defer_free(s, x);
65746451
}
65756452
EXPORT_SYMBOL_GPL(kfree_nolock);
65766453

@@ -6996,7 +6873,7 @@ static void __kmem_cache_free_bulk(struct kmem_cache *s, size_t size, void **p)
69966873
if (kfence_free(df.freelist))
69976874
continue;
69986875

6999-
do_slab_free(df.s, df.slab, df.freelist, df.tail, df.cnt,
6876+
__slab_free(df.s, df.slab, df.freelist, df.tail, df.cnt,
70006877
_RET_IP_);
70016878
} while (likely(size));
70026879
}
@@ -7082,7 +6959,7 @@ __refill_objects(struct kmem_cache *s, void **p, gfp_t gfp, unsigned int min,
70826959
cnt++;
70836960
object = get_freepointer(s, object);
70846961
} while (object);
7085-
do_slab_free(s, slab, head, tail, cnt, _RET_IP_);
6962+
__slab_free(s, slab, head, tail, cnt, _RET_IP_);
70866963
}
70876964

70886965
if (refilled >= max)

0 commit comments

Comments
 (0)