Skip to content

Commit 3ee2d74

Browse files
songmuchunakpm00
authored andcommitted
mm: kfence: fix PG_slab and memcg_data clearing
It does not reset PG_slab and memcg_data when KFENCE fails to initialize kfence pool at runtime. It is reporting a "Bad page state" message when kfence pool is freed to buddy. The checking of whether it is a compound head page seems unnecessary since we already guarantee this when allocating kfence pool. Remove the check to simplify the code. Link: https://lkml.kernel.org/r/20230320030059.20189-1-songmuchun@bytedance.com Fixes: 0ce20dd ("mm: add Kernel Electric-Fence infrastructure") Signed-off-by: Muchun Song <songmuchun@bytedance.com> Cc: Alexander Potapenko <glider@google.com> Cc: Dmitry Vyukov <dvyukov@google.com> Cc: Jann Horn <jannh@google.com> Cc: Marco Elver <elver@google.com> Cc: Roman Gushchin <roman.gushchin@linux.dev> Cc: SeongJae Park <sjpark@amazon.de> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
1 parent e900ba1 commit 3ee2d74

1 file changed

Lines changed: 15 additions & 15 deletions

File tree

mm/kfence/core.c

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -561,10 +561,6 @@ static unsigned long kfence_init_pool(void)
561561
if (!i || (i % 2))
562562
continue;
563563

564-
/* Verify we do not have a compound head page. */
565-
if (WARN_ON(compound_head(&pages[i]) != &pages[i]))
566-
return addr;
567-
568564
__folio_set_slab(slab_folio(slab));
569565
#ifdef CONFIG_MEMCG
570566
slab->memcg_data = (unsigned long)&kfence_metadata[i / 2 - 1].objcg |
@@ -597,12 +593,26 @@ static unsigned long kfence_init_pool(void)
597593

598594
/* Protect the right redzone. */
599595
if (unlikely(!kfence_protect(addr + PAGE_SIZE)))
600-
return addr;
596+
goto reset_slab;
601597

602598
addr += 2 * PAGE_SIZE;
603599
}
604600

605601
return 0;
602+
603+
reset_slab:
604+
for (i = 0; i < KFENCE_POOL_SIZE / PAGE_SIZE; i++) {
605+
struct slab *slab = page_slab(&pages[i]);
606+
607+
if (!i || (i % 2))
608+
continue;
609+
#ifdef CONFIG_MEMCG
610+
slab->memcg_data = 0;
611+
#endif
612+
__folio_clear_slab(slab_folio(slab));
613+
}
614+
615+
return addr;
606616
}
607617

608618
static bool __init kfence_init_pool_early(void)
@@ -632,16 +642,6 @@ static bool __init kfence_init_pool_early(void)
632642
* fails for the first page, and therefore expect addr==__kfence_pool in
633643
* most failure cases.
634644
*/
635-
for (char *p = (char *)addr; p < __kfence_pool + KFENCE_POOL_SIZE; p += PAGE_SIZE) {
636-
struct slab *slab = virt_to_slab(p);
637-
638-
if (!slab)
639-
continue;
640-
#ifdef CONFIG_MEMCG
641-
slab->memcg_data = 0;
642-
#endif
643-
__folio_clear_slab(slab_folio(slab));
644-
}
645645
memblock_free_late(__pa(addr), KFENCE_POOL_SIZE - (addr - (unsigned long)__kfence_pool));
646646
__kfence_pool = NULL;
647647
return false;

0 commit comments

Comments
 (0)