diff options
author | Vlastimil Babka <vbabka@suse.cz> | 2022-11-10 12:42:34 +0300 |
---|---|---|
committer | Vlastimil Babka <vbabka@suse.cz> | 2022-11-21 12:36:09 +0300 |
commit | 76537db3b95cbf5d0189ce185c16db9f93017021 (patch) | |
tree | a09d81a797d52a9a64da0470ec25997b81d8499e /mm/slub.c | |
parent | 1c1aaa3319ab860883791edd2ba3e55610214c2e (diff) | |
parent | 130d4df57390a29521cb7cccd1b3144c184c111c (diff) | |
download | linux-76537db3b95cbf5d0189ce185c16db9f93017021.tar.xz |
Merge branch 'slab/for-6.2/fit_rcu_head' into slab/for-next
A series by myself to reorder fields in struct slab to allow the
embedded rcu_head to grow (for debugging purposes). Requires changes to
isolate_movable_page() to skip slab pages which can otherwise become
false-positive __PageMovable due to its use of low bits in
page->mapping.
Diffstat (limited to 'mm/slub.c')
-rw-r--r-- | mm/slub.c | 26 |
1 files changed, 15 insertions, 11 deletions
diff --git a/mm/slub.c b/mm/slub.c index 1ff5319c0ea8..0a14e7bc278c 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -1800,6 +1800,8 @@ static inline struct slab *alloc_slab_page(gfp_t flags, int node, slab = folio_slab(folio); __folio_set_slab(folio); + /* Make the flag visible before any changes to folio->mapping */ + smp_wmb(); if (page_is_pfmemalloc(folio_page(folio, 0))) slab_set_pfmemalloc(slab); @@ -1999,17 +2001,11 @@ static void __free_slab(struct kmem_cache *s, struct slab *slab) int order = folio_order(folio); int pages = 1 << order; - if (kmem_cache_debug_flags(s, SLAB_CONSISTENCY_CHECKS)) { - void *p; - - slab_pad_check(s, slab); - for_each_object(p, s, slab_address(slab), slab->objects) - check_object(s, slab, p, SLUB_RED_INACTIVE); - } - __slab_clear_pfmemalloc(slab); - __folio_clear_slab(folio); folio->mapping = NULL; + /* Make the mapping reset visible before clearing the flag */ + smp_wmb(); + __folio_clear_slab(folio); if (current->reclaim_state) current->reclaim_state->reclaimed_slab += pages; unaccount_slab(slab, order, s); @@ -2025,9 +2021,17 @@ static void rcu_free_slab(struct rcu_head *h) static void free_slab(struct kmem_cache *s, struct slab *slab) { - if (unlikely(s->flags & SLAB_TYPESAFE_BY_RCU)) { + if (kmem_cache_debug_flags(s, SLAB_CONSISTENCY_CHECKS)) { + void *p; + + slab_pad_check(s, slab); + for_each_object(p, s, slab_address(slab), slab->objects) + check_object(s, slab, p, SLUB_RED_INACTIVE); + } + + if (unlikely(s->flags & SLAB_TYPESAFE_BY_RCU)) call_rcu(&slab->rcu_head, rcu_free_slab); - } else + else __free_slab(s, slab); } |