• Hugh Dickins's avatar
    [PATCH] rmaplock: SLAB_DESTROY_BY_RCU · 77631565
    Hugh Dickins authored
    With page_map_lock gone, how to stabilize page->mapping's anon_vma while
    acquiring anon_vma->lock in page_referenced_anon and try_to_unmap_anon?
    
    The page cannot actually be freed (vmscan holds reference), but however much
    we check page_mapped (which guarantees that anon_vma is in use - or would
    guarantee that if we added suitable barriers), there's no locking against page
    becoming unmapped the instant after, then anon_vma freed.
    
    It's okay to take anon_vma->lock after it's freed, so long as it remains a
    struct anon_vma (its list would become empty, or perhaps reused for an
    unrelated anon_vma: but no problem since we always check that the page located
    is the right one); but corruption if that memory gets reused for some other
    purpose.
    
    This is not unique: it's liable to be problem whenever the kernel tries to
    approach a structure obliquely.  It's generally solved with an atomic
    reference count; but one advantage of anon_vma over anonmm is that it does not
    have such a count, and it would be a backward step to add one.
    
    Therefore...  implement SLAB_DESTROY_BY_RCU flag, to guarantee that such a
    kmem_cache_alloc'ed structure cannot get freed to other use while the
    rcu_read_lock is held i.e.  preempt disabled; and use that for anon_vma.
    
    Fix concerns raised by Manfred: this flag is incompatible with poisoning and
    destructor, and kmem_cache_destroy needs to synchronize_kernel.
    
    I hope SLAB_DESTROY_BY_RCU may be useful elsewhere; but though it's safe for
    little anon_vma, I'd be reluctant to use it on any caches whose immediate
    shrinkage under pressure is important to the system.
    Signed-off-by: default avatarHugh Dickins <hugh@veritas.com>
    Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
    77631565
slab.c 80.5 KB