• Dave Chinner's avatar
    radix-tree: radix_tree_range_tag_if_tagged() can set incorrect tags · 144dcfc0
    Dave Chinner authored
    Commit ebf8aa44 ("radix-tree:
    omplement function radix_tree_range_tag_if_tagged") does not safely
    set tags on on intermediate tree nodes. The code walks down the tree
    setting tags before it has fully resolved the path to the leaf under
    the assumption there will be a leaf slot with the tag set in the
    range it is searching.
    
    Unfortunately, this is not a valid assumption - we can abort after
    setting a tag on an intermediate node if we overrun the number of
    tags we are allowed to set in a batch, or stop scanning because we
    we have passed the last scan index before we reach a leaf slot with
    the tag we are searching for set.
    
    As a result, we can leave the function with tags set on intemediate
    nodes which can be tripped over later by tag-based lookups. The
    result of these stale tags is that lookup may end prematurely or
    livelock because the lookup cannot make progress.
    
    The fix for the problem involves reocrding the traversal path we
    take to the leaf nodes, and only propagating the tags back up the
    tree once the tag is set in the leaf node slot. We are already
    recording the path for efficient traversal, so there is no
    additional overhead to do the intermediately node tag setting in
    this manner.
    
    This fixes a radix tree lookup livelock triggered by the new
    writeback sync livelock avoidance code introduced in commit
    f446daae ("mm: implement writeback
    livelock avoidance using page tagging").
    Signed-off-by: default avatarDave Chinner <dchinner@redhat.com>
    Acked-by: default avatarJan Kara <jack@suse.cz>
    144dcfc0
radix-tree.c 35.7 KB