All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vlastimil Babka <vbabka@suse.cz>
To: linux-mm@kvack.org, linux-kernel@vger.kernel.org,
	Christoph Lameter <cl@linux.com>,
	David Rientjes <rientjes@google.com>,
	Pekka Enberg <penberg@kernel.org>,
	Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Mike Galbraith <efault@gmx.de>,
	Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
	Thomas Gleixner <tglx@linutronix.de>,
	Mel Gorman <mgorman@techsingularity.net>,
	Jesper Dangaard Brouer <brouer@redhat.com>,
	Jann Horn <jannh@google.com>, Vlastimil Babka <vbabka@suse.cz>
Subject: [PATCH v3 29/35] mm: slub: Move flush_cpu_slab() invocations __free_slab() invocations out of IRQ context
Date: Thu, 29 Jul 2021 15:21:26 +0200	[thread overview]
Message-ID: <20210729132132.19691-30-vbabka@suse.cz> (raw)
In-Reply-To: <20210729132132.19691-1-vbabka@suse.cz>

From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>

flush_all() flushes a specific SLAB cache on each CPU (where the cache
is present). The deactivate_slab()/__free_slab() invocation happens
within IPI handler and is problematic for PREEMPT_RT.

The flush operation is not a frequent operation or a hot path. The
per-CPU flush operation can be moved to within a workqueue.

[vbabka@suse.cz: adapt to new SLUB changes]
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
---
 mm/slub.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 48 insertions(+), 8 deletions(-)

diff --git a/mm/slub.c b/mm/slub.c
index 9fbc5396f3e1..dbb74dbe1c1e 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2513,33 +2513,73 @@ static inline void __flush_cpu_slab(struct kmem_cache *s, int cpu)
 	unfreeze_partials_cpu(s, c);
 }
 
+struct slub_flush_work {
+	struct work_struct work;
+	struct kmem_cache *s;
+	bool skip;
+};
+
 /*
  * Flush cpu slab.
  *
- * Called from IPI handler with interrupts disabled.
+ * Called from CPU work handler with migration disabled.
  */
-static void flush_cpu_slab(void *d)
+static void flush_cpu_slab(struct work_struct *w)
 {
-	struct kmem_cache *s = d;
-	struct kmem_cache_cpu *c = this_cpu_ptr(s->cpu_slab);
+	struct kmem_cache *s;
+	struct kmem_cache_cpu *c;
+	struct slub_flush_work *sfw;
+
+	sfw = container_of(w, struct slub_flush_work, work);
+
+	s = sfw->s;
+	c = this_cpu_ptr(s->cpu_slab);
 
 	if (c->page)
-		flush_slab(s, c, false);
+		flush_slab(s, c, true);
 
 	unfreeze_partials(s);
 }
 
-static bool has_cpu_slab(int cpu, void *info)
+static bool has_cpu_slab(int cpu, struct kmem_cache *s)
 {
-	struct kmem_cache *s = info;
 	struct kmem_cache_cpu *c = per_cpu_ptr(s->cpu_slab, cpu);
 
 	return c->page || slub_percpu_partial(c);
 }
 
+static DEFINE_MUTEX(flush_lock);
+static DEFINE_PER_CPU(struct slub_flush_work, slub_flush);
+
 static void flush_all(struct kmem_cache *s)
 {
-	on_each_cpu_cond(has_cpu_slab, flush_cpu_slab, s, 1);
+	struct slub_flush_work *sfw;
+	unsigned int cpu;
+
+	mutex_lock(&flush_lock);
+	cpus_read_lock();
+
+	for_each_online_cpu(cpu) {
+		sfw = &per_cpu(slub_flush, cpu);
+		if (!has_cpu_slab(cpu, s)) {
+			sfw->skip = true;
+			continue;
+		}
+		INIT_WORK(&sfw->work, flush_cpu_slab);
+		sfw->skip = false;
+		sfw->s = s;
+		schedule_work_on(cpu, &sfw->work);
+	}
+
+	for_each_online_cpu(cpu) {
+		sfw = &per_cpu(slub_flush, cpu);
+		if (sfw->skip)
+			continue;
+		flush_work(&sfw->work);
+	}
+
+	cpus_read_unlock();
+	mutex_unlock(&flush_lock);
 }
 
 /*
-- 
2.32.0


  parent reply	other threads:[~2021-07-29 13:23 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-29 13:20 [PATCH v3 00/35] SLUB: reduce irq disabled scope and make it RT compatible Vlastimil Babka
2021-07-29 13:20 ` [PATCH v3 01/35] mm, slub: don't call flush_all() from slab_debug_trace_open() Vlastimil Babka
2021-07-29 13:20 ` [PATCH v3 02/35] mm, slub: allocate private object map for debugfs listings Vlastimil Babka
2021-07-29 13:21 ` [PATCH v3 03/35] mm, slub: allocate private object map for validate_slab_cache() Vlastimil Babka
2021-07-29 13:21 ` [PATCH v3 04/35] mm, slub: don't disable irq for debug_check_no_locks_freed() Vlastimil Babka
2021-07-29 13:21 ` [PATCH v3 05/35] mm, slub: remove redundant unfreeze_partials() from put_cpu_partial() Vlastimil Babka
2021-07-29 13:21 ` [PATCH v3 06/35] mm, slub: unify cmpxchg_double_slab() and __cmpxchg_double_slab() Vlastimil Babka
2021-07-29 13:21 ` [PATCH v3 07/35] mm, slub: extract get_partial() from new_slab_objects() Vlastimil Babka
2021-07-29 13:21 ` [PATCH v3 08/35] mm, slub: dissolve new_slab_objects() into ___slab_alloc() Vlastimil Babka
2021-07-29 13:21 ` [PATCH v3 09/35] mm, slub: return slab page from get_partial() and set c->page afterwards Vlastimil Babka
2021-07-29 13:21 ` [PATCH v3 10/35] mm, slub: restructure new page checks in ___slab_alloc() Vlastimil Babka
2021-07-29 13:21 ` [PATCH v3 11/35] mm, slub: simplify kmem_cache_cpu and tid setup Vlastimil Babka
2021-07-29 13:21 ` [PATCH v3 12/35] mm, slub: move disabling/enabling irqs to ___slab_alloc() Vlastimil Babka
2021-07-29 13:21 ` [PATCH v3 13/35] mm, slub: do initial checks in ___slab_alloc() with irqs enabled Vlastimil Babka
2021-07-29 13:21 ` [PATCH v3 14/35] mm, slub: move disabling irqs closer to get_partial() in ___slab_alloc() Vlastimil Babka
2021-07-29 13:21 ` [PATCH v3 15/35] mm, slub: restore irqs around calling new_slab() Vlastimil Babka
2021-07-29 13:21 ` [PATCH v3 16/35] mm, slub: validate slab from partial list or page allocator before making it cpu slab Vlastimil Babka
2021-07-29 13:21 ` [PATCH v3 17/35] mm, slub: check new pages with restored irqs Vlastimil Babka
2021-07-29 13:21 ` [PATCH v3 18/35] mm, slub: stop disabling irqs around get_partial() Vlastimil Babka
2021-07-29 13:21 ` [PATCH v3 19/35] mm, slub: move reset of c->page and freelist out of deactivate_slab() Vlastimil Babka
2021-07-29 13:21 ` [PATCH v3 20/35] mm, slub: make locking in deactivate_slab() irq-safe Vlastimil Babka
2021-07-29 13:21 ` [PATCH v3 21/35] mm, slub: call deactivate_slab() without disabling irqs Vlastimil Babka
2021-07-29 13:21 ` [PATCH v3 22/35] mm, slub: move irq control into unfreeze_partials() Vlastimil Babka
2021-07-29 13:21 ` [PATCH v3 23/35] mm, slub: discard slabs in unfreeze_partials() without irqs disabled Vlastimil Babka
2021-07-29 13:21 ` [PATCH v3 24/35] mm, slub: detach whole partial list at once in unfreeze_partials() Vlastimil Babka
2021-07-29 13:21 ` [PATCH v3 25/35] mm, slub: separate detaching of partial list in unfreeze_partials() from unfreezing Vlastimil Babka
2021-07-29 13:21 ` [PATCH v3 26/35] mm, slub: only disable irq with spin_lock in __unfreeze_partials() Vlastimil Babka
2021-07-29 13:21 ` [PATCH v3 27/35] mm, slub: don't disable irqs in slub_cpu_dead() Vlastimil Babka
2021-07-29 13:21 ` [PATCH v3 28/35] mm, slab: make flush_slab() possible to call with irqs enabled Vlastimil Babka
2021-07-29 13:21 ` Vlastimil Babka [this message]
2021-07-29 13:21 ` [PATCH v3 30/35] mm: slub: Make object_map_lock a raw_spinlock_t Vlastimil Babka
2021-07-29 13:21 ` [PATCH v3 31/35] mm, slub: optionally save/restore irqs in slab_[un]lock()/ Vlastimil Babka
2021-07-29 15:43   ` Mel Gorman
2021-07-29 13:21 ` [PATCH v3 32/35] mm, slub: make slab_lock() disable irqs with PREEMPT_RT Vlastimil Babka
2021-07-29 13:21 ` [PATCH v3 33/35] mm, slub: protect put_cpu_partial() with disabled irqs instead of cmpxchg Vlastimil Babka
2021-07-29 15:42   ` Vlastimil Babka
2021-07-29 13:21 ` [PATCH v3 34/35] mm, slub: use migrate_disable() on PREEMPT_RT Vlastimil Babka
2021-07-29 13:21 ` [PATCH v3 35/35] mm, slub: convert kmem_cpu_slab protection to local_lock Vlastimil Babka
2021-07-29 15:24 ` [PATCH v3 00/35] SLUB: reduce irq disabled scope and make it RT compatible Sebastian Andrzej Siewior
2021-07-29 15:27   ` Vlastimil Babka
2021-07-29 15:29     ` Sebastian Andrzej Siewior
2021-07-29 15:30       ` Sebastian Andrzej Siewior
2021-07-29 15:31       ` Vlastimil Babka
2021-07-29 15:47 ` Vlastimil Babka
2021-07-30  9:19   ` Sebastian Andrzej Siewior
2021-08-04 12:05 ` Mel Gorman
2021-08-04 12:14   ` Vlastimil Babka

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210729132132.19691-30-vbabka@suse.cz \
    --to=vbabka@suse.cz \
    --cc=bigeasy@linutronix.de \
    --cc=brouer@redhat.com \
    --cc=cl@linux.com \
    --cc=efault@gmx.de \
    --cc=iamjoonsoo.kim@lge.com \
    --cc=jannh@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mgorman@techsingularity.net \
    --cc=penberg@kernel.org \
    --cc=rientjes@google.com \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.