• Liam R. Howlett's avatar
    maple_tree: fix mas_skip_node() end slot detection · 0fa99fdf
    Liam R. Howlett authored
    Patch series "Fix mas_skip_node() for mas_empty_area()", v2.
    
    mas_empty_area() was incorrectly returning an error when there was room. 
    The issue was tracked down to mas_skip_node() using the incorrect
    end-of-slot count.  Instead of using the nodes hard limit, the limit of
    data should be used.
    
    mas_skip_node() was also setting the min and max to that of the child
    node, which was unnecessary.  Within these limits being set, there was
    also a bug that corrupted the maple state's max if the offset was set to
    the maximum node pivot.  The bug was without consequence unless there was
    a sufficient gap in the next child node which would cause an error to be
    returned.
    
    This patch set fixes these errors by removing the limit setting from
    mas_skip_node() and uses the mas_data_end() for slot limits, and adds
    tests for all failures discovered.
    
    
    This patch (of 2):
    
    mas_skip_node() is used to move the maple state to the node with a higher
    limit.  It does this by walking up the tree and increasing the slot count.
    Since slot count may not be able to be increased, it may need to walk up
    multiple times to find room to walk right to a higher limit node.  The
    limit of slots that was being used was the node limit and not the last
    location of data in the node.  This would cause the maple state to be
    shifted outside actual data and enter an error state, thus returning
    -EBUSY.
    
    The result of the incorrect error state means that mas_awalk() would
    return an error instead of finding the allocation space.
    
    The fix is to use mas_data_end() in mas_skip_node() to detect the nodes
    data end point and continue walking the tree up until it is safe to move
    to a node with a higher limit.
    
    The walk up the tree also sets the maple state limits so remove the buggy
    code from mas_skip_node().  Setting the limits had the unfortunate side
    effect of triggering another bug if the parent node was full and the there
    was no suitable gap in the second last child, but room in the next child.
    
    mas_skip_node() may also be passed a maple state in an error state from
    mas_anode_descend() when no allocations are available.  Return on such an
    error state immediately.
    
    Link: https://lkml.kernel.org/r/20230307180247.2220303-1-Liam.Howlett@oracle.com
    Link: https://lkml.kernel.org/r/20230307180247.2220303-2-Liam.Howlett@oracle.com
    Fixes: 54a611b6 ("Maple Tree: add new data structure")
    Signed-off-by: default avatarLiam R. Howlett <Liam.Howlett@oracle.com>
    Reported-by: default avatarSnild Dolkow <snild@sony.com>
      Link: https://lore.kernel.org/linux-mm/cb8dc31a-fef2-1d09-f133-e9f7b9f9e77a@sony.com/Tested-by: default avatarSnild Dolkow <snild@sony.com>
    Cc: Peng Zhang <zhangpeng.00@bytedance.com>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    0fa99fdf
maple_tree.c 177 KB