104
104
* except the stat counters. This is a percpu structure manipulated only by
105
105
* the local cpu, so the lock protects against being preempted or interrupted
106
106
* by an irq. Fast path operations rely on lockless operations instead.
107
- * On PREEMPT_RT, the local lock does not actually disable irqs (and thus
108
- * prevent the lockless operations), so fastpath operations also need to take
109
- * the lock and are no longer lockless.
107
+ *
108
+ * On PREEMPT_RT, the local lock neither disables interrupts nor preemption
109
+ * which means the lockless fastpath cannot be used as it might interfere with
110
+ * an in-progress slow path operations. In this case the local lock is always
111
+ * taken but it still utilizes the freelist for the common operations.
110
112
*
111
113
* lockless fastpaths
112
114
*
167
169
* function call even on !PREEMPT_RT, use inline preempt_disable() there.
168
170
*/
169
171
#ifndef CONFIG_PREEMPT_RT
170
- #define slub_get_cpu_ptr (var ) get_cpu_ptr(var)
171
- #define slub_put_cpu_ptr (var ) put_cpu_ptr(var)
172
+ #define slub_get_cpu_ptr (var ) get_cpu_ptr(var)
173
+ #define slub_put_cpu_ptr (var ) put_cpu_ptr(var)
174
+ #define USE_LOCKLESS_FAST_PATH () (true)
172
175
#else
173
176
#define slub_get_cpu_ptr (var ) \
174
177
({ \
@@ -180,6 +183,7 @@ do { \
180
183
(void)(var); \
181
184
migrate_enable(); \
182
185
} while (0)
186
+ #define USE_LOCKLESS_FAST_PATH () (false)
183
187
#endif
184
188
185
189
#ifdef CONFIG_SLUB_DEBUG
@@ -474,7 +478,7 @@ static inline bool __cmpxchg_double_slab(struct kmem_cache *s, struct slab *slab
474
478
void * freelist_new , unsigned long counters_new ,
475
479
const char * n )
476
480
{
477
- if (! IS_ENABLED ( CONFIG_PREEMPT_RT ))
481
+ if (USE_LOCKLESS_FAST_PATH ( ))
478
482
lockdep_assert_irqs_disabled ();
479
483
#if defined(CONFIG_HAVE_CMPXCHG_DOUBLE ) && \
480
484
defined(CONFIG_HAVE_ALIGNED_STRUCT_PAGE )
@@ -3288,14 +3292,8 @@ static __always_inline void *slab_alloc_node(struct kmem_cache *s, struct list_l
3288
3292
3289
3293
object = c -> freelist ;
3290
3294
slab = c -> slab ;
3291
- /*
3292
- * We cannot use the lockless fastpath on PREEMPT_RT because if a
3293
- * slowpath has taken the local_lock_irqsave(), it is not protected
3294
- * against a fast path operation in an irq handler. So we need to take
3295
- * the slow path which uses local_lock. It is still relatively fast if
3296
- * there is a suitable cpu freelist.
3297
- */
3298
- if (IS_ENABLED (CONFIG_PREEMPT_RT ) ||
3295
+
3296
+ if (!USE_LOCKLESS_FAST_PATH () ||
3299
3297
unlikely (!object || !slab || !node_match (slab , node ))) {
3300
3298
object = __slab_alloc (s , gfpflags , node , addr , c );
3301
3299
} else {
@@ -3555,6 +3553,7 @@ static __always_inline void do_slab_free(struct kmem_cache *s,
3555
3553
void * tail_obj = tail ? : head ;
3556
3554
struct kmem_cache_cpu * c ;
3557
3555
unsigned long tid ;
3556
+ void * * freelist ;
3558
3557
3559
3558
redo :
3560
3559
/*
@@ -3569,9 +3568,13 @@ static __always_inline void do_slab_free(struct kmem_cache *s,
3569
3568
/* Same with comment on barrier() in slab_alloc_node() */
3570
3569
barrier ();
3571
3570
3572
- if (likely (slab == c -> slab )) {
3573
- #ifndef CONFIG_PREEMPT_RT
3574
- void * * freelist = READ_ONCE (c -> freelist );
3571
+ if (unlikely (slab != c -> slab )) {
3572
+ __slab_free (s , slab , head , tail_obj , cnt , addr );
3573
+ return ;
3574
+ }
3575
+
3576
+ if (USE_LOCKLESS_FAST_PATH ()) {
3577
+ freelist = READ_ONCE (c -> freelist );
3575
3578
3576
3579
set_freepointer (s , tail_obj , freelist );
3577
3580
@@ -3583,16 +3586,8 @@ static __always_inline void do_slab_free(struct kmem_cache *s,
3583
3586
note_cmpxchg_failure ("slab_free" , s , tid );
3584
3587
goto redo ;
3585
3588
}
3586
- #else /* CONFIG_PREEMPT_RT */
3587
- /*
3588
- * We cannot use the lockless fastpath on PREEMPT_RT because if
3589
- * a slowpath has taken the local_lock_irqsave(), it is not
3590
- * protected against a fast path operation in an irq handler. So
3591
- * we need to take the local_lock. We shouldn't simply defer to
3592
- * __slab_free() as that wouldn't use the cpu freelist at all.
3593
- */
3594
- void * * freelist ;
3595
-
3589
+ } else {
3590
+ /* Update the free list under the local lock */
3596
3591
local_lock (& s -> cpu_slab -> lock );
3597
3592
c = this_cpu_ptr (s -> cpu_slab );
3598
3593
if (unlikely (slab != c -> slab )) {
@@ -3607,11 +3602,8 @@ static __always_inline void do_slab_free(struct kmem_cache *s,
3607
3602
c -> tid = next_tid (tid );
3608
3603
3609
3604
local_unlock (& s -> cpu_slab -> lock );
3610
- #endif
3611
- stat (s , FREE_FASTPATH );
3612
- } else
3613
- __slab_free (s , slab , head , tail_obj , cnt , addr );
3614
-
3605
+ }
3606
+ stat (s , FREE_FASTPATH );
3615
3607
}
3616
3608
3617
3609
static __always_inline void slab_free (struct kmem_cache * s , struct slab * slab ,
0 commit comments