Re: [patch] v2 mm/slub: restore/expand unfreeze_partials() local exclusion scope

From: Mike Galbraith
Date: Mon Jul 19 2021 - 09:16:12 EST


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 */
}