• N
    radix-tree: fix RCU bug · 27d20fdd
    Nick Piggin 提交于
    Salman Qazi describes the following radix-tree bug:
    
    In the following case, we get can get a deadlock:
    
    0.  The radix tree contains two items, one has the index 0.
    1.  The reader (in this case find_get_pages) takes the rcu_read_lock.
    2.  The reader acquires slot(s) for item(s) including the index 0 item.
    3.  The non-zero index item is deleted, and as a consequence the other item is
        moved to the root of the tree. The place where it used to be is queued for
        deletion after the readers finish.
    3b. The zero item is deleted, removing it from the direct slot, it remains in
        the rcu-delayed indirect node.
    4.  The reader looks at the index 0 slot, and finds that the page has 0 ref
        count
    5.  The reader looks at it again, hoping that the item will either be freed or
        the ref count will increase. This never happens, as the slot it is looking
        at will never be updated. Also, this slot can never be reclaimed because
        the reader is holding rcu_read_lock and is in an infinite loop.
    
    The fix is to re-use the same "indirect" pointer case that requires a slot
    lookup retry into a general "retry the lookup" bit.
    Signed-off-by: NNick Piggin <npiggin@kernel.dk>
    Reported-by: NSalman Qazi <sqazi@google.com>
    Cc: <stable@kernel.org>
    Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
    27d20fdd
filemap.c 66.4 KB