From: Peng Zhang <perlyzhang@gmail.com>
To: "Liam R. Howlett" <Liam.Howlett@oracle.com>,
Andrew Morton <akpm@linux-foundation.org>
Cc: linux-kernel@vger.kernel.org, linux-mm@kvack.org,
maple-tree@lists.infradead.org
Subject: Re: [PATCH 29/34] maple_tree: Introduce mas_prev_slot() interface
Date: Fri, 28 Apr 2023 16:27:43 +0800 [thread overview]
Message-ID: <e91f609b-bee7-bc6a-cc01-e2d69fdd68c3@gmail.com> (raw)
In-Reply-To: <20230425140955.3834476-30-Liam.Howlett@oracle.com>
在 2023/4/25 22:09, Liam R. Howlett 写道:
> Sometimes the user needs to revert to the previous slot, regardless of
> if it is empty or not. Add an interface to go to the previous slot.
>
> Since there can't be two consecutive NULLs in the tree, the mas_prev()
> function can be implemented by calling mas_prev_slot() a maximum of 2
> times. Change the underlying interface to use mas_prev_slot() to align
> the code.
>
> Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
> ---
> lib/maple_tree.c | 217 ++++++++++++++++++++---------------------------
> 1 file changed, 90 insertions(+), 127 deletions(-)
>
> diff --git a/lib/maple_tree.c b/lib/maple_tree.c
> index 7370d7c12fe3b..297d936321347 100644
> --- a/lib/maple_tree.c
> +++ b/lib/maple_tree.c
> @@ -4498,6 +4498,25 @@ static inline void *mas_insert(struct ma_state *mas, void *entry)
>
> }
>
> +static inline void mas_rewalk(struct ma_state *mas, unsigned long index)
> +{
> +retry:
> + mas_set(mas, index);
> + mas_state_walk(mas);
> + if (mas_is_start(mas))
> + goto retry;
> +}
> +
> +static inline bool mas_rewalk_if_dead(struct ma_state *mas,
> + struct maple_node *node, const unsigned long index)
> +{
> + if (unlikely(ma_dead_node(node))) {
> + mas_rewalk(mas, index);
> + return true;
> + }
> + return false;
> +}
> +
> /*
> * mas_prev_node() - Find the prev non-null entry at the same level in the
> * tree. The prev value will be mas->node[mas->offset] or MAS_NONE.
> @@ -4515,13 +4534,15 @@ static inline int mas_prev_node(struct ma_state *mas, unsigned long min)
> struct maple_node *node;
> struct maple_enode *enode;
> unsigned long *pivots;
> + unsigned long max;
>
> - if (mas_is_none(mas))
> - return 0;
> + node = mas_mn(mas);
> + max = mas->min - 1;
May underflow.
> + if (max < min)
> + goto no_entry;
>
> level = 0;
> do {
> - node = mas_mn(mas);
> if (ma_is_root(node))
> goto no_entry;
>
> @@ -4530,11 +4551,11 @@ static inline int mas_prev_node(struct ma_state *mas, unsigned long min)
> return 1;
> offset = mas->offset;
> level++;
> + node = mas_mn(mas);
> } while (!offset);
>
> offset--;
> mt = mte_node_type(mas->node);
> - node = mas_mn(mas);
> slots = ma_slots(node, mt);
> pivots = ma_pivots(node, mt);
> if (unlikely(ma_dead_node(node)))
> @@ -4543,12 +4564,10 @@ static inline int mas_prev_node(struct ma_state *mas, unsigned long min)
> mas->max = pivots[offset];
> if (offset)
> mas->min = pivots[offset - 1] + 1;
> +
> if (unlikely(ma_dead_node(node)))
> return 1;
>
> - if (mas->max < min)
> - goto no_entry_min;
> -
> while (level > 1) {
> level--;
> enode = mas_slot(mas, slots, offset);
> @@ -4569,9 +4588,6 @@ static inline int mas_prev_node(struct ma_state *mas, unsigned long min)
>
> if (offset < mt_pivots[mt])
> mas->max = pivots[offset];
> -
> - if (mas->max < min)
> - goto no_entry;
> }
>
> mas->node = mas_slot(mas, slots, offset);
> @@ -4584,10 +4600,6 @@ static inline int mas_prev_node(struct ma_state *mas, unsigned long min)
>
> return 0;
>
> -no_entry_min:
> - mas->offset = offset;
> - if (offset)
> - mas->min = pivots[offset - 1] + 1;
> no_entry:
> if (unlikely(ma_dead_node(node)))
> return 1;
> @@ -4596,6 +4608,62 @@ static inline int mas_prev_node(struct ma_state *mas, unsigned long min)
> return 0;
> }
>
> +/*
> + * mas_prev_slot() - Get the entry in the previous slot
> + *
> + * @mas: The maple state
> + * @max: The minimum starting range
> + *
> + * Return: The entry in the previous slot which is possibly NULL
> + */
> +void *mas_prev_slot(struct ma_state *mas, unsigned long min)
> +{
> + void *entry;
> + void __rcu **slots;
> + unsigned long pivot;
> + enum maple_type type;
> + unsigned long *pivots;
> + struct maple_node *node;
> + unsigned long save_point = mas->index;
> +
> +retry:
> + node = mas_mn(mas);
> + type = mte_node_type(mas->node);
> + pivots = ma_pivots(node, type);
> + pivot = mas_safe_min(mas, pivots, mas->offset);
> + if (unlikely(mas_rewalk_if_dead(mas, node, save_point)))
> + goto retry;
> +
> + if (pivot <= min)
> + return NULL;
> +
> + if (likely(mas->offset)) {
> + mas->offset--;
> + mas->last = mas->index - 1;
> + } else {
> + if (mas_prev_node(mas, min)) {
> + mas_rewalk(mas, save_point);
> + goto retry;
> + }
> +
> + if (mas_is_none(mas))
> + return NULL;
> +
> + mas->last = mas->max;
> + node = mas_mn(mas);
> + type = mte_node_type(mas->node);
> + pivots = ma_pivots(node, type);
> + }
> +
> + mas->index = mas_safe_min(mas, pivots, mas->offset);
> + slots = ma_slots(node, type);
> + entry = mas_slot(mas, slots, mas->offset);
> + if (unlikely(mas_rewalk_if_dead(mas, node, save_point)))
> + goto retry;
> +
> + return entry;
> +}
> +
> /*
> * mas_next_node() - Get the next node at the same level in the tree.
> * @mas: The maple state
> @@ -4680,25 +4748,6 @@ static inline int mas_next_node(struct ma_state *mas, struct maple_node *node,
> return 0;
> }
>
> -static inline void mas_rewalk(struct ma_state *mas, unsigned long index)
> -{
> -retry:
> - mas_set(mas, index);
> - mas_state_walk(mas);
> - if (mas_is_start(mas))
> - goto retry;
> -}
> -
> -static inline bool mas_rewalk_if_dead(struct ma_state *mas,
> - struct maple_node *node, const unsigned long index)
> -{
> - if (unlikely(ma_dead_node(node))) {
> - mas_rewalk(mas, index);
> - return true;
> - }
> - return false;
> -}
> -
> /*
> * mas_next_slot() - Get the entry in the next slot
> *
> @@ -4777,117 +4826,31 @@ static inline void *mas_next_entry(struct ma_state *mas, unsigned long limit)
> if (mas->last >= limit)
> return NULL;
>
> - entry = mas_next_slot_limit(mas, limit);
> + entry = mas_next_slot(mas, limit);
> if (entry)
> return entry;
>
> if (mas_is_none(mas))
> return NULL;
>
> - return mas_next_slot_limit(mas, limit);
> -}
> -
> -/*
> - * mas_prev_nentry() - Get the previous node entry.
> - * @mas: The maple state.
> - * @limit: The lower limit to check for a value.
> - *
> - * Return: the entry, %NULL otherwise.
> - */
> -static inline void *mas_prev_nentry(struct ma_state *mas, unsigned long limit,
> - unsigned long index)
> -{
> - unsigned long pivot, min;
> - unsigned char offset, count;
> - struct maple_node *mn;
> - enum maple_type mt;
> - unsigned long *pivots;
> - void __rcu **slots;
> - void *entry;
> -
> -retry:
> - if (!mas->offset)
> - return NULL;
> -
> - mn = mas_mn(mas);
> - mt = mte_node_type(mas->node);
> - offset = mas->offset - 1;
> - slots = ma_slots(mn, mt);
> - pivots = ma_pivots(mn, mt);
> - count = ma_data_end(mn, mt, pivots, mas->max);
> - if (unlikely(mas_rewalk_if_dead(mas, mn, index)))
> - goto retry;
> -
> - offset = mas->offset - 1;
> - if (offset >= mt_slots[mt])
> - offset = mt_slots[mt] - 1;
> -
> - if (offset >= count) {
> - pivot = mas->max;
> - offset = count;
> - } else {
> - pivot = pivots[offset];
> - }
> -
> - if (unlikely(mas_rewalk_if_dead(mas, mn, index)))
> - goto retry;
> -
> - while (offset && !mas_slot(mas, slots, offset)) {
> - pivot = pivots[--offset];
> - if (pivot >= limit)
> - break;
> - }
> -
> - /*
> - * If the slot was null but we've shifted outside the limits, then set
> - * the range to the last NULL.
> - */
> - if (unlikely((pivot < limit) && (offset < mas->offset)))
> - pivot = pivots[++offset];
> -
> - min = mas_safe_min(mas, pivots, offset);
> - entry = mas_slot(mas, slots, offset);
> - if (unlikely(mas_rewalk_if_dead(mas, mn, index)))
> - goto retry;
> -
> - mas->offset = offset;
> - mas->last = pivot;
> - mas->index = min;
> - return entry;
> + return mas_next_slot(mas, limit);
> }
>
> static inline void *mas_prev_entry(struct ma_state *mas, unsigned long min)
> {
> void *entry;
> - struct maple_enode *prev_enode;
> - unsigned char prev_offset;
>
> if (mas->index < min)
> return NULL;
>
> -retry:
> - prev_enode = mas->node;
> - prev_offset = mas->offset;
> - while (likely(!mas_is_none(mas))) {
> - entry = mas_prev_nentry(mas, min, mas->index);
> -
> - if (likely(entry))
> - return entry;
> -
> - if (unlikely(mas->index <= min))
> - return NULL;
> -
> - if (unlikely(mas_prev_node(mas, min))) {
> - mas_rewalk(mas, mas->index);
> - goto retry;
> - }
> + entry = mas_prev_slot(mas, min);
> + if (entry)
> + return entry;
>
> - mas->offset++;
> - }
> + if (mas_is_none(mas))
> + return NULL;
>
> - mas->node = prev_enode;
> - mas->offset = prev_offset;
> - return NULL;
> + return mas_prev_slot(mas, min);
> }
>
> /*
next prev parent reply other threads:[~2023-04-28 8:27 UTC|newest]
Thread overview: 65+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-04-25 14:09 [PATCH 00/34] Maple tree mas_{next,prev}_range() and cleanup Liam R. Howlett
2023-04-25 14:09 ` [PATCH 01/34] maple_tree: Fix static analyser cppcheck issue Liam R. Howlett
2023-04-26 4:06 ` Peng Zhang
2023-04-25 14:09 ` [PATCH 02/34] maple_tree: Clean up mas_parent_enum() Liam R. Howlett
2023-04-25 16:13 ` Wei Yang
2023-04-26 4:14 ` Peng Zhang
2023-04-26 21:07 ` Liam R. Howlett
2023-04-25 14:09 ` [PATCH 03/34] maple_tree: Avoid unnecessary ascending Liam R. Howlett
2023-04-26 5:27 ` Peng Zhang
2023-04-25 14:09 ` [PATCH 04/34] maple_tree: Clean up mas_dfs_postorder() Liam R. Howlett
2023-04-25 14:09 ` [PATCH 05/34] maple_tree: Add format option to mt_dump() Liam R. Howlett
2023-04-25 14:09 ` [PATCH 06/34] maple_tree: Add debug BUG_ON and WARN_ON variants Liam R. Howlett
2023-04-25 14:09 ` [PATCH 07/34] maple_tree: Convert BUG_ON() to MT_BUG_ON() Liam R. Howlett
2023-04-25 14:09 ` [PATCH 08/34] maple_tree: Change RCU checks to WARN_ON() instead of BUG_ON() Liam R. Howlett
2023-04-25 14:09 ` [PATCH 09/34] maple_tree: Convert debug code to use MT_WARN_ON() and MAS_WARN_ON() Liam R. Howlett
2023-04-25 14:09 ` [PATCH 10/34] maple_tree: Use MAS_BUG_ON() when setting a leaf node as a parent Liam R. Howlett
2023-04-28 10:08 ` Petr Tesařík
2023-05-03 19:31 ` Liam R. Howlett
2023-04-25 14:09 ` [PATCH 11/34] maple_tree: Use MAS_BUG_ON() in mas_set_height() Liam R. Howlett
2023-04-28 10:10 ` Petr Tesařík
2023-05-03 19:33 ` Liam R. Howlett
2023-04-25 14:09 ` [PATCH 12/34] maple_tree: Use MAS_BUG_ON() from mas_topiary_range() Liam R. Howlett
2023-04-25 14:09 ` [PATCH 13/34] maple_tree: Use MAS_WR_BUG_ON() in mas_store_prealloc() Liam R. Howlett
2023-04-25 14:09 ` [PATCH 14/34] maple_tree: Use MAS_BUG_ON() prior to calling mas_meta_gap() Liam R. Howlett
2023-04-25 14:09 ` [PATCH 15/34] maple_tree: Return error on mte_pivots() out of range Liam R. Howlett
2023-04-26 9:55 ` Peng Zhang
2023-04-25 14:09 ` [PATCH 16/34] maple_tree: Make test code work without debug enabled Liam R. Howlett
2023-04-26 3:23 ` kernel test robot
2023-04-25 14:09 ` [PATCH 17/34] mm: Update validate_mm() to use vma iterator Liam R. Howlett
2023-04-25 14:09 ` [PATCH 18/34] mm: Update vma_iter_store() to use MAS_WARN_ON() Liam R. Howlett
2023-04-27 1:07 ` Sergey Senozhatsky
2023-04-27 1:17 ` Liam R. Howlett
2023-04-25 14:09 ` [PATCH 19/34] maple_tree: Add __init and __exit to test module Liam R. Howlett
2023-04-25 14:09 ` [PATCH 20/34] maple_tree: Remove unnecessary check from mas_destroy() Liam R. Howlett
2023-04-26 9:59 ` Peng Zhang
2023-04-25 14:09 ` [PATCH 21/34] maple_tree: mas_start() reset depth on dead node Liam R. Howlett
2023-04-28 2:45 ` Peng Zhang
2023-04-25 14:09 ` [PATCH 22/34] mm/mmap: Change do_vmi_align_munmap() for maple tree iterator changes Liam R. Howlett
2023-04-25 14:09 ` [PATCH 23/34] maple_tree: Try harder to keep active node after mas_next() Liam R. Howlett
2023-05-04 2:44 ` kernel test robot
2023-04-25 14:09 ` [PATCH 24/34] maple_tree: Try harder to keep active node with mas_prev() Liam R. Howlett
2023-04-25 14:09 ` [PATCH 25/34] maple_tree: Clear up index and last setting in single entry tree Liam R. Howlett
2023-04-27 11:19 ` Peng Zhang
2023-04-27 17:25 ` Liam R. Howlett
2023-04-25 14:09 ` [PATCH 26/34] maple_tree: Update testing code for mas_{next,prev,walk} Liam R. Howlett
2023-05-04 3:33 ` Peng Zhang
2023-05-04 18:50 ` Liam R. Howlett
2023-04-25 14:09 ` [PATCH 27/34] maple_tree: Introduce mas_next_slot() interface Liam R. Howlett
2023-04-26 1:21 ` kernel test robot
2023-04-26 13:16 ` kernel test robot
2023-04-28 6:48 ` Peng Zhang
2023-05-03 19:31 ` Liam R. Howlett
2023-04-28 8:39 ` kernel test robot
2023-04-25 14:09 ` [PATCH 28/34] maple_tree: Revise limit checks in mas_empty_area{_rev}() Liam R. Howlett
2023-04-28 7:06 ` Peng Zhang
2023-04-25 14:09 ` [PATCH 29/34] maple_tree: Introduce mas_prev_slot() interface Liam R. Howlett
2023-04-28 8:27 ` Peng Zhang [this message]
2023-05-03 19:29 ` Liam R. Howlett
2023-04-25 14:09 ` [PATCH 30/34] maple_tree: Fix comments for mas_next_entry() and mas_prev_entry() Liam R. Howlett
2023-04-25 14:09 ` [PATCH 31/34] maple_tree: Add mas_next_range() and mas_find_range() interfaces Liam R. Howlett
2023-04-25 14:09 ` [PATCH 32/34] maple_tree: Add mas_prev_range() and mas_find_range_rev interface Liam R. Howlett
2023-04-25 14:09 ` [PATCH 33/34] maple_tree: Add testing for mas_{prev,next}_range() Liam R. Howlett
2023-04-26 1:41 ` kernel test robot
2023-05-05 17:11 ` Liam R. Howlett
2023-04-25 14:09 ` [PATCH 34/34] mm: Add vma_iter_{next,prev}_range() to vma iterator Liam R. Howlett
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=e91f609b-bee7-bc6a-cc01-e2d69fdd68c3@gmail.com \
--to=perlyzhang@gmail.com \
--cc=Liam.Howlett@oracle.com \
--cc=akpm@linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=maple-tree@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox