From: "Liam R. Howlett" <Liam.Howlett@Oracle.com>
To: Peng Zhang <perlyzhang@gmail.com>
Cc: linux-kernel@vger.kernel.org, linux-mm@kvack.org,
maple-tree@lists.infradead.org,
Andrew Morton <akpm@linux-foundation.org>
Subject: Re: [PATCH 27/34] maple_tree: Introduce mas_next_slot() interface
Date: Wed, 3 May 2023 15:31:26 -0400 [thread overview]
Message-ID: <20230503193126.2jejttv7kwtjznh3@revolver> (raw)
In-Reply-To: <cfa05198-9ab0-3529-bc1f-08d8035a435c@gmail.com>
* Peng Zhang <perlyzhang@gmail.com> [230428 02:48]:
>
>
> 在 2023/4/25 22:09, Liam R. Howlett 写道:
> > Sometimes, during a tree walk, the user needs the next slot regardless
> > of if it is empty or not. Add an interface to get the next slot.
> >
> > Since there are no consecutive NULLs allowed in the tree, the mas_next()
> > function can only advance two slots at most. So use the new
> > mas_next_slot() interface to align both implementations.
> >
> > Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
> > ---
> > lib/maple_tree.c | 178 +++++++++++++++++++----------------------------
> > 1 file changed, 71 insertions(+), 107 deletions(-)
> >
> > diff --git a/lib/maple_tree.c b/lib/maple_tree.c
> > index 31cbfd7b44728..fe6c9da6f2bd5 100644
> > --- a/lib/maple_tree.c
> > +++ b/lib/maple_tree.c
> > @@ -4619,15 +4619,16 @@ static inline int mas_next_node(struct ma_state *mas, struct maple_node *node,
> > if (mas->max >= max)
> > goto no_entry;
> > + min = mas->max + 1;
> > + if (min > max)
> > + goto no_entry;
> Unnecessary check due to mas->max < max.
Thanks, I will address this in v2.
> > +
> > level = 0;
> > do {
> > if (ma_is_root(node))
> > goto no_entry;
> > - min = mas->max + 1;
> > - if (min > max)
> > - goto no_entry;
> > -
> > + /* Walk up. */
> > if (unlikely(mas_ascend(mas)))
> > return 1;
> > @@ -4645,13 +4646,12 @@ static inline int mas_next_node(struct ma_state *mas, struct maple_node *node,
> > slots = ma_slots(node, mt);
> > pivot = mas_safe_pivot(mas, pivots, ++offset, mt);
> > while (unlikely(level > 1)) {
> > - /* Descend, if necessary */
> > + level--;
> > enode = mas_slot(mas, slots, offset);
> > if (unlikely(ma_dead_node(node)))
> > return 1;
> > mas->node = enode;
> > - level--;
> > node = mas_mn(mas);
> > mt = mte_node_type(mas->node);
> > slots = ma_slots(node, mt);
> > @@ -4680,85 +4680,84 @@ 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_nentry() - Get the next node entry
> > - * @mas: The maple state
> > - * @max: The maximum value to check
> > - * @*range_start: Pointer to store the start of the range.
> > + * mas_next_slot() - Get the entry in the next slot
> > *
> > - * Sets @mas->offset to the offset of the next node entry, @mas->last to the
> > - * pivot of the entry.
> > + * @mas: The maple state
> > + * @max: The maximum starting range
> > *
> > - * Return: The next entry, %NULL otherwise
> > + * Return: The entry in the next slot which is possibly NULL
> > */
> > -static inline void *mas_next_nentry(struct ma_state *mas,
> > - struct maple_node *node, unsigned long max, enum maple_type type)
> > +void *mas_next_slot(struct ma_state *mas, unsigned long max)
> > {
> > - unsigned char count;
> > - unsigned long pivot;
> > - unsigned long *pivots;
> > void __rcu **slots;
> > + unsigned long *pivots;
> > + unsigned long pivot;
> > + enum maple_type type;
> > + struct maple_node *node;
> > + unsigned char data_end;
> > + unsigned long save_point = mas->last;
> > void *entry;
> > - if (mas->last == mas->max) {
> > - mas->index = mas->max;
> > - return NULL;
> > - }
> > -
> > - slots = ma_slots(node, type);
> > +retry:
> > + node = mas_mn(mas);
> > + type = mte_node_type(mas->node);
> > pivots = ma_pivots(node, type);
> > - count = ma_data_end(node, type, pivots, mas->max);
> > - if (unlikely(ma_dead_node(node)))
> > - return NULL;
> > -
> > - mas->index = mas_safe_min(mas, pivots, mas->offset);
> > - if (unlikely(ma_dead_node(node)))
> > - return NULL;
> > -
> > - if (mas->index > max)
> > - return NULL;
> > + data_end = ma_data_end(node, type, pivots, mas->max);
> > + pivot = mas_logical_pivot(mas, pivots, mas->offset, type);
> > + if (unlikely(mas_rewalk_if_dead(mas, node, save_point)))
> > + goto retry;
> > - if (mas->offset > count)
> > + if (pivot >= max)
> > return NULL;
> > - while (mas->offset < count) {
> > - pivot = pivots[mas->offset];
> > - entry = mas_slot(mas, slots, mas->offset);
> > - if (ma_dead_node(node))
> > - return NULL;
> > -
> > - mas->last = pivot;
> > - if (entry)
> > - return entry;
> > -
> > - if (pivot >= max)
> > - return NULL;
> > + if (likely(data_end > mas->offset)) {
> > + mas->offset++;
> > + mas->index = mas->last + 1;
> > + } else {
> > + if (mas_next_node(mas, node, max)) {
> > + mas_rewalk(mas, save_point);
> > + goto retry;
> > + }
> > - if (pivot >= mas->max)
> > + if (mas_is_none(mas))
> > return NULL;
> > - mas->index = pivot + 1;
> > - mas->offset++;
> > + mas->offset = 0;
> > + mas->index = mas->min;
> > + node = mas_mn(mas);
> > + type = mte_node_type(mas->node);
> > + pivots = ma_pivots(node, type);
> > }
> > - pivot = mas_logical_pivot(mas, pivots, mas->offset, type);
> > + slots = ma_slots(node, type);
> > + mas->last = mas_logical_pivot(mas, pivots, mas->offset, type);
> > entry = mas_slot(mas, slots, mas->offset);
> > - if (ma_dead_node(node))
> > - return NULL;
> > + if (unlikely(mas_rewalk_if_dead(mas, node, save_point)))
> > + goto retry;
> > - mas->last = pivot;
> > return 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;
> > -}
> > -
> > /*
> > * mas_next_entry() - Internal function to get the next entry.
> > * @mas: The maple state
> > @@ -4774,47 +4773,18 @@ static inline void mas_rewalk(struct ma_state *mas, unsigned long index)
> > static inline void *mas_next_entry(struct ma_state *mas, unsigned long limit)
> > {
> > void *entry = NULL;
> > - struct maple_node *node;
> > - unsigned long last;
> > - enum maple_type mt;
> > if (mas->last >= limit)
> > return NULL;
> > - last = mas->last;
> > -retry:
> > - node = mas_mn(mas);
> > - mt = mte_node_type(mas->node);
> > - mas->offset++;
> > - if (unlikely(mas->offset >= mt_slots[mt])) {
> > - mas->offset = mt_slots[mt] - 1;
> > - goto next_node;
> > - }
> > -
> > - while (!mas_is_none(mas)) {
> > - entry = mas_next_nentry(mas, node, limit, mt);
> > - if (unlikely(ma_dead_node(node))) {
> > - mas_rewalk(mas, last);
> > - goto retry;
> > - }
> > -
> > - if (likely(entry))
> > - return entry;
> > -
> > - if (unlikely((mas->last >= limit)))
> > - return NULL;
> > + entry = mas_next_slot_limit(mas, limit);
> > + if (entry)
> > + return entry;
> > -next_node:
> > - if (unlikely(mas_next_node(mas, node, limit))) {
> > - mas_rewalk(mas, last);
> > - goto retry;
> > - }
> > - mas->offset = 0;
> > - node = mas_mn(mas);
> > - mt = mte_node_type(mas->node);
> > - }
> > + if (mas_is_none(mas))
> > + return NULL;
> > - return NULL;
> > + return mas_next_slot_limit(mas, limit);
> > }
> > /*
> > @@ -4845,10 +4815,8 @@ static inline void *mas_prev_nentry(struct ma_state *mas, unsigned long limit,
> > slots = ma_slots(mn, mt);
> > pivots = ma_pivots(mn, mt);
> > count = ma_data_end(mn, mt, pivots, mas->max);
> > - if (unlikely(ma_dead_node(mn))) {
> > - mas_rewalk(mas, index);
> > + if (unlikely(mas_rewalk_if_dead(mas, mn, index)))
> > goto retry;
> > - }
> > offset = mas->offset - 1;
> > if (offset >= mt_slots[mt])
> > @@ -4861,10 +4829,8 @@ static inline void *mas_prev_nentry(struct ma_state *mas, unsigned long limit,
> > pivot = pivots[offset];
> > }
> > - if (unlikely(ma_dead_node(mn))) {
> > - mas_rewalk(mas, index);
> > + if (unlikely(mas_rewalk_if_dead(mas, mn, index)))
> > goto retry;
> > - }
> > while (offset && !mas_slot(mas, slots, offset)) {
> > pivot = pivots[--offset];
> > @@ -4881,10 +4847,8 @@ static inline void *mas_prev_nentry(struct ma_state *mas, unsigned long limit,
> > min = mas_safe_min(mas, pivots, offset);
> > entry = mas_slot(mas, slots, offset);
> > - if (unlikely(ma_dead_node(mn))) {
> > - mas_rewalk(mas, index);
> > + if (unlikely(mas_rewalk_if_dead(mas, mn, index)))
> > goto retry;
> > - }
> > mas->offset = offset;
> > mas->last = pivot;
next prev parent reply other threads:[~2023-05-03 19:31 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 [this message]
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
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=20230503193126.2jejttv7kwtjznh3@revolver \
--to=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 \
--cc=perlyzhang@gmail.com \
/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