sbitmap: correct wake_batch recalculation to avoid potential IO hung
[platform/kernel/linux-starfive.git] / lib / maple_tree.c
index df352f6..69cb44b 100644 (file)
@@ -665,12 +665,13 @@ static inline unsigned long mte_pivot(const struct maple_enode *mn,
                                 unsigned char piv)
 {
        struct maple_node *node = mte_to_node(mn);
+       enum maple_type type = mte_node_type(mn);
 
-       if (piv >= mt_pivots[piv]) {
+       if (piv >= mt_pivots[type]) {
                WARN_ON(1);
                return 0;
        }
-       switch (mte_node_type(mn)) {
+       switch (type) {
        case maple_arange_64:
                return node->ma64.pivot[piv];
        case maple_range_64:
@@ -2989,7 +2990,9 @@ static int mas_spanning_rebalance(struct ma_state *mas,
        mast->free = &free;
        mast->destroy = &destroy;
        l_mas.node = r_mas.node = m_mas.node = MAS_NONE;
-       if (!(mast->orig_l->min && mast->orig_r->max == ULONG_MAX) &&
+
+       /* Check if this is not root and has sufficient data.  */
+       if (((mast->orig_l->min != 0) || (mast->orig_r->max != ULONG_MAX)) &&
            unlikely(mast->bn->b_end <= mt_min_slots[mast->bn->type]))
                mast_spanning_rebalance(mast);
 
@@ -4880,7 +4883,7 @@ static bool mas_rev_awalk(struct ma_state *mas, unsigned long size)
        unsigned long *pivots, *gaps;
        void __rcu **slots;
        unsigned long gap = 0;
-       unsigned long max, min, index;
+       unsigned long max, min;
        unsigned char offset;
 
        if (unlikely(mas_is_err(mas)))
@@ -4902,8 +4905,7 @@ static bool mas_rev_awalk(struct ma_state *mas, unsigned long size)
                min = mas_safe_min(mas, pivots, --offset);
 
        max = mas_safe_pivot(mas, pivots, offset, type);
-       index = mas->index;
-       while (index <= max) {
+       while (mas->index <= max) {
                gap = 0;
                if (gaps)
                        gap = gaps[offset];
@@ -4934,10 +4936,8 @@ static bool mas_rev_awalk(struct ma_state *mas, unsigned long size)
                min = mas_safe_min(mas, pivots, offset);
        }
 
-       if (unlikely(index > max)) {
-               mas_set_err(mas, -EBUSY);
-               return false;
-       }
+       if (unlikely((mas->index > max) || (size - 1 > max - mas->index)))
+               goto no_space;
 
        if (unlikely(ma_is_leaf(type))) {
                mas->offset = offset;
@@ -4954,9 +4954,11 @@ static bool mas_rev_awalk(struct ma_state *mas, unsigned long size)
        return false;
 
 ascend:
-       if (mte_is_root(mas->node))
-               mas_set_err(mas, -EBUSY);
+       if (!mte_is_root(mas->node))
+               return false;
 
+no_space:
+       mas_set_err(mas, -EBUSY);
        return false;
 }