On 7/23/25 19:22, Pavel Tikhomirov wrote:
We have a crash at refill_obj_stock on accessing obj_exts->objcg from
wrong obj_exts, as slab_obj_exts() breaks the original obj_exts pointer.

That happens because we add MEMCG_DATA_PGCACHE to page_memcg_data_flags,
and we already have 3 bits there before, and 4 bits now don't fit into
pointer alignment (pointers are aligned to 8, thus we can use 3 last
bits for flags).

To fix that let's reuse OBJEXTS_ALLOC_FAIL as MEMCG_DATA_PGCACHE for
folios, it should be safe as for folios we don't use obj_exts, and cache
folios do not belong to slab, so we should not see the bit in slab
context, and also should not get the bit from slab context.

Note: we would need to put our flag into corresponding obj_exts if/when
they would be used for regular non-slab folios.


Fixes: 6a2ca4d515c5 ("mm: Memory cgroup page cache limit")

https://virtuozzo.atlassian.net/browse/VSTOR-108538
Signed-off-by: Pavel Tikhomirov <ptikhomi...@virtuozzo.com>

Feature: mm: Memory cgroup page cache limit
---
  include/linux/memcontrol.h | 14 +++++++++++---
  1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 89ce21cdc622..c97bd1a4b3c9 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -360,10 +360,16 @@ enum page_memcg_data_flags {
        MEMCG_DATA_OBJEXTS = (1UL << 0),
        /* page has been accounted as a non-slab kernel page */
        MEMCG_DATA_KMEM = (1UL << 1),
-       /* page has been accounted as a cache page */
-       MEMCG_DATA_PGCACHE = (1UL << 2),
        /* the next bit after the last actual flag */
-       __NR_MEMCG_DATA_FLAGS  = (1UL << 3),
+       __NR_MEMCG_DATA_FLAGS  = (1UL << 2),
+       /*
+        * page has been accounted as a cache page
+        *
+        * This flag coincides with OBJEXTS_ALLOC_FAIL below, but at least now 
we don't
+        * use neither OBJEXTS_ALLOC_FAIL nor MEMCG_DATA_OBJEXTS for folios, 
they are
+        * only used for slab. So this should be safe.
+        */
+       MEMCG_DATA_PGCACHE = (1UL << 2),
  };
#define __FIRST_OBJEXT_FLAG __NR_MEMCG_DATA_FLAGS
@@ -727,6 +733,8 @@ int mem_cgroup_charge_cache(struct folio *folio, struct 
mm_struct *mm,
   */
  static inline bool folio_memcg_cache(struct folio *folio)
  {
+       /* Let's detect when memcg_data will be using obj_exts */
+       VM_BUG_ON_FOLIO(folio->memcg_data & MEMCG_DATA_OBJEXTS, folio);
        return folio->memcg_data & MEMCG_DATA_PGCACHE;
  }

--
Best regards, Pavel Tikhomirov
Senior Software Developer, Virtuozzo.

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to