Commit 3406e91b authored by Vlastimil Babka's avatar Vlastimil Babka
Browse files

mm, slub: make locking in deactivate_slab() irq-safe



dectivate_slab() now no longer touches the kmem_cache_cpu structure, so it will
be possible to call it with irqs enabled. Just convert the spin_lock calls to
their irq saving/restoring variants to make it irq-safe.

Note we now have to use cmpxchg_double_slab() for irq-safe slab_lock(), because
in some situations we don't take the list_lock, which would disable irqs.

Signed-off-by: default avatarVlastimil Babka <vbabka@suse.cz>
parent a019d201
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -2223,6 +2223,7 @@ static void deactivate_slab(struct kmem_cache *s, struct page *page,
	enum slab_modes l = M_NONE, m = M_NONE;
	void *nextfree, *freelist_iter, *freelist_tail;
	int tail = DEACTIVATE_TO_HEAD;
	unsigned long flags = 0;
	struct page new;
	struct page old;

@@ -2298,7 +2299,7 @@ static void deactivate_slab(struct kmem_cache *s, struct page *page,
			 * that acquire_slab() will see a slab page that
			 * is frozen
			 */
			spin_lock(&n->list_lock);
			spin_lock_irqsave(&n->list_lock, flags);
		}
	} else {
		m = M_FULL;
@@ -2309,7 +2310,7 @@ static void deactivate_slab(struct kmem_cache *s, struct page *page,
			 * slabs from diagnostic functions will not see
			 * any frozen slabs.
			 */
			spin_lock(&n->list_lock);
			spin_lock_irqsave(&n->list_lock, flags);
		}
	}

@@ -2326,14 +2327,14 @@ static void deactivate_slab(struct kmem_cache *s, struct page *page,
	}

	l = m;
	if (!__cmpxchg_double_slab(s, page,
	if (!cmpxchg_double_slab(s, page,
				old.freelist, old.counters,
				new.freelist, new.counters,
				"unfreezing slab"))
		goto redo;

	if (lock)
		spin_unlock(&n->list_lock);
		spin_unlock_irqrestore(&n->list_lock, flags);

	if (m == M_PARTIAL)
		stat(s, tail);