• Catalin Marinas's avatar
    mm: kmemleak: fix delete_object_*() race when called on the same memory block · e781a9ab
    Catalin Marinas authored
    Calling delete_object_*() on the same pointer is not a standard use case
    (unless there is a bug in the code calling kmemleak_free()).  However,
    during kmemleak disabling (error or user triggered via /sys), there is a
    potential race between kmemleak_free() calls on a CPU and
    __kmemleak_do_cleanup() on a different CPU.
    
    The current delete_object_*() implementation first performs a look-up
    holding kmemleak_lock, increments the object->use_count and then
    re-acquires kmemleak_lock to remove the object from object_tree_root and
    object_list.
    
    This patch simplifies the delete_object_*() mechanism to both look up
    and remove an object from the object_tree_root and object_list
    atomically (guarded by kmemleak_lock).  This allows safe concurrent
    calls to delete_object_*() on the same pointer without additional
    locking for synchronising the kmemleak_free_enabled flag.
    
    A side effect is a slight improvement in the delete_object_*() performance
    by avoiding acquiring kmemleak_lock twice and incrementing/decrementing
    object->use_count.
    Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    e781a9ab
kmemleak.c 54 KB