Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mm/damon/vaddr: do not split regions for min_nr_regions

The previous commit made DAMON core split regions at the beginning for
min_nr_regions. The virtual address space operation set (vaddr) does
similar work on its own, for a case user delegates entire initial
monitoring regions setup to vaddr. It is unnecessary now, as DAMON core
will do similar work for any case. Remove the duplicated work in vaddr.

Also, remove a helper function that was being used only for the work, and
the test code of the helper function.

Link: https://lkml.kernel.org/r/20260228222831.7232-3-sj@kernel.org
Signed-off-by: SeongJae Park <sj@kernel.org>
Cc: Brendan Higgins <brendan.higgins@linux.dev>
Cc: David Gow <davidgow@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

SeongJae Park and committed by
Andrew Morton
442d87c7 b1029f29

+2 -144
-76
mm/damon/tests/vaddr-kunit.h
··· 252 252 new_three_regions, expected, ARRAY_SIZE(expected)); 253 253 } 254 254 255 - static void damon_test_split_evenly_fail(struct kunit *test, 256 - unsigned long start, unsigned long end, unsigned int nr_pieces) 257 - { 258 - struct damon_target *t = damon_new_target(); 259 - struct damon_region *r; 260 - 261 - if (!t) 262 - kunit_skip(test, "target alloc fail"); 263 - 264 - r = damon_new_region(start, end); 265 - if (!r) { 266 - damon_free_target(t); 267 - kunit_skip(test, "region alloc fail"); 268 - } 269 - 270 - damon_add_region(r, t); 271 - KUNIT_EXPECT_EQ(test, 272 - damon_va_evenly_split_region(t, r, nr_pieces), -EINVAL); 273 - KUNIT_EXPECT_EQ(test, damon_nr_regions(t), 1u); 274 - 275 - damon_for_each_region(r, t) { 276 - KUNIT_EXPECT_EQ(test, r->ar.start, start); 277 - KUNIT_EXPECT_EQ(test, r->ar.end, end); 278 - } 279 - 280 - damon_free_target(t); 281 - } 282 - 283 - static void damon_test_split_evenly_succ(struct kunit *test, 284 - unsigned long start, unsigned long end, unsigned int nr_pieces) 285 - { 286 - struct damon_target *t = damon_new_target(); 287 - struct damon_region *r; 288 - unsigned long expected_width = (end - start) / nr_pieces; 289 - unsigned long i = 0; 290 - 291 - if (!t) 292 - kunit_skip(test, "target alloc fail"); 293 - r = damon_new_region(start, end); 294 - if (!r) { 295 - damon_free_target(t); 296 - kunit_skip(test, "region alloc fail"); 297 - } 298 - damon_add_region(r, t); 299 - KUNIT_EXPECT_EQ(test, 300 - damon_va_evenly_split_region(t, r, nr_pieces), 0); 301 - KUNIT_EXPECT_EQ(test, damon_nr_regions(t), nr_pieces); 302 - 303 - damon_for_each_region(r, t) { 304 - if (i == nr_pieces - 1) { 305 - KUNIT_EXPECT_EQ(test, 306 - r->ar.start, start + i * expected_width); 307 - KUNIT_EXPECT_EQ(test, r->ar.end, end); 308 - break; 309 - } 310 - KUNIT_EXPECT_EQ(test, 311 - r->ar.start, start + i++ * expected_width); 312 - KUNIT_EXPECT_EQ(test, r->ar.end, start + i * expected_width); 313 - } 314 - damon_free_target(t); 315 - } 316 - 317 - static void damon_test_split_evenly(struct kunit *test) 318 - { 319 - KUNIT_EXPECT_EQ(test, damon_va_evenly_split_region(NULL, NULL, 5), 320 - -EINVAL); 321 - 322 - damon_test_split_evenly_fail(test, 0, 100, 0); 323 - damon_test_split_evenly_succ(test, 0, 100, 10); 324 - damon_test_split_evenly_succ(test, 5, 59, 5); 325 - damon_test_split_evenly_succ(test, 4, 6, 1); 326 - damon_test_split_evenly_succ(test, 0, 3, 2); 327 - damon_test_split_evenly_fail(test, 5, 6, 2); 328 - } 329 - 330 255 static struct kunit_case damon_test_cases[] = { 331 256 KUNIT_CASE(damon_test_three_regions_in_vmas), 332 257 KUNIT_CASE(damon_test_apply_three_regions1), 333 258 KUNIT_CASE(damon_test_apply_three_regions2), 334 259 KUNIT_CASE(damon_test_apply_three_regions3), 335 260 KUNIT_CASE(damon_test_apply_three_regions4), 336 - KUNIT_CASE(damon_test_split_evenly), 337 261 {}, 338 262 }; 339 263
+2 -68
mm/damon/vaddr.c
··· 53 53 return mm; 54 54 } 55 55 56 - /* 57 - * Functions for the initial monitoring target regions construction 58 - */ 59 - 60 - /* 61 - * Size-evenly split a region into 'nr_pieces' small regions 62 - * 63 - * Returns 0 on success, or negative error code otherwise. 64 - */ 65 - static int damon_va_evenly_split_region(struct damon_target *t, 66 - struct damon_region *r, unsigned int nr_pieces) 67 - { 68 - unsigned long sz_orig, sz_piece, orig_end; 69 - struct damon_region *n = NULL, *next; 70 - unsigned long start; 71 - unsigned int i; 72 - 73 - if (!r || !nr_pieces) 74 - return -EINVAL; 75 - 76 - if (nr_pieces == 1) 77 - return 0; 78 - 79 - orig_end = r->ar.end; 80 - sz_orig = damon_sz_region(r); 81 - sz_piece = ALIGN_DOWN(sz_orig / nr_pieces, DAMON_MIN_REGION_SZ); 82 - 83 - if (!sz_piece) 84 - return -EINVAL; 85 - 86 - r->ar.end = r->ar.start + sz_piece; 87 - next = damon_next_region(r); 88 - for (start = r->ar.end, i = 1; i < nr_pieces; start += sz_piece, i++) { 89 - n = damon_new_region(start, start + sz_piece); 90 - if (!n) 91 - return -ENOMEM; 92 - damon_insert_region(n, r, next, t); 93 - r = n; 94 - } 95 - /* complement last region for possible rounding error */ 96 - if (n) 97 - n->ar.end = orig_end; 98 - 99 - return 0; 100 - } 101 - 102 56 static unsigned long sz_range(struct damon_addr_range *r) 103 57 { 104 58 return r->end - r->start; ··· 194 240 struct damon_target *t) 195 241 { 196 242 struct damon_target *ti; 197 - struct damon_region *r; 198 243 struct damon_addr_range regions[3]; 199 - unsigned long sz = 0, nr_pieces; 200 - int i, tidx = 0; 244 + int tidx = 0; 201 245 202 246 if (damon_va_three_regions(t, regions)) { 203 247 damon_for_each_target(ti, ctx) { ··· 207 255 return; 208 256 } 209 257 210 - for (i = 0; i < 3; i++) 211 - sz += regions[i].end - regions[i].start; 212 - if (ctx->attrs.min_nr_regions) 213 - sz /= ctx->attrs.min_nr_regions; 214 - if (sz < DAMON_MIN_REGION_SZ) 215 - sz = DAMON_MIN_REGION_SZ; 216 - 217 - /* Set the initial three regions of the target */ 218 - for (i = 0; i < 3; i++) { 219 - r = damon_new_region(regions[i].start, regions[i].end); 220 - if (!r) { 221 - pr_err("%d'th init region creation failed\n", i); 222 - return; 223 - } 224 - damon_add_region(r, t); 225 - 226 - nr_pieces = (regions[i].end - regions[i].start) / sz; 227 - damon_va_evenly_split_region(t, r, nr_pieces); 228 - } 258 + damon_set_regions(t, regions, 3, DAMON_MIN_REGION_SZ); 229 259 } 230 260 231 261 /* Initialize '->regions_list' of every target (task) */