codetag: debug: handle existing CODETAG_EMPTY in mark_objexts_empty for slabobj_ext
Subsystems (3)
PATCH v2 1/1 codetag: debug: handle existing CODETAG_EMPTY in mark_objexts_empty for slabobj_ext
From: Hao Ge <[email protected]>
When alloc_slab_obj_exts() fails and then later succeeds in allocating a slab extension vector, it calls handle_failed_objexts_alloc() to mark all objects in the vector as empty. As a result all objects in this slab (slabA) will have their extensions set to CODETAG_EMPTY. Later on if this slabA is used to allocate a slabobj_ext vector for another slab (slabB), we end up with the slabB->obj_exts pointing to a slabobj_ext vector that itself has a non-NULL slabobj_ext equal to CODETAG_EMPTY. When slabB gets freed, free_slab_obj_exts() is called to free slabB->obj_exts vector. free_slab_obj_exts() calls mark_objexts_empty(slabB->obj_exts) which will generate a warning because it expects slabobj_ext vectors to have a NULL obj_ext, not CODETAG_EMPTY.
Modify mark_objexts_empty() to skip the warning and setting the obj_ext value if it's already set to CODETAG_EMPTY.
---
v2: Update the commit message and code comments for greater accuracy,
incorporating Suren's suggestions.
Thanks for Suren's help.
--- mm/slub.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
mm/slub.c +5 -1
@@ -2046,7 +2046,11 @@ static inline void mark_objexts_empty(struct slabobj_ext *obj_exts)if (slab_exts) {unsigned int offs =obj_to_index (obj_exts_slab->slab_cache, obj_exts_slab, obj_exts); -/* codetag should be NULL */ + +if (unlikely (is_codetag_empty (&slab_exts[offs].ref))) +return ; + +/* codetag should be NULL here */ WARN_ON (slab_exts[offs].ref.ct);set_codetag_empty (&slab_exts[offs].ref); }
Signature · 1 line
2.25.1
Quoted 16 lines · Hao Ge
From: Hao Ge <[email protected]>
When
alloc_slab_obj_exts()fails and then later succeeds in allocating a slab extension vector, it callshandle_failed_objexts_alloc()to mark all objects in the vector as empty. As a result all objects in this slab (slabA) will have their extensions set toCODETAG_EMPTY. Later on if this slabA is used to allocate aslabobj_extvector for another slab (slabB), we end up with theslabB->obj_extspointing to aslabobj_extvector that itself has a non-NULLslabobj_extequal toCODETAG_EMPTY. When slabB gets freed,free_slab_obj_exts()is called to freeslabB->obj_extsvector.free_slab_obj_exts()callsmark_objexts_empty(slabB->obj_exts)which will generate a warning because it expectsslabobj_extvectors to have a NULLobj_ext, notCODETAG_EMPTY.
Quoted 6 lines
Modify
mark_objexts_empty()to skip the warning and setting theobj_extvalue if it's already set toCODETAG_EMPTY.Fixes 09c46563ff6d ("codetag: debug: introduce OBJEXTS_ALLOC_FAIL to mark failed slab_ext allocations")Cc <[email protected]>Signed-off-by Hao Ge <[email protected]>
Quoted 29 lines
---
v2: Update the commit message and code comments for greater accuracy,
incorporating Suren's suggestions.
Thanks for Suren's help.--- mm/slub.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)mm/slub.c +5
-2@@ -2046,7 +2046,11 @@ static inline void mark_objexts_empty(struct slabobj_ext *obj_exts)if (slab_exts) {unsigned int offs =obj_to_index (obj_exts_slab->slab_cache, obj_exts_slab, obj_exts); -/* codetag should be NULL */ + +if (unlikely (is_codetag_empty (&slab_exts[offs].ref))) +return ; + +/* codetag should be NULL here */ WARN_ON (slab_exts[offs].ref.ct);set_codetag_empty (&slab_exts[offs].ref); } --2.25.1