2023-05-15 13:32:54

by Peng Zhang

[permalink] [raw]
Subject: [PATCH 02/10] maple_tree: Drop mtree_alloc_{range,rrange}() and related functions.

Drop mtree_alloc_{range,rrange}(), mas_{rev_}alloc() and mas_fill_gap().
mtree_alloc_{range,rrange}() currently have no users and can be easily
implemented with mas_empty_area{_rev}(). mas_{rev_}alloc() and
mas_fill_gap() are just their internal functions, drop them together.

Signed-off-by: Peng Zhang <[email protected]>
---
include/linux/maple_tree.h | 7 --
lib/maple_tree.c | 177 -------------------------------------
2 files changed, 184 deletions(-)

diff --git a/include/linux/maple_tree.h b/include/linux/maple_tree.h
index 542b09118a09f..3dd6edccf83af 100644
--- a/include/linux/maple_tree.h
+++ b/include/linux/maple_tree.h
@@ -306,13 +306,6 @@ int mtree_insert(struct maple_tree *mt, unsigned long index,
void *entry, gfp_t gfp);
int mtree_insert_range(struct maple_tree *mt, unsigned long first,
unsigned long last, void *entry, gfp_t gfp);
-int mtree_alloc_range(struct maple_tree *mt, unsigned long *startp,
- void *entry, unsigned long size, unsigned long min,
- unsigned long max, gfp_t gfp);
-int mtree_alloc_rrange(struct maple_tree *mt, unsigned long *startp,
- void *entry, unsigned long size, unsigned long min,
- unsigned long max, gfp_t gfp);
-
int mtree_store_range(struct maple_tree *mt, unsigned long first,
unsigned long last, void *entry, gfp_t gfp);
int mtree_store(struct maple_tree *mt, unsigned long index,
diff --git a/lib/maple_tree.c b/lib/maple_tree.c
index b37065a6f570d..49dfe81dfa1b6 100644
--- a/lib/maple_tree.c
+++ b/lib/maple_tree.c
@@ -5120,46 +5120,6 @@ static inline void mas_awalk(struct ma_state *mas, unsigned long size)
}
}

