aboutsummaryrefslogtreecommitdiffstats
path: root/features/rt/mm-slub-Move-discard_slab-invocations-out-of-IRQ-off.patch
diff options
context:
space:
mode:
Diffstat (limited to 'features/rt/mm-slub-Move-discard_slab-invocations-out-of-IRQ-off.patch')
-rw-r--r--features/rt/mm-slub-Move-discard_slab-invocations-out-of-IRQ-off.patch416
1 files changed, 0 insertions, 416 deletions
diff --git a/features/rt/mm-slub-Move-discard_slab-invocations-out-of-IRQ-off.patch b/features/rt/mm-slub-Move-discard_slab-invocations-out-of-IRQ-off.patch
deleted file mode 100644
index 9f53a2dd..00000000
--- a/features/rt/mm-slub-Move-discard_slab-invocations-out-of-IRQ-off.patch
+++ /dev/null
@@ -1,416 +0,0 @@
-From a554a721d714cba4bf3c8eb17e25913fa593a6bf Mon Sep 17 00:00:00 2001
-From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
-Date: Fri, 26 Feb 2021 15:14:15 +0100
-Subject: [PATCH 107/191] mm: slub: Move discard_slab() invocations out of
- IRQ-off sections
-
-discard_slab() gives the memory back to the page-allocator. Some of its
-invocation occur from IRQ-disabled sections which were disabled by SLUB.
-An example is the deactivate_slab() invocation from within
-___slab_alloc() or put_cpu_partial().
-
-Instead of giving the memory back directly, put the pages on a list and
-process it once the caller is out of the known IRQ-off region.
-
-Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
----
- mm/slub.c | 114 +++++++++++++++++++++++++++++++++++++-----------------
- 1 file changed, 78 insertions(+), 36 deletions(-)
-
-diff --git a/mm/slub.c b/mm/slub.c
-index 1382845c3802..af9c0fbe2cf5 100644
---- a/mm/slub.c
-+++ b/mm/slub.c
-@@ -1889,12 +1889,29 @@ static void free_slab(struct kmem_cache *s, struct page *page)
- __free_slab(s, page);
- }
-
-+static void discard_slab_delayed(struct kmem_cache *s, struct page *page,
-+ struct list_head *delayed_free)
-+{
-+ dec_slabs_node(s, page_to_nid(page), page->objects);
-+ list_add(&page->lru, delayed_free);
-+}
-+
- static void discard_slab(struct kmem_cache *s, struct page *page)
- {
- dec_slabs_node(s, page_to_nid(page), page->objects);
- free_slab(s, page);
- }
-
-+static void discard_delayed(struct list_head *l)
-+{
-+ while (!list_empty(l)) {
-+ struct page *page = list_first_entry(l, struct page, lru);
-+
-+ list_del(&page->lru);
-+ __free_slab(page->slab_cache, page);
-+ }
-+}
-+
- /*
- * Management of partially allocated slabs.
- */
-@@ -1968,15 +1985,16 @@ static inline void *acquire_slab(struct kmem_cache *s,
- WARN_ON(!freelist);
- return freelist;
- }
--
--static void put_cpu_partial(struct kmem_cache *s, struct page *page, int drain);
-+static void put_cpu_partial(struct kmem_cache *s, struct page *page, int drain,
-+ struct list_head *delayed_free);
- static inline bool pfmemalloc_match(struct page *page, gfp_t gfpflags);
-
- /*
- * Try to allocate a partial slab from a specific node.
- */
- static void *get_partial_node(struct kmem_cache *s, struct kmem_cache_node *n,
-- struct kmem_cache_cpu *c, gfp_t flags)
-+ struct kmem_cache_cpu *c, gfp_t flags,
-+ struct list_head *delayed_free)
- {
- struct page *page, *page2;
- void *object = NULL;
-@@ -2009,7 +2027,7 @@ static void *get_partial_node(struct kmem_cache *s, struct kmem_cache_node *n,
- stat(s, ALLOC_FROM_PARTIAL);
- object = t;
- } else {
-- put_cpu_partial(s, page, 0);
-+ put_cpu_partial(s, page, 0, delayed_free);
- stat(s, CPU_PARTIAL_NODE);
- }
- if (!kmem_cache_has_cpu_partial(s)
-@@ -2025,7 +2043,8 @@ static void *get_partial_node(struct kmem_cache *s, struct kmem_cache_node *n,
- * Get a page from somewhere. Search in increasing NUMA distances.
- */
- static void *get_any_partial(struct kmem_cache *s, gfp_t flags,
-- struct kmem_cache_cpu *c)
-+ struct kmem_cache_cpu *c,
-+ struct list_head *delayed_free)
- {
- #ifdef CONFIG_NUMA
- struct zonelist *zonelist;
-@@ -2067,7 +2086,7 @@ static void *get_any_partial(struct kmem_cache *s, gfp_t flags,
-
- if (n && cpuset_zone_allowed(zone, flags) &&
- n->nr_partial > s->min_partial) {
-- object = get_partial_node(s, n, c, flags);
-+ object = get_partial_node(s, n, c, flags, delayed_free);
- if (object) {
- /*
- * Don't check read_mems_allowed_retry()
-@@ -2089,7 +2108,8 @@ static void *get_any_partial(struct kmem_cache *s, gfp_t flags,
- * Get a partial page, lock it and return it.
- */
- static void *get_partial(struct kmem_cache *s, gfp_t flags, int node,
-- struct kmem_cache_cpu *c)
-+ struct kmem_cache_cpu *c,
-+ struct list_head *delayed_free)
- {
- void *object;
- int searchnode = node;
-@@ -2097,11 +2117,12 @@ static void *get_partial(struct kmem_cache *s, gfp_t flags, int node,
- if (node == NUMA_NO_NODE)
- searchnode = numa_mem_id();
-
-- object = get_partial_node(s, get_node(s, searchnode), c, flags);
-+ object = get_partial_node(s, get_node(s, searchnode), c, flags,
-+ delayed_free);
- if (object || node != NUMA_NO_NODE)
- return object;
-
-- return get_any_partial(s, flags, c);
-+ return get_any_partial(s, flags, c, delayed_free);
- }
-
- #ifdef CONFIG_PREEMPTION
-@@ -2177,7 +2198,8 @@ static void init_kmem_cache_cpus(struct kmem_cache *s)
- * Remove the cpu slab
- */
- static void deactivate_slab(struct kmem_cache *s, struct page *page,
-- void *freelist, struct kmem_cache_cpu *c)
-+ void *freelist, struct kmem_cache_cpu *c,
-+ struct list_head *delayed_free)
- {
- enum slab_modes { M_NONE, M_PARTIAL, M_FULL, M_FREE };
- struct kmem_cache_node *n = get_node(s, page_to_nid(page));
-@@ -2303,7 +2325,7 @@ static void deactivate_slab(struct kmem_cache *s, struct page *page,
- stat(s, DEACTIVATE_FULL);
- else if (m == M_FREE) {
- stat(s, DEACTIVATE_EMPTY);
-- discard_slab(s, page);
-+ discard_slab_delayed(s, page, delayed_free);
- stat(s, FREE_SLAB);
- }
-
-@@ -2318,8 +2340,8 @@ static void deactivate_slab(struct kmem_cache *s, struct page *page,
- * for the cpu using c (or some other guarantee must be there
- * to guarantee no concurrent accesses).
- */
--static void unfreeze_partials(struct kmem_cache *s,
-- struct kmem_cache_cpu *c)
-+static void unfreeze_partials(struct kmem_cache *s, struct kmem_cache_cpu *c,
-+ struct list_head *delayed_free)
- {
- #ifdef CONFIG_SLUB_CPU_PARTIAL
- struct kmem_cache_node *n = NULL, *n2 = NULL;
-@@ -2373,7 +2395,7 @@ static void unfreeze_partials(struct kmem_cache *s,
- discard_page = discard_page->next;
-
- stat(s, DEACTIVATE_EMPTY);
-- discard_slab(s, page);
-+ discard_slab_delayed(s, page, delayed_free);
- stat(s, FREE_SLAB);
- }
- #endif /* CONFIG_SLUB_CPU_PARTIAL */
-@@ -2386,7 +2408,8 @@ static void unfreeze_partials(struct kmem_cache *s,
- * If we did not find a slot then simply move all the partials to the
- * per node partial list.
- */
--static void put_cpu_partial(struct kmem_cache *s, struct page *page, int drain)
-+static void put_cpu_partial(struct kmem_cache *s, struct page *page, int drain,
-+ struct list_head *delayed_free)
- {
- #ifdef CONFIG_SLUB_CPU_PARTIAL
- struct page *oldpage;
-@@ -2409,7 +2432,8 @@ static void put_cpu_partial(struct kmem_cache *s, struct page *page, int drain)
- * set to the per node partial list.
- */
- local_irq_save(flags);
-- unfreeze_partials(s, this_cpu_ptr(s->cpu_slab));
-+ unfreeze_partials(s, this_cpu_ptr(s->cpu_slab),
-+ delayed_free);
- local_irq_restore(flags);
- oldpage = NULL;
- pobjects = 0;
-@@ -2431,17 +2455,18 @@ static void put_cpu_partial(struct kmem_cache *s, struct page *page, int drain)
- unsigned long flags;
-
- local_irq_save(flags);
-- unfreeze_partials(s, this_cpu_ptr(s->cpu_slab));
-+ unfreeze_partials(s, this_cpu_ptr(s->cpu_slab), delayed_free);
- local_irq_restore(flags);
- }
- preempt_enable();
- #endif /* CONFIG_SLUB_CPU_PARTIAL */
- }
-
--static inline void flush_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
-+static inline void flush_slab(struct kmem_cache *s, struct kmem_cache_cpu *c,
-+ struct list_head *delayed_free)
- {
- stat(s, CPUSLAB_FLUSH);
-- deactivate_slab(s, c->page, c->freelist, c);
-+ deactivate_slab(s, c->page, c->freelist, c, delayed_free);
-
- c->tid = next_tid(c->tid);
- }
-@@ -2451,21 +2476,24 @@ static inline void flush_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
- *
- * Called from IPI handler with interrupts disabled.
- */
--static inline void __flush_cpu_slab(struct kmem_cache *s, int cpu)
-+static inline void __flush_cpu_slab(struct kmem_cache *s, int cpu,
-+ struct list_head *delayed_free)
- {
- struct kmem_cache_cpu *c = per_cpu_ptr(s->cpu_slab, cpu);
-
- if (c->page)
-- flush_slab(s, c);
-+ flush_slab(s, c, delayed_free);
-
-- unfreeze_partials(s, c);
-+ unfreeze_partials(s, c, delayed_free);
- }
-
- static void flush_cpu_slab(void *d)
- {
- struct kmem_cache *s = d;
-+ LIST_HEAD(delayed_free);
-
-- __flush_cpu_slab(s, smp_processor_id());
-+ __flush_cpu_slab(s, smp_processor_id(), &delayed_free);
-+ discard_delayed(&delayed_free);
- }
-
- static bool has_cpu_slab(int cpu, void *info)
-@@ -2489,13 +2517,15 @@ static int slub_cpu_dead(unsigned int cpu)
- {
- struct kmem_cache *s;
- unsigned long flags;
-+ LIST_HEAD(delayed_free);
-
- mutex_lock(&slab_mutex);
- list_for_each_entry(s, &slab_caches, list) {
- local_irq_save(flags);
-- __flush_cpu_slab(s, cpu);
-+ __flush_cpu_slab(s, cpu, &delayed_free);
- local_irq_restore(flags);
- }
-+ discard_delayed(&delayed_free);
- mutex_unlock(&slab_mutex);
- return 0;
- }
-@@ -2579,7 +2609,8 @@ slab_out_of_memory(struct kmem_cache *s, gfp_t gfpflags, int nid)
- }
-
- static inline void *new_slab_objects(struct kmem_cache *s, gfp_t flags,
-- int node, struct kmem_cache_cpu **pc)
-+ int node, struct kmem_cache_cpu **pc,
-+ struct list_head *delayed_free)
- {
- void *freelist;
- struct kmem_cache_cpu *c = *pc;
-@@ -2587,7 +2618,7 @@ static inline void *new_slab_objects(struct kmem_cache *s, gfp_t flags,
-
- WARN_ON_ONCE(s->ctor && (flags & __GFP_ZERO));
-
-- freelist = get_partial(s, flags, node, c);
-+ freelist = get_partial(s, flags, node, c, delayed_free);
-
- if (freelist)
- return freelist;
-@@ -2596,7 +2627,7 @@ static inline void *new_slab_objects(struct kmem_cache *s, gfp_t flags,
- if (page) {
- c = raw_cpu_ptr(s->cpu_slab);
- if (c->page)
-- flush_slab(s, c);
-+ flush_slab(s, c, delayed_free);
-
- /*
- * No other reference to the page yet so we can
-@@ -2675,7 +2706,8 @@ static inline void *get_freelist(struct kmem_cache *s, struct page *page)
- * already disabled (which is the case for bulk allocation).
- */
- static void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
-- unsigned long addr, struct kmem_cache_cpu *c)
-+ unsigned long addr, struct kmem_cache_cpu *c,
-+ struct list_head *delayed_free)
- {
- void *freelist;
- struct page *page;
-@@ -2705,7 +2737,7 @@ static void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
- goto redo;
- } else {
- stat(s, ALLOC_NODE_MISMATCH);
-- deactivate_slab(s, page, c->freelist, c);
-+ deactivate_slab(s, page, c->freelist, c, delayed_free);
- goto new_slab;
- }
- }
-@@ -2716,7 +2748,7 @@ static void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
- * information when the page leaves the per-cpu allocator
- */
- if (unlikely(!pfmemalloc_match(page, gfpflags))) {
-- deactivate_slab(s, page, c->freelist, c);
-+ deactivate_slab(s, page, c->freelist, c, delayed_free);
- goto new_slab;
- }
-
-@@ -2755,7 +2787,7 @@ static void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
- goto redo;
- }
-
-- freelist = new_slab_objects(s, gfpflags, node, &c);
-+ freelist = new_slab_objects(s, gfpflags, node, &c, delayed_free);
-
- if (unlikely(!freelist)) {
- slab_out_of_memory(s, gfpflags, node);
-@@ -2771,7 +2803,7 @@ static void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
- !alloc_debug_processing(s, page, freelist, addr))
- goto new_slab; /* Slab failed checks. Next slab needed */
-
-- deactivate_slab(s, page, get_freepointer(s, freelist), c);
-+ deactivate_slab(s, page, get_freepointer(s, freelist), c, delayed_free);
- return freelist;
- }
-
-@@ -2784,6 +2816,7 @@ static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
- {
- void *p;
- unsigned long flags;
-+ LIST_HEAD(delayed_free);
-
- local_irq_save(flags);
- #ifdef CONFIG_PREEMPTION
-@@ -2795,8 +2828,9 @@ static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
- c = this_cpu_ptr(s->cpu_slab);
- #endif
-
-- p = ___slab_alloc(s, gfpflags, node, addr, c);
-+ p = ___slab_alloc(s, gfpflags, node, addr, c, &delayed_free);
- local_irq_restore(flags);
-+ discard_delayed(&delayed_free);
- return p;
- }
-
-@@ -3060,11 +3094,13 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
- */
- stat(s, FREE_FROZEN);
- } else if (new.frozen) {
-+ LIST_HEAD(delayed_free);
- /*
- * If we just froze the page then put it onto the
- * per cpu partial list.
- */
-- put_cpu_partial(s, page, 1);
-+ put_cpu_partial(s, page, 1, &delayed_free);
-+ discard_delayed(&delayed_free);
- stat(s, CPU_PARTIAL_FREE);
- }
-
-@@ -3315,6 +3351,7 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size,
- struct kmem_cache_cpu *c;
- int i;
- struct obj_cgroup *objcg = NULL;
-+ LIST_HEAD(delayed_free);
-
- if (IS_ENABLED(CONFIG_PREEMPT_RT) && IS_ENABLED(CONFIG_DEBUG_ATOMIC_SLEEP))
- WARN_ON_ONCE(!preemptible() &&
-@@ -3356,7 +3393,7 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size,
- * of re-populating per CPU c->freelist
- */
- p[i] = ___slab_alloc(s, flags, NUMA_NO_NODE,
-- _RET_IP_, c);
-+ _RET_IP_, c, &delayed_free);
- if (unlikely(!p[i]))
- goto error;
-
-@@ -3372,6 +3409,8 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size,
- c->tid = next_tid(c->tid);
- local_irq_enable();
-
-+ discard_delayed(&delayed_free);
-+
- /* Clear memory outside IRQ disabled fastpath loop */
- if (unlikely(slab_want_init_on_alloc(flags, s))) {
- int j;
-@@ -3385,6 +3424,7 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size,
- return i;
- error:
- local_irq_enable();
-+ discard_delayed(&delayed_free);
- slab_post_alloc_hook(s, objcg, flags, i, p);
- __kmem_cache_free_bulk(s, i, p);
- return 0;
-@@ -4437,6 +4477,7 @@ static struct kmem_cache * __init bootstrap(struct kmem_cache *static_cache)
- int node;
- struct kmem_cache *s = kmem_cache_zalloc(kmem_cache, GFP_NOWAIT);
- struct kmem_cache_node *n;
-+ LIST_HEAD(delayed_free);
-
- memcpy(s, static_cache, kmem_cache->object_size);
-
-@@ -4445,7 +4486,8 @@ static struct kmem_cache * __init bootstrap(struct kmem_cache *static_cache)
- * up. Even if it weren't true, IRQs are not up so we couldn't fire
- * IPIs around.
- */
-- __flush_cpu_slab(s, smp_processor_id());
-+ __flush_cpu_slab(s, smp_processor_id(), &delayed_free);
-+ discard_delayed(&delayed_free);
- for_each_kmem_cache_node(s, node, n) {
- struct page *p;
-
---
-2.19.1
-