![]() If obj_exts allocation failed, slab->obj_exts is set to OBJEXTS_ALLOC_FAIL, But we do not clear it when freeing the slab. Since OBJEXTS_ALLOC_FAIL and MEMCG_DATA_OBJEXTS currently share the same bit position, during the release of the associated folio, a VM_BUG_ON_FOLIO() check in folio_memcg_kmem() is triggered because the OBJEXTS_ALLOC_FAIL flag was not cleared, causing it to be interpreted as a kmem folio (non-slab) with MEMCG_OBJEXTS_DATA flag set, which is invalid because MEMCG_OBJEXTS_DATA is supposed to be set only on slabs. Another problem that predates sharing the OBJEXTS_ALLOC_FAIL and MEMCG_DATA_OBJEXTS bits is that on configurations with is_check_pages_enabled(), the non-cleared bit in page->memcg_data will trigger a free_page_is_bad() failure "page still charged to cgroup" When freeing a slab, we clear slab->obj_exts if the obj_ext array has been successfully allocated. So let's clear it also when the allocation has failed. Fixes: |
||
---|---|---|
.. | ||
damon | ||
kasan | ||
kfence | ||
kmsan | ||
Kconfig | ||
Kconfig.debug | ||
Makefile | ||
backing-dev.c | ||
balloon_compaction.c | ||
bootmem_info.c | ||
cma.c | ||
cma.h | ||
cma_debug.c | ||
cma_sysfs.c | ||
compaction.c | ||
debug.c | ||
debug_page_alloc.c | ||
debug_page_ref.c | ||
debug_vm_pgtable.c | ||
dmapool.c | ||
dmapool_test.c | ||
early_ioremap.c | ||
execmem.c | ||
fadvise.c | ||
fail_page_alloc.c | ||
failslab.c | ||
filemap.c | ||
folio-compat.c | ||
gup.c | ||
gup_test.c | ||
gup_test.h | ||
highmem.c | ||
hmm.c | ||
huge_memory.c | ||
hugetlb.c | ||
hugetlb_cgroup.c | ||
hugetlb_cma.c | ||
hugetlb_cma.h | ||
hugetlb_vmemmap.c | ||
hugetlb_vmemmap.h | ||
hwpoison-inject.c | ||
init-mm.c | ||
internal.h | ||
interval_tree.c | ||
ioremap.c | ||
khugepaged.c | ||
kmemleak.c | ||
ksm.c | ||
list_lru.c | ||
maccess.c | ||
madvise.c | ||
mapping_dirty_helpers.c | ||
memblock.c | ||
memcontrol-v1.c | ||
memcontrol-v1.h | ||
memcontrol.c | ||
memfd.c | ||
memory-failure.c | ||
memory-tiers.c | ||
memory.c | ||
memory_hotplug.c | ||
mempolicy.c | ||
mempool.c | ||
memremap.c | ||
memtest.c | ||
migrate.c | ||
migrate_device.c | ||
mincore.c | ||
mlock.c | ||
mm_init.c | ||
mm_slot.h | ||
mmap.c | ||
mmap_lock.c | ||
mmu_gather.c | ||
mmu_notifier.c | ||
mmzone.c | ||
mprotect.c | ||
mremap.c | ||
mseal.c | ||
msync.c | ||
nommu.c | ||
numa.c | ||
numa_emulation.c | ||
numa_memblks.c | ||
oom_kill.c | ||
page-writeback.c | ||
page_alloc.c | ||
page_counter.c | ||
page_ext.c | ||
page_frag_cache.c | ||
page_idle.c | ||
page_io.c | ||
page_isolation.c | ||
page_owner.c | ||
page_poison.c | ||
page_reporting.c | ||
page_reporting.h | ||
page_table_check.c | ||
page_vma_mapped.c | ||
pagewalk.c | ||
percpu-internal.h | ||
percpu-km.c | ||
percpu-stats.c | ||
percpu-vm.c | ||
percpu.c | ||
pgalloc-track.h | ||
pgtable-generic.c | ||
process_vm_access.c | ||
pt_reclaim.c | ||
ptdump.c | ||
readahead.c | ||
rmap.c | ||
rodata_test.c | ||
secretmem.c | ||
shmem.c | ||
shmem_quota.c | ||
show_mem.c | ||
shrinker.c | ||
shrinker_debug.c | ||
shuffle.c | ||
shuffle.h | ||
slab.h | ||
slab_common.c | ||
slub.c | ||
sparse-vmemmap.c | ||
sparse.c | ||
swap.c | ||
swap.h | ||
swap_cgroup.c | ||
swap_state.c | ||
swap_table.h | ||
swapfile.c | ||
truncate.c | ||
usercopy.c | ||
userfaultfd.c | ||
util.c | ||
vma.c | ||
vma.h | ||
vma_exec.c | ||
vma_init.c | ||
vma_internal.h | ||
vmalloc.c | ||
vmpressure.c | ||
vmscan.c | ||
vmstat.c | ||
workingset.c | ||
zpdesc.h | ||
zsmalloc.c | ||
zswap.c |