-/*
- * mas_fill_gap() - Fill a located gap with @entry.
- * @mas: The maple state
- * @entry: The value to store
- * @slot: The offset into the node to store the @entry
- * @size: The size of the entry
- * @index: The start location
- */
-static inline void mas_fill_gap(struct ma_state *mas, void *entry,
- unsigned char slot, unsigned long size, unsigned long *index)
-{
- MA_WR_STATE(wr_mas, mas, entry);
- unsigned char pslot = mte_parent_slot(mas->node);
- struct maple_enode *mn = mas->node;
- unsigned long *pivots;
- enum maple_type ptype;
- /*
- * mas->index is the start address for the search
- * which may no longer be needed.
- * mas->last is the end address for the search
- */
-
- *index = mas->index;
- mas->last = mas->index + size - 1;
-
- /*
- * It is possible that using mas->max and mas->min to correctly
- * calculate the index and last will cause an issue in the gap
- * calculation, so fix the ma_state here
- */
- mas_ascend(mas);
- ptype = mte_node_type(mas->node);
- pivots = ma_pivots(mas_mn(mas), ptype);
- mas->max = mas_safe_pivot(mas, pivots, pslot, ptype);
- mas->min = mas_safe_min(mas, pivots, pslot);
- mas->node = mn;
- mas->offset = slot;
- mas_wr_store_entry(&wr_mas);
-}
-
/*
* mas_sparse_area() - Internal function. Return upper or lower limit when
* searching for a gap in an empty tree.
@@ -5307,74 +5267,6 @@ int mas_empty_area_rev(struct ma_state *mas, unsigned long min,
}
EXPORT_SYMBOL_GPL(mas_empty_area_rev);

-static inline int mas_alloc(struct ma_state *mas, void *entry,
- unsigned long size, unsigned long *index)
-{
- unsigned long min;
-
- mas_start(mas);
- if (mas_is_none(mas) || mas_is_ptr(mas)) {
- mas_root_expand(mas, entry);
- if (mas_is_err(mas))
- return xa_err(mas->node);
-
- if (!mas->index)
- return mas_pivot(mas, 0);
- return mas_pivot(mas, 1);
- }
-
- /* Must be walking a tree. */
- mas_awalk(mas, size);
- if (mas_is_err(mas))
- return xa_err(mas->node);
-
- if (mas->offset == MAPLE_NODE_SLOTS)
- goto no_gap;
-
- /*
- * At this point, mas->node points to the right node and we have an
- * offset that has a sufficient gap.
- */
- min = mas->min;
- if (mas->offset)
- min = mas_pivot(mas, mas->offset - 1) + 1;
-
- if (mas_is_err(mas))
- return xa_err(mas->node);
-
- if (mas->index < min)
- mas->index = min;
-
- mas_fill_gap(mas, entry, mas->offset, size, index);
- return 0;
-
-no_gap:
- return -EBUSY;
-}
-
-static inline int mas_rev_alloc(struct ma_state *mas, unsigned long min,
- unsigned long max, void *entry,
- unsigned long size, unsigned long *index)
-{
- int ret = 0;
-
- ret = mas_empty_area_rev(mas, min, max, size);
- if (ret)
- return ret;
-
- if (mas_is_err(mas))
- return xa_err(mas->node);
-
- if (mas->offset == MAPLE_NODE_SLOTS)
- goto no_gap;
-
- mas_fill_gap(mas, entry, mas->offset, size, index);
- return 0;
-
-no_gap:
- return -EBUSY;
-}
-
/*
* mte_dead_leaves() - Mark all leaves of a node as dead.
* @mas: The maple state
@@ -6481,75 +6373,6 @@ int mtree_insert(struct maple_tree *mt, unsigned long index, void *entry,
}
EXPORT_SYMBOL(mtree_insert);

-int mtree_alloc_range(struct maple_tree *mt, unsigned long *startp,
- void *entry, unsigned long size, unsigned long min,
- unsigned long max, gfp_t gfp)
-{
- int ret = 0;
-
- MA_STATE(mas, mt, min, min);
- if (!mt_is_alloc(mt))
- return -EINVAL;
-
- if (WARN_ON_ONCE(mt_is_reserved(entry)))
- return -EINVAL;
-
- if (min > max)
- return -EINVAL;
-
- if (max < size)
- return -EINVAL;
-
- if (!size)
- return -EINVAL;
-
- mtree_lock(mt);
-retry:
- mas.offset = 0;
- mas.index = min;
- mas.last = max - size + 1;
- ret = mas_alloc(&mas, entry, size, startp);
- if (mas_nomem(&mas, gfp))
- goto retry;
-
- mtree_unlock(mt);
- return ret;
-}
-EXPORT_SYMBOL(mtree_alloc_range);
-
-int mtree_alloc_rrange(struct maple_tree *mt, unsigned long *startp,
- void *entry, unsigned long size, unsigned long min,
- unsigned long max, gfp_t gfp)
-{
- int ret = 0;
-
- MA_STATE(mas, mt, min, max - size + 1);
- if (!mt_is_alloc(mt))
- return -EINVAL;
-
- if (WARN_ON_ONCE(mt_is_reserved(entry)))
- return -EINVAL;
-
- if (min > max)
- return -EINVAL;
-
- if (max < size - 1)
- return -EINVAL;
-
- if (!size)
- return -EINVAL;
-
- mtree_lock(mt);
-retry:
- ret = mas_rev_alloc(&mas, min, max, entry, size, startp);
- if (mas_nomem(&mas, gfp))
- goto retry;
-
- mtree_unlock(mt);
- return ret;
-}
-EXPORT_SYMBOL(mtree_alloc_rrange);
-
/**
* mtree_erase() - Find an index and erase the entire range.
* @mt: The maple tree
--
2.20.1



2023-05-15 17:34:37

by Liam R. Howlett

[permalink] [raw]
Subject: Re: [PATCH 02/10] maple_tree: Drop mtree_alloc_{range,rrange}() and related functions.

* Peng Zhang <[email protected]> [230515 09:18]:
> Drop mtree_alloc_{range,rrange}(), mas_{rev_}alloc() and mas_fill_gap().
> mtree_alloc_{range,rrange}() currently have no users and can be easily
> implemented with mas_empty_area{_rev}(). mas_{rev_}alloc() and
> mas_fill_gap() are just their internal functions, drop them together.
>
> Signed-off-by: Peng Zhang <[email protected]>

Reviewed-by: Liam R. Howlett <[email protected]>

> ---
> include/linux/maple_tree.h | 7 --
> lib/maple_tree.c | 177 -------------------------------------
> 2 files changed, 184 deletions(-)
>
> diff --git a/include/linux/maple_tree.h b/include/linux/maple_tree.h
> index 542b09118a09f..3dd6edccf83af 100644
> --- a/include/linux/maple_tree.h
> +++ b/include/linux/maple_tree.h
> @@ -306,13 +306,6 @@ int mtree_insert(struct maple_tree *mt, unsigned long index,
> void *entry, gfp_t gfp);
> int mtree_insert_range(struct maple_tree *mt, unsigned long first,
> unsigned long last, void *entry, gfp_t gfp);
> -int mtree_alloc_range(struct maple_tree *mt, unsigned long *startp,
> - void *entry, unsigned long size, unsigned long min,
> - unsigned long max, gfp_t gfp);
> -int mtree_alloc_rrange(struct maple_tree *mt, unsigned long *startp,
> - void *entry, unsigned long size, unsigned long min,
> - unsigned long max, gfp_t gfp);
> -
> int mtree_store_range(struct maple_tree *mt, unsigned long first,
> unsigned long last, void *entry, gfp_t gfp);
> int mtree_store(struct maple_tree *mt, unsigned long index,
> diff --git a/lib/maple_tree.c b/lib/maple_tree.c
> index b37065a6f570d..49dfe81dfa1b6 100644
> --- a/lib/maple_tree.c
> +++ b/lib/maple_tree.c
> @@ -5120,46 +5120,6 @@ static inline void mas_awalk(struct ma_state *mas, unsigned long size)
> }
> }
>
> -/*
> - * mas_fill_gap() - Fill a located gap with @entry.
> - * @mas: The maple state
> - * @entry: The value to store
> - * @slot: The offset into the node to store the @entry
> - * @size: The size of the entry
> - * @index: The start location
> - */
> -static inline void mas_fill_gap(struct ma_state *mas, void *entry,
> - unsigned char slot, unsigned long size, unsigned long *index)
> -{
> - MA_WR_STATE(wr_mas, mas, entry);
> - unsigned char pslot = mte_parent_slot(mas->node);
> - struct maple_enode *mn = mas->node;
> - unsigned long *pivots;
> - enum maple_type ptype;
> - /*
> - * mas->index is the start address for the search
> - * which may no longer be needed.
> - * mas->last is the end address for the search
> - */
> -
> - *index = mas->index;
> - mas->last = mas->index + size - 1;
> -
> - /*
> - * It is possible that using mas->max and mas->min to correctly
> - * calculate the index and last will cause an issue in the gap
> - * calculation, so fix the ma_state here
> - */
> - mas_ascend(mas);
> - ptype = mte_node_type(mas->node);
> - pivots = ma_pivots(mas_mn(mas), ptype);
> - mas->max = mas_safe_pivot(mas, pivots, pslot, ptype);
> - mas->min = mas_safe_min(mas, pivots, pslot);
> - mas->node = mn;
> - mas->offset = slot;
> - mas_wr_store_entry(&wr_mas);
> -}
> -
> /*
> * mas_sparse_area() - Internal function. Return upper or lower limit when
> * searching for a gap in an empty tree.
> @@ -5307,74 +5267,6 @@ int mas_empty_area_rev(struct ma_state *mas, unsigned long min,
> }
> EXPORT_SYMBOL_GPL(mas_empty_area_rev);
>
> -static inline int mas_alloc(struct ma_state *mas, void *entry,
> - unsigned long size, unsigned long *index)
> -{
> - unsigned long min;
> -
> - mas_start(mas);
> - if (mas_is_none(mas) || mas_is_ptr(mas)) {
> - mas_root_expand(mas, entry);
> - if (mas_is_err(mas))
> - return xa_err(mas->node);
> -
> - if (!mas->index)
> - return mas_pivot(mas, 0);
> - return mas_pivot(mas, 1);
> - }
> -
> - /* Must be walking a tree. */
> - mas_awalk(mas, size);
> - if (mas_is_err(mas))
> - return xa_err(mas->node);
> -
> - if (mas->offset == MAPLE_NODE_SLOTS)
> - goto no_gap;
> -
> - /*
> - * At this point, mas->node points to the right node and we have an
> - * offset that has a sufficient gap.
> - */
> - min = mas->min;
> - if (mas->offset)
> - min = mas_pivot(mas, mas->offset - 1) + 1;
> -
> - if (mas_is_err(mas))
> - return xa_err(mas->node);
> -
> - if (mas->index < min)
> - mas->index = min;
> -
> - mas_fill_gap(mas, entry, mas->offset, size, index);
> - return 0;
> -
> -no_gap:
> - return -EBUSY;
> -}
> -
> -static inline int mas_rev_alloc(struct ma_state *mas, unsigned long min,
> - unsigned long max, void *entry,
> - unsigned long size, unsigned long *index)
> -{
> - int ret = 0;
> -
> - ret = mas_empty_area_rev(mas, min, max, size);
> - if (ret)
> - return ret;
> -
> - if (mas_is_err(mas))
> - return xa_err(mas->node);
> -
> - if (mas->offset == MAPLE_NODE_SLOTS)
> - goto no_gap;
> -
> - mas_fill_gap(mas, entry, mas->offset, size, index);
> - return 0;
> -
> -no_gap:
> - return -EBUSY;
> -}
> -
> /*
> * mte_dead_leaves() - Mark all leaves of a node as dead.
> * @mas: The maple state
> @@ -6481,75 +6373,6 @@ int mtree_insert(struct maple_tree *mt, unsigned long index, void *entry,
> }
> EXPORT_SYMBOL(mtree_insert);
>
> -int mtree_alloc_range(struct maple_tree *mt, unsigned long *startp,
> - void *entry, unsigned long size, unsigned long min,
> - unsigned long max, gfp_t gfp)
> -{
> - int ret = 0;
> -
> - MA_STATE(mas, mt, min, min);
> - if (!mt_is_alloc(mt))
> - return -EINVAL;
> -
> - if (WARN_ON_ONCE(mt_is_reserved(entry)))
> - return -EINVAL;
> -
> - if (min > max)
> - return -EINVAL;
> -
> - if (max < size)
> - return -EINVAL;
> -
> - if (!size)
> - return -EINVAL;
> -
> - mtree_lock(mt);
> -retry:
> - mas.offset = 0;
> - mas.index = min;
> - mas.last = max - size + 1;
> - ret = mas_alloc(&mas, entry, size, startp);
> - if (mas_nomem(&mas, gfp))
> - goto retry;
> -
> - mtree_unlock(mt);
> - return ret;
> -}
> -EXPORT_SYMBOL(mtree_alloc_range);
> -
> -int mtree_alloc_rrange(struct maple_tree *mt, unsigned long *startp,
> - void *entry, unsigned long size, unsigned long min,
> - unsigned long max, gfp_t gfp)
> -{
> - int ret = 0;
> -
> - MA_STATE(mas, mt, min, max - size + 1);
> - if (!mt_is_alloc(mt))
> - return -EINVAL;
> -
> - if (WARN_ON_ONCE(mt_is_reserved(entry)))
> - return -EINVAL;
> -
> - if (min > max)
> - return -EINVAL;
> -
> - if (max < size - 1)
> - return -EINVAL;
> -
> - if (!size)
> - return -EINVAL;
> -
> - mtree_lock(mt);
> -retry:
> - ret = mas_rev_alloc(&mas, min, max, entry, size, startp);
> - if (mas_nomem(&mas, gfp))
> - goto retry;
> -
> - mtree_unlock(mt);
> - return ret;
> -}
> -EXPORT_SYMBOL(mtree_alloc_rrange);
> -
> /**
> * mtree_erase() - Find an index and erase the entire range.
> * @mt: The maple tree
> --
> 2.20.1
>

2023-05-15 17:36:15

by Matthew Wilcox

[permalink] [raw]
Subject: Re: [PATCH 02/10] maple_tree: Drop mtree_alloc_{range,rrange}() and related functions.

On Mon, May 15, 2023 at 09:17:49PM +0800, Peng Zhang wrote:
> Drop mtree_alloc_{range,rrange}(), mas_{rev_}alloc() and mas_fill_gap().
> mtree_alloc_{range,rrange}() currently have no users and can be easily
> implemented with mas_empty_area{_rev}(). mas_{rev_}alloc() and
> mas_fill_gap() are just their internal functions, drop them together.

No, I think this is the wrong way to go.

Most users should not be using the mas_* API. These are the advanced
APIs. Most users will want to use mtree_alloc_range(). Just like most
users of the XArray use the xa_insert() API rather than open-coding the
xa_state and calling the xas_* APIs.

Please read Documentation/core-api/xarray.rst and maple_tree.rst for more
details on Normal vs Advanced API. The real problem is that we have so
few users today, so you haven't seen that most people don't want to use
the advanced APIs.

2023-05-15 18:02:30

by Liam R. Howlett

[permalink] [raw]
Subject: Re: [PATCH 02/10] maple_tree: Drop mtree_alloc_{range,rrange}() and related functions.

* Matthew Wilcox <[email protected]> [230515 13:27]:
> On Mon, May 15, 2023 at 09:17:49PM +0800, Peng Zhang wrote:
> > Drop mtree_alloc_{range,rrange}(), mas_{rev_}alloc() and mas_fill_gap().
> > mtree_alloc_{range,rrange}() currently have no users and can be easily
> > implemented with mas_empty_area{_rev}(). mas_{rev_}alloc() and
> > mas_fill_gap() are just their internal functions, drop them together.
>
> No, I think this is the wrong way to go.
>
> Most users should not be using the mas_* API. These are the advanced
> APIs. Most users will want to use mtree_alloc_range(). Just like most
> users of the XArray use the xa_insert() API rather than open-coding the
> xa_state and calling the xas_* APIs.
>
> Please read Documentation/core-api/xarray.rst and maple_tree.rst for more
> details on Normal vs Advanced API. The real problem is that we have so
> few users today, so you haven't seen that most people don't want to use
> the advanced APIs.


Peng, Apologies on the confusion. Please do as Matthew said. If you
have a way to unify the functionality to use the same internal
functions, then I think that would be a welcome change.

2023-05-16 00:44:10

by Peng Zhang

[permalink] [raw]
Subject: Re: [PATCH 02/10] maple_tree: Drop mtree_alloc_{range,rrange}() and related functions.



在 2023/5/16 01:35, Liam R. Howlett 写道:
> * Matthew Wilcox <[email protected]> [230515 13:27]:
>> On Mon, May 15, 2023 at 09:17:49PM +0800, Peng Zhang wrote:
>>> Drop mtree_alloc_{range,rrange}(), mas_{rev_}alloc() and mas_fill_gap().
>>> mtree_alloc_{range,rrange}() currently have no users and can be easily
>>> implemented with mas_empty_area{_rev}(). mas_{rev_}alloc() and
>>> mas_fill_gap() are just their internal functions, drop them together.
>>
>> No, I think this is the wrong way to go.
>>
>> Most users should not be using the mas_* API. These are the advanced
>> APIs. Most users will want to use mtree_alloc_range(). Just like most
>> users of the XArray use the xa_insert() API rather than open-coding the
>> xa_state and calling the xas_* APIs.
>>
>> Please read Documentation/core-api/xarray.rst and maple_tree.rst for more
>> details on Normal vs Advanced API. The real problem is that we have so
>> few users today, so you haven't seen that most people don't want to use
>> the advanced APIs.
>
>
> Peng, Apologies on the confusion. Please do as Matthew said. If you
> have a way to unify the functionality to use the same internal
> functions, then I think that would be a welcome change.
>
I will implement new mtree_alloc_{range,rrange}() using other internal
functions.