@@ -113,37 +113,38 @@ static unsigned long sz_range(struct damon_addr_range *r)
113
113
*
114
114
* Returns 0 if success, or negative error code otherwise.
115
115
*/
116
- static int __damon_va_three_regions (struct vm_area_struct * vma ,
116
+ static int __damon_va_three_regions (struct mm_struct * mm ,
117
117
struct damon_addr_range regions [3 ])
118
118
{
119
- struct damon_addr_range gap = {0 }, first_gap = {0 }, second_gap = {0 };
120
- struct vm_area_struct * last_vma = NULL ;
121
- unsigned long start = 0 ;
122
- struct rb_root rbroot ;
123
-
124
- /* Find two biggest gaps so that first_gap > second_gap > others */
125
- for (; vma ; vma = vma -> vm_next ) {
126
- if (!last_vma ) {
127
- start = vma -> vm_start ;
128
- goto next ;
129
- }
119
+ struct damon_addr_range first_gap = {0 }, second_gap = {0 };
120
+ VMA_ITERATOR (vmi , mm , 0 );
121
+ struct vm_area_struct * vma , * prev = NULL ;
122
+ unsigned long start ;
130
123
131
- if (vma -> rb_subtree_gap <= sz_range (& second_gap )) {
132
- rbroot .rb_node = & vma -> vm_rb ;
133
- vma = rb_entry (rb_last (& rbroot ),
134
- struct vm_area_struct , vm_rb );
124
+ /*
125
+ * Find the two biggest gaps so that first_gap > second_gap > others.
126
+ * If this is too slow, it can be optimised to examine the maple
127
+ * tree gaps.
128
+ */
129
+ for_each_vma (vmi , vma ) {
130
+ unsigned long gap ;
131
+
132
+ if (!prev ) {
133
+ start = vma -> vm_start ;
135
134
goto next ;
136
135
}
137
-
138
- gap .start = last_vma -> vm_end ;
139
- gap .end = vma -> vm_start ;
140
- if (sz_range (& gap ) > sz_range (& second_gap )) {
141
- swap (gap , second_gap );
142
- if (sz_range (& second_gap ) > sz_range (& first_gap ))
143
- swap (second_gap , first_gap );
136
+ gap = vma -> vm_start - prev -> vm_end ;
137
+
138
+ if (gap > sz_range (& first_gap )) {
139
+ second_gap = first_gap ;
140
+ first_gap .start = prev -> vm_end ;
141
+ first_gap .end = vma -> vm_start ;
142
+ } else if (gap > sz_range (& second_gap )) {
143
+ second_gap .start = prev -> vm_end ;
144
+ second_gap .end = vma -> vm_start ;
144
145
}
145
146
next :
146
- last_vma = vma ;
147
+ prev = vma ;
147
148
}
148
149
149
150
if (!sz_range (& second_gap ) || !sz_range (& first_gap ))
@@ -159,7 +160,7 @@ static int __damon_va_three_regions(struct vm_area_struct *vma,
159
160
regions [1 ].start = ALIGN (first_gap .end , DAMON_MIN_REGION );
160
161
regions [1 ].end = ALIGN (second_gap .start , DAMON_MIN_REGION );
161
162
regions [2 ].start = ALIGN (second_gap .end , DAMON_MIN_REGION );
162
- regions [2 ].end = ALIGN (last_vma -> vm_end , DAMON_MIN_REGION );
163
+ regions [2 ].end = ALIGN (prev -> vm_end , DAMON_MIN_REGION );
163
164
164
165
return 0 ;
165
166
}
@@ -180,7 +181,7 @@ static int damon_va_three_regions(struct damon_target *t,
180
181
return - EINVAL ;
181
182
182
183
mmap_read_lock (mm );
183
- rc = __damon_va_three_regions (mm -> mmap , regions );
184
+ rc = __damon_va_three_regions (mm , regions );
184
185
mmap_read_unlock (mm );
185
186
186
187
mmput (mm );
0 commit comments