On Mon, 2021-07-19 at 06:01 +0200, Mike Galbraith wrote: > > ... despite the unlock/relock in this patch, it still manages to be a > -ENOBOOT. The somewhat bent up half of your patch below has been chugging away long enough for me to speculate that __slab_free() vs ___slab_alloc() is the *only* player in the explosion varieties I've been seeing. --- mm/slub.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) --- a/mm/slub.c +++ b/mm/slub.c @@ -2484,6 +2484,9 @@ static void put_cpu_partial(struct kmem_ int pobjects; slub_get_cpu_ptr(s->cpu_slab); + /* __slab_free() vs ___slab_alloc() critical sections */ + if (IS_ENABLED(CONFIG_PREEMPT_RT) && drain) + local_lock(&s->cpu_slab->lock); do { pages = 0; pobjects = 0; @@ -2497,7 +2500,13 @@ static void put_cpu_partial(struct kmem_ * partial array is full. Move the existing * set to the per node partial list. */ - unfreeze_partials(s); + this_cpu_write(s->cpu_slab->partial, NULL); + if (IS_ENABLED(CONFIG_PREEMPT_RT) && drain) + local_unlock(&s->cpu_slab->lock); + __unfreeze_partials(s, oldpage); + if (IS_ENABLED(CONFIG_PREEMPT_RT) && drain) + local_lock(&s->cpu_slab->lock); + oldpage = NULL; pobjects = 0; pages = 0; @@ -2514,6 +2523,8 @@ static void put_cpu_partial(struct kmem_ } while (this_cpu_cmpxchg(s->cpu_slab->partial, oldpage, page) != oldpage); + if (IS_ENABLED(CONFIG_PREEMPT_RT) && drain) + local_unlock(&s->cpu_slab->lock); slub_put_cpu_ptr(s->cpu_slab); #endif /* CONFIG_SLUB_CPU_PARTIAL */ }