@@ -4607,31 +4607,27 @@ static inline int mas_prev_node(struct ma_state *mas, unsigned long min)
46074607static inline int mas_next_node (struct ma_state * mas , struct maple_node * node ,
46084608 unsigned long max )
46094609{
4610- unsigned long min , pivot ;
4610+ unsigned long min ;
46114611 unsigned long * pivots ;
46124612 struct maple_enode * enode ;
46134613 int level = 0 ;
4614- unsigned char offset ;
46154614 unsigned char node_end ;
46164615 enum maple_type mt ;
46174616 void __rcu * * slots ;
46184617
46194618 if (mas -> max >= max )
46204619 goto no_entry ;
46214620
4621+ min = mas -> max + 1 ;
46224622 level = 0 ;
46234623 do {
46244624 if (ma_is_root (node ))
46254625 goto no_entry ;
46264626
4627- min = mas -> max + 1 ;
4628- if (min > max )
4629- goto no_entry ;
4630-
4627+ /* Walk up. */
46314628 if (unlikely (mas_ascend (mas )))
46324629 return 1 ;
46334630
4634- offset = mas -> offset ;
46354631 level ++ ;
46364632 node = mas_mn (mas );
46374633 mt = mte_node_type (mas -> node );
@@ -4640,36 +4636,37 @@ static inline int mas_next_node(struct ma_state *mas, struct maple_node *node,
46404636 if (unlikely (ma_dead_node (node )))
46414637 return 1 ;
46424638
4643- } while (unlikely (offset == node_end ));
4639+ } while (unlikely (mas -> offset == node_end ));
46444640
46454641 slots = ma_slots (node , mt );
4646- pivot = mas_safe_pivot (mas , pivots , ++ offset , mt );
4647- while (unlikely (level > 1 )) {
4648- /* Descend, if necessary */
4649- enode = mas_slot (mas , slots , offset );
4650- if (unlikely (ma_dead_node (node )))
4651- return 1 ;
4642+ mas -> offset ++ ;
4643+ enode = mas_slot (mas , slots , mas -> offset );
4644+ if (unlikely (ma_dead_node (node )))
4645+ return 1 ;
46524646
4653- mas -> node = enode ;
4647+ if (level > 1 )
4648+ mas -> offset = 0 ;
4649+
4650+ while (unlikely (level > 1 )) {
46544651 level -- ;
4652+ mas -> node = enode ;
46554653 node = mas_mn (mas );
46564654 mt = mte_node_type (mas -> node );
46574655 slots = ma_slots (node , mt );
4658- pivots = ma_pivots ( node , mt );
4656+ enode = mas_slot ( mas , slots , 0 );
46594657 if (unlikely (ma_dead_node (node )))
46604658 return 1 ;
4661-
4662- offset = 0 ;
4663- pivot = pivots [0 ];
46644659 }
46654660
4666- enode = mas_slot (mas , slots , offset );
4661+ if (!mas -> offset )
4662+ pivots = ma_pivots (node , mt );
4663+
4664+ mas -> max = mas_safe_pivot (mas , pivots , mas -> offset , mt );
46674665 if (unlikely (ma_dead_node (node )))
46684666 return 1 ;
46694667
46704668 mas -> node = enode ;
46714669 mas -> min = min ;
4672- mas -> max = pivot ;
46734670 return 0 ;
46744671
46754672no_entry :
@@ -4680,83 +4677,106 @@ static inline int mas_next_node(struct ma_state *mas, struct maple_node *node,
46804677 return 0 ;
46814678}
46824679
4680+ static inline void mas_rewalk (struct ma_state * mas , unsigned long index )
4681+ {
4682+ retry :
4683+ mas_set (mas , index );
4684+ mas_state_walk (mas );
4685+ if (mas_is_start (mas ))
4686+ goto retry ;
4687+ }
4688+
4689+ static inline bool mas_rewalk_if_dead (struct ma_state * mas ,
4690+ struct maple_node * node , const unsigned long index )
4691+ {
4692+ if (unlikely (ma_dead_node (node ))) {
4693+ mas_rewalk (mas , index );
4694+ return true;
4695+ }
4696+ return false;
4697+ }
4698+
46834699/*
4684- * mas_next_nentry() - Get the next node entry
4685- * @mas: The maple state
4686- * @max: The maximum value to check
4687- * @*range_start: Pointer to store the start of the range.
4700+ * mas_next_slot() - Get the entry in the next slot
46884701 *
4689- * Sets @mas->offset to the offset of the next node entry, @mas->last to the
4690- * pivot of the entry.
4702+ * @mas: The maple state
4703+ * @max: The maximum starting range
4704+ * @empty: Can be empty
46914705 *
4692- * Return: The next entry, %NULL otherwise
4706+ * Return: The entry in the next slot which is possibly NULL
46934707 */
4694- static inline void * mas_next_nentry (struct ma_state * mas ,
4695- struct maple_node * node , unsigned long max , enum maple_type type )
4708+ static void * mas_next_slot (struct ma_state * mas , unsigned long max , bool empty )
46964709{
4697- unsigned char count ;
4698- unsigned long pivot ;
4699- unsigned long * pivots ;
47004710 void __rcu * * slots ;
4711+ unsigned long * pivots ;
4712+ unsigned long pivot ;
4713+ enum maple_type type ;
4714+ struct maple_node * node ;
4715+ unsigned char data_end ;
4716+ unsigned long save_point = mas -> last ;
47014717 void * entry ;
47024718
4703- if (mas -> last == mas -> max ) {
4704- mas -> index = mas -> max ;
4705- return NULL ;
4706- }
4707-
4708- slots = ma_slots (node , type );
4719+ retry :
4720+ node = mas_mn (mas );
4721+ type = mte_node_type (mas -> node );
47094722 pivots = ma_pivots (node , type );
4710- count = ma_data_end (node , type , pivots , mas -> max );
4711- if (unlikely (ma_dead_node (node )))
4712- return NULL ;
4713-
4714- mas -> index = mas_safe_min (mas , pivots , mas -> offset );
4715- if (unlikely (ma_dead_node (node )))
4716- return NULL ;
4717-
4718- if (mas -> index > max )
4719- return NULL ;
4720-
4721- if (mas -> offset > count )
4722- return NULL ;
4723+ data_end = ma_data_end (node , type , pivots , mas -> max );
4724+ if (unlikely (mas_rewalk_if_dead (mas , node , save_point )))
4725+ goto retry ;
47234726
4724- while (mas -> offset < count ) {
4725- pivot = pivots [mas -> offset ];
4726- entry = mas_slot (mas , slots , mas -> offset );
4727- if (ma_dead_node (node ))
4728- return NULL ;
4727+ again :
4728+ if (mas -> max >= max ) {
4729+ if (likely (mas -> offset < data_end ))
4730+ pivot = pivots [mas -> offset ];
4731+ else
4732+ return NULL ; /* must be mas->max */
47294733
4730- mas -> last = pivot ;
4731- if (entry )
4732- return entry ;
4734+ if (unlikely (mas_rewalk_if_dead (mas , node , save_point )))
4735+ goto retry ;
47334736
47344737 if (pivot >= max )
47354738 return NULL ;
4739+ }
47364740
4737- if (pivot >= mas -> max )
4741+ if (likely (mas -> offset < data_end )) {
4742+ mas -> index = pivots [mas -> offset ] + 1 ;
4743+ mas -> offset ++ ;
4744+ if (likely (mas -> offset < data_end ))
4745+ mas -> last = pivots [mas -> offset ];
4746+ else
4747+ mas -> last = mas -> max ;
4748+ } else {
4749+ if (mas_next_node (mas , node , max )) {
4750+ mas_rewalk (mas , save_point );
4751+ goto retry ;
4752+ }
4753+
4754+ if (mas_is_none (mas ))
47384755 return NULL ;
47394756
4740- mas -> index = pivot + 1 ;
4741- mas -> offset ++ ;
4757+ mas -> offset = 0 ;
4758+ mas -> index = mas -> min ;
4759+ node = mas_mn (mas );
4760+ type = mte_node_type (mas -> node );
4761+ pivots = ma_pivots (node , type );
4762+ mas -> last = pivots [0 ];
47424763 }
47434764
4744- pivot = mas_logical_pivot ( mas , pivots , mas -> offset , type );
4745- entry = mas_slot (mas , slots , mas -> offset );
4746- if (ma_dead_node ( node ))
4747- return NULL ;
4765+ slots = ma_slots ( node , type );
4766+ entry = mt_slot (mas -> tree , slots , mas -> offset );
4767+ if (unlikely ( mas_rewalk_if_dead ( mas , node , save_point ) ))
4768+ goto retry ;
47484769
4749- mas -> last = pivot ;
4750- return entry ;
4751- }
4770+ if (entry )
4771+ return entry ;
47524772
4753- static inline void mas_rewalk ( struct ma_state * mas , unsigned long index )
4754- {
4755- retry :
4756- mas_set ( mas , index ) ;
4757- mas_state_walk ( mas );
4758- if ( mas_is_start ( mas ))
4759- goto retry ;
4773+ if (! empty ) {
4774+ if (! mas -> offset )
4775+ data_end = 2 ;
4776+ goto again ;
4777+ }
4778+
4779+ return entry ;
47604780}
47614781
47624782/*
@@ -4774,47 +4794,12 @@ static inline void mas_rewalk(struct ma_state *mas, unsigned long index)
47744794static inline void * mas_next_entry (struct ma_state * mas , unsigned long limit )
47754795{
47764796 void * entry = NULL ;
4777- struct maple_node * node ;
4778- unsigned long last ;
4779- enum maple_type mt ;
47804797
47814798 if (mas -> last >= limit )
47824799 return NULL ;
47834800
4784- last = mas -> last ;
4785- retry :
4786- node = mas_mn (mas );
4787- mt = mte_node_type (mas -> node );
4788- mas -> offset ++ ;
4789- if (unlikely (mas -> offset >= mt_slots [mt ])) {
4790- mas -> offset = mt_slots [mt ] - 1 ;
4791- goto next_node ;
4792- }
4793-
4794- while (!mas_is_none (mas )) {
4795- entry = mas_next_nentry (mas , node , limit , mt );
4796- if (unlikely (ma_dead_node (node ))) {
4797- mas_rewalk (mas , last );
4798- goto retry ;
4799- }
4800-
4801- if (likely (entry ))
4802- return entry ;
4803-
4804- if (unlikely ((mas -> last >= limit )))
4805- return NULL ;
4806-
4807- next_node :
4808- if (unlikely (mas_next_node (mas , node , limit ))) {
4809- mas_rewalk (mas , last );
4810- goto retry ;
4811- }
4812- mas -> offset = 0 ;
4813- node = mas_mn (mas );
4814- mt = mte_node_type (mas -> node );
4815- }
4816-
4817- return NULL ;
4801+ entry = mas_next_slot (mas , limit , false);
4802+ return entry ;
48184803}
48194804
48204805/*
@@ -4845,10 +4830,8 @@ static inline void *mas_prev_nentry(struct ma_state *mas, unsigned long limit,
48454830 slots = ma_slots (mn , mt );
48464831 pivots = ma_pivots (mn , mt );
48474832 count = ma_data_end (mn , mt , pivots , mas -> max );
4848- if (unlikely (ma_dead_node (mn ))) {
4849- mas_rewalk (mas , index );
4833+ if (unlikely (mas_rewalk_if_dead (mas , mn , index )))
48504834 goto retry ;
4851- }
48524835
48534836 offset = mas -> offset - 1 ;
48544837 if (offset >= mt_slots [mt ])
@@ -4861,10 +4844,8 @@ static inline void *mas_prev_nentry(struct ma_state *mas, unsigned long limit,
48614844 pivot = pivots [offset ];
48624845 }
48634846
4864- if (unlikely (ma_dead_node (mn ))) {
4865- mas_rewalk (mas , index );
4847+ if (unlikely (mas_rewalk_if_dead (mas , mn , index )))
48664848 goto retry ;
4867- }
48684849
48694850 while (offset && !mas_slot (mas , slots , offset )) {
48704851 pivot = pivots [-- offset ];
@@ -4881,10 +4862,8 @@ static inline void *mas_prev_nentry(struct ma_state *mas, unsigned long limit,
48814862
48824863 min = mas_safe_min (mas , pivots , offset );
48834864 entry = mas_slot (mas , slots , offset );
4884- if (unlikely (ma_dead_node (mn ))) {
4885- mas_rewalk (mas , index );
4865+ if (unlikely (mas_rewalk_if_dead (mas , mn , index )))
48864866 goto retry ;
4887- }
48884867
48894868 mas -> offset = offset ;
48904869 mas -> last = pivot ;
@@ -6103,8 +6082,8 @@ void *mas_find(struct ma_state *mas, unsigned long max)
61036082 if (mas -> index == max )
61046083 return NULL ;
61056084
6106- /* Retries on dead nodes handled by mas_next_entry */
6107- return mas_next_entry (mas , max );
6085+ /* Retries on dead nodes handled by mas_next_slot */
6086+ return mas_next_slot (mas , max , false );
61086087
61096088ptr_out_of_range :
61106089 mas -> node = MAS_NONE ;
0 commit comments