1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * DAMON Debugfs Interface 4 * 5 * Author: SeongJae Park <sjpark@amazon.de> 6 */ 7 8 #define pr_fmt(fmt) "damon-dbgfs: " fmt 9 10 #include <linux/damon.h> 11 #include <linux/debugfs.h> 12 #include <linux/file.h> 13 #include <linux/mm.h> 14 #include <linux/module.h> 15 #include <linux/page_idle.h> 16 #include <linux/slab.h> 17 18 static struct damon_ctx **dbgfs_ctxs; 19 static int dbgfs_nr_ctxs; 20 static struct dentry **dbgfs_dirs; 21 static DEFINE_MUTEX(damon_dbgfs_lock); 22 23 /* 24 * Returns non-empty string on success, negative error code otherwise. 25 */ 26 static char *user_input_str(const char __user *buf, size_t count, loff_t *ppos) 27 { 28 char *kbuf; 29 ssize_t ret; 30 31 /* We do not accept continuous write */ 32 if (*ppos) 33 return ERR_PTR(-EINVAL); 34 35 kbuf = kmalloc(count + 1, GFP_KERNEL | __GFP_NOWARN); 36 if (!kbuf) 37 return ERR_PTR(-ENOMEM); 38 39 ret = simple_write_to_buffer(kbuf, count + 1, ppos, buf, count); 40 if (ret != count) { 41 kfree(kbuf); 42 return ERR_PTR(-EIO); 43 } 44 kbuf[ret] = '\0'; 45 46 return kbuf; 47 } 48 49 static ssize_t dbgfs_attrs_read(struct file *file, 50 char __user *buf, size_t count, loff_t *ppos) 51 { 52 struct damon_ctx *ctx = file->private_data; 53 char kbuf[128]; 54 int ret; 55 56 mutex_lock(&ctx->kdamond_lock); 57 ret = scnprintf(kbuf, ARRAY_SIZE(kbuf), "%lu %lu %lu %lu %lu\n", 58 ctx->attrs.sample_interval, ctx->attrs.aggr_interval, 59 ctx->attrs.ops_update_interval, 60 ctx->attrs.min_nr_regions, ctx->attrs.max_nr_regions); 61 mutex_unlock(&ctx->kdamond_lock); 62 63 return simple_read_from_buffer(buf, count, ppos, kbuf, ret); 64 } 65 66 static ssize_t dbgfs_attrs_write(struct file *file, 67 const char __user *buf, size_t count, loff_t *ppos) 68 { 69 struct damon_ctx *ctx = file->private_data; 70 struct damon_attrs attrs; 71 char *kbuf; 72 ssize_t ret; 73 74 kbuf = user_input_str(buf, count, ppos); 75 if (IS_ERR(kbuf)) 76 return PTR_ERR(kbuf); 77 78 if (sscanf(kbuf, "%lu %lu %lu %lu %lu", 79 &attrs.sample_interval, &attrs.aggr_interval, 80 &attrs.ops_update_interval, 81 &attrs.min_nr_regions, 82 &attrs.max_nr_regions) != 5) { 83 ret = -EINVAL; 84 goto out; 85 } 86 87 mutex_lock(&ctx->kdamond_lock); 88 if (ctx->kdamond) { 89 ret = -EBUSY; 90 goto unlock_out; 91 } 92 93 ret = damon_set_attrs(ctx, &attrs); 94 if (!ret) 95 ret = count; 96 unlock_out: 97 mutex_unlock(&ctx->kdamond_lock); 98 out: 99 kfree(kbuf); 100 return ret; 101 } 102 103 /* 104 * Return corresponding dbgfs' scheme action value (int) for the given 105 * damos_action if the given damos_action value is valid and supported by 106 * dbgfs, negative error code otherwise. 107 */ 108 static int damos_action_to_dbgfs_scheme_action(enum damos_action action) 109 { 110 switch (action) { 111 case DAMOS_WILLNEED: 112 return 0; 113 case DAMOS_COLD: 114 return 1; 115 case DAMOS_PAGEOUT: 116 return 2; 117 case DAMOS_HUGEPAGE: 118 return 3; 119 case DAMOS_NOHUGEPAGE: 120 return 4; 121 case DAMOS_STAT: 122 return 5; 123 default: 124 return -EINVAL; 125 } 126 } 127 128 static ssize_t sprint_schemes(struct damon_ctx *c, char *buf, ssize_t len) 129 { 130 struct damos *s; 131 int written = 0; 132 int rc; 133 134 damon_for_each_scheme(s, c) { 135 rc = scnprintf(&buf[written], len - written, 136 "%lu %lu %u %u %u %u %d %lu %lu %lu %u %u %u %d %lu %lu %lu %lu %lu %lu %lu %lu %lu\n", 137 s->pattern.min_sz_region, 138 s->pattern.max_sz_region, 139 s->pattern.min_nr_accesses, 140 s->pattern.max_nr_accesses, 141 s->pattern.min_age_region, 142 s->pattern.max_age_region, 143 damos_action_to_dbgfs_scheme_action(s->action), 144 s->quota.ms, s->quota.sz, 145 s->quota.reset_interval, 146 s->quota.weight_sz, 147 s->quota.weight_nr_accesses, 148 s->quota.weight_age, 149 s->wmarks.metric, s->wmarks.interval, 150 s->wmarks.high, s->wmarks.mid, s->wmarks.low, 151 s->stat.nr_tried, s->stat.sz_tried, 152 s->stat.nr_applied, s->stat.sz_applied, 153 s->stat.qt_exceeds); 154 if (!rc) 155 return -ENOMEM; 156 157 written += rc; 158 } 159 return written; 160 } 161 162 static ssize_t dbgfs_schemes_read(struct file *file, char __user *buf, 163 size_t count, loff_t *ppos) 164 { 165 struct damon_ctx *ctx = file->private_data; 166 char *kbuf; 167 ssize_t len; 168 169 kbuf = kmalloc(count, GFP_KERNEL | __GFP_NOWARN); 170 if (!kbuf) 171 return -ENOMEM; 172 173 mutex_lock(&ctx->kdamond_lock); 174 len = sprint_schemes(ctx, kbuf, count); 175 mutex_unlock(&ctx->kdamond_lock); 176 if (len < 0) 177 goto out; 178 len = simple_read_from_buffer(buf, count, ppos, kbuf, len); 179 180 out: 181 kfree(kbuf); 182 return len; 183 } 184 185 static void free_schemes_arr(struct damos **schemes, ssize_t nr_schemes) 186 { 187 ssize_t i; 188 189 for (i = 0; i < nr_schemes; i++) 190 kfree(schemes[i]); 191 kfree(schemes); 192 } 193 194 /* 195 * Return corresponding damos_action for the given dbgfs input for a scheme 196 * action if the input is valid, negative error code otherwise. 197 */ 198 static enum damos_action dbgfs_scheme_action_to_damos_action(int dbgfs_action) 199 { 200 switch (dbgfs_action) { 201 case 0: 202 return DAMOS_WILLNEED; 203 case 1: 204 return DAMOS_COLD; 205 case 2: 206 return DAMOS_PAGEOUT; 207 case 3: 208 return DAMOS_HUGEPAGE; 209 case 4: 210 return DAMOS_NOHUGEPAGE; 211 case 5: 212 return DAMOS_STAT; 213 default: 214 return -EINVAL; 215 } 216 } 217 218 /* 219 * Converts a string into an array of struct damos pointers 220 * 221 * Returns an array of struct damos pointers that converted if the conversion 222 * success, or NULL otherwise. 223 */ 224 static struct damos **str_to_schemes(const char *str, ssize_t len, 225 ssize_t *nr_schemes) 226 { 227 struct damos *scheme, **schemes; 228 const int max_nr_schemes = 256; 229 int pos = 0, parsed, ret; 230 unsigned int action_input; 231 enum damos_action action; 232 233 schemes = kmalloc_array(max_nr_schemes, sizeof(scheme), 234 GFP_KERNEL); 235 if (!schemes) 236 return NULL; 237 238 *nr_schemes = 0; 239 while (pos < len && *nr_schemes < max_nr_schemes) { 240 struct damos_access_pattern pattern = {}; 241 struct damos_quota quota = {}; 242 struct damos_watermarks wmarks; 243 244 ret = sscanf(&str[pos], 245 "%lu %lu %u %u %u %u %u %lu %lu %lu %u %u %u %u %lu %lu %lu %lu%n", 246 &pattern.min_sz_region, &pattern.max_sz_region, 247 &pattern.min_nr_accesses, 248 &pattern.max_nr_accesses, 249 &pattern.min_age_region, 250 &pattern.max_age_region, 251 &action_input, "a.ms, 252 "a.sz, "a.reset_interval, 253 "a.weight_sz, "a.weight_nr_accesses, 254 "a.weight_age, &wmarks.metric, 255 &wmarks.interval, &wmarks.high, &wmarks.mid, 256 &wmarks.low, &parsed); 257 if (ret != 18) 258 break; 259 action = dbgfs_scheme_action_to_damos_action(action_input); 260 if ((int)action < 0) 261 goto fail; 262 263 if (pattern.min_sz_region > pattern.max_sz_region || 264 pattern.min_nr_accesses > pattern.max_nr_accesses || 265 pattern.min_age_region > pattern.max_age_region) 266 goto fail; 267 268 if (wmarks.high < wmarks.mid || wmarks.high < wmarks.low || 269 wmarks.mid < wmarks.low) 270 goto fail; 271 272 pos += parsed; 273 scheme = damon_new_scheme(&pattern, action, "a, &wmarks); 274 if (!scheme) 275 goto fail; 276 277 schemes[*nr_schemes] = scheme; 278 *nr_schemes += 1; 279 } 280 return schemes; 281 fail: 282 free_schemes_arr(schemes, *nr_schemes); 283 return NULL; 284 } 285 286 static ssize_t dbgfs_schemes_write(struct file *file, const char __user *buf, 287 size_t count, loff_t *ppos) 288 { 289 struct damon_ctx *ctx = file->private_data; 290 char *kbuf; 291 struct damos **schemes; 292 ssize_t nr_schemes = 0, ret; 293 294 kbuf = user_input_str(buf, count, ppos); 295 if (IS_ERR(kbuf)) 296 return PTR_ERR(kbuf); 297 298 schemes = str_to_schemes(kbuf, count, &nr_schemes); 299 if (!schemes) { 300 ret = -EINVAL; 301 goto out; 302 } 303 304 mutex_lock(&ctx->kdamond_lock); 305 if (ctx->kdamond) { 306 ret = -EBUSY; 307 goto unlock_out; 308 } 309 310 damon_set_schemes(ctx, schemes, nr_schemes); 311 ret = count; 312 nr_schemes = 0; 313 314 unlock_out: 315 mutex_unlock(&ctx->kdamond_lock); 316 free_schemes_arr(schemes, nr_schemes); 317 out: 318 kfree(kbuf); 319 return ret; 320 } 321 322 static ssize_t sprint_target_ids(struct damon_ctx *ctx, char *buf, ssize_t len) 323 { 324 struct damon_target *t; 325 int id; 326 int written = 0; 327 int rc; 328 329 damon_for_each_target(t, ctx) { 330 if (damon_target_has_pid(ctx)) 331 /* Show pid numbers to debugfs users */ 332 id = pid_vnr(t->pid); 333 else 334 /* Show 42 for physical address space, just for fun */ 335 id = 42; 336 337 rc = scnprintf(&buf[written], len - written, "%d ", id); 338 if (!rc) 339 return -ENOMEM; 340 written += rc; 341 } 342 if (written) 343 written -= 1; 344 written += scnprintf(&buf[written], len - written, "\n"); 345 return written; 346 } 347 348 static ssize_t dbgfs_target_ids_read(struct file *file, 349 char __user *buf, size_t count, loff_t *ppos) 350 { 351 struct damon_ctx *ctx = file->private_data; 352 ssize_t len; 353 char ids_buf[320]; 354 355 mutex_lock(&ctx->kdamond_lock); 356 len = sprint_target_ids(ctx, ids_buf, 320); 357 mutex_unlock(&ctx->kdamond_lock); 358 if (len < 0) 359 return len; 360 361 return simple_read_from_buffer(buf, count, ppos, ids_buf, len); 362 } 363 364 /* 365 * Converts a string into an integers array 366 * 367 * Returns an array of integers array if the conversion success, or NULL 368 * otherwise. 369 */ 370 static int *str_to_ints(const char *str, ssize_t len, ssize_t *nr_ints) 371 { 372 int *array; 373 const int max_nr_ints = 32; 374 int nr; 375 int pos = 0, parsed, ret; 376 377 *nr_ints = 0; 378 array = kmalloc_array(max_nr_ints, sizeof(*array), GFP_KERNEL); 379 if (!array) 380 return NULL; 381 while (*nr_ints < max_nr_ints && pos < len) { 382 ret = sscanf(&str[pos], "%d%n", &nr, &parsed); 383 pos += parsed; 384 if (ret != 1) 385 break; 386 array[*nr_ints] = nr; 387 *nr_ints += 1; 388 } 389 390 return array; 391 } 392 393 static void dbgfs_put_pids(struct pid **pids, int nr_pids) 394 { 395 int i; 396 397 for (i = 0; i < nr_pids; i++) 398 put_pid(pids[i]); 399 } 400 401 /* 402 * Converts a string into an struct pid pointers array 403 * 404 * Returns an array of struct pid pointers if the conversion success, or NULL 405 * otherwise. 406 */ 407 static struct pid **str_to_pids(const char *str, ssize_t len, ssize_t *nr_pids) 408 { 409 int *ints; 410 ssize_t nr_ints; 411 struct pid **pids; 412 413 *nr_pids = 0; 414 415 ints = str_to_ints(str, len, &nr_ints); 416 if (!ints) 417 return NULL; 418 419 pids = kmalloc_array(nr_ints, sizeof(*pids), GFP_KERNEL); 420 if (!pids) 421 goto out; 422 423 for (; *nr_pids < nr_ints; (*nr_pids)++) { 424 pids[*nr_pids] = find_get_pid(ints[*nr_pids]); 425 if (!pids[*nr_pids]) { 426 dbgfs_put_pids(pids, *nr_pids); 427 kfree(ints); 428 kfree(pids); 429 return NULL; 430 } 431 } 432 433 out: 434 kfree(ints); 435 return pids; 436 } 437 438 /* 439 * dbgfs_set_targets() - Set monitoring targets. 440 * @ctx: monitoring context 441 * @nr_targets: number of targets 442 * @pids: array of target pids (size is same to @nr_targets) 443 * 444 * This function should not be called while the kdamond is running. @pids is 445 * ignored if the context is not configured to have pid in each target. On 446 * failure, reference counts of all pids in @pids are decremented. 447 * 448 * Return: 0 on success, negative error code otherwise. 449 */ 450 static int dbgfs_set_targets(struct damon_ctx *ctx, ssize_t nr_targets, 451 struct pid **pids) 452 { 453 ssize_t i; 454 struct damon_target *t, *next; 455 456 damon_for_each_target_safe(t, next, ctx) { 457 if (damon_target_has_pid(ctx)) 458 put_pid(t->pid); 459 damon_destroy_target(t); 460 } 461 462 for (i = 0; i < nr_targets; i++) { 463 t = damon_new_target(); 464 if (!t) { 465 damon_for_each_target_safe(t, next, ctx) 466 damon_destroy_target(t); 467 if (damon_target_has_pid(ctx)) 468 dbgfs_put_pids(pids, nr_targets); 469 return -ENOMEM; 470 } 471 if (damon_target_has_pid(ctx)) 472 t->pid = pids[i]; 473 damon_add_target(ctx, t); 474 } 475 476 return 0; 477 } 478 479 static ssize_t dbgfs_target_ids_write(struct file *file, 480 const char __user *buf, size_t count, loff_t *ppos) 481 { 482 struct damon_ctx *ctx = file->private_data; 483 bool id_is_pid = true; 484 char *kbuf; 485 struct pid **target_pids = NULL; 486 ssize_t nr_targets; 487 ssize_t ret; 488 489 kbuf = user_input_str(buf, count, ppos); 490 if (IS_ERR(kbuf)) 491 return PTR_ERR(kbuf); 492 493 if (!strncmp(kbuf, "paddr\n", count)) { 494 id_is_pid = false; 495 nr_targets = 1; 496 } 497 498 if (id_is_pid) { 499 target_pids = str_to_pids(kbuf, count, &nr_targets); 500 if (!target_pids) { 501 ret = -ENOMEM; 502 goto out; 503 } 504 } 505 506 mutex_lock(&ctx->kdamond_lock); 507 if (ctx->kdamond) { 508 if (id_is_pid) 509 dbgfs_put_pids(target_pids, nr_targets); 510 ret = -EBUSY; 511 goto unlock_out; 512 } 513 514 /* remove previously set targets */ 515 dbgfs_set_targets(ctx, 0, NULL); 516 if (!nr_targets) { 517 ret = count; 518 goto unlock_out; 519 } 520 521 /* Configure the context for the address space type */ 522 if (id_is_pid) 523 ret = damon_select_ops(ctx, DAMON_OPS_VADDR); 524 else 525 ret = damon_select_ops(ctx, DAMON_OPS_PADDR); 526 if (ret) 527 goto unlock_out; 528 529 ret = dbgfs_set_targets(ctx, nr_targets, target_pids); 530 if (!ret) 531 ret = count; 532 533 unlock_out: 534 mutex_unlock(&ctx->kdamond_lock); 535 kfree(target_pids); 536 out: 537 kfree(kbuf); 538 return ret; 539 } 540 541 static ssize_t sprint_init_regions(struct damon_ctx *c, char *buf, ssize_t len) 542 { 543 struct damon_target *t; 544 struct damon_region *r; 545 int target_idx = 0; 546 int written = 0; 547 int rc; 548 549 damon_for_each_target(t, c) { 550 damon_for_each_region(r, t) { 551 rc = scnprintf(&buf[written], len - written, 552 "%d %lu %lu\n", 553 target_idx, r->ar.start, r->ar.end); 554 if (!rc) 555 return -ENOMEM; 556 written += rc; 557 } 558 target_idx++; 559 } 560 return written; 561 } 562 563 static ssize_t dbgfs_init_regions_read(struct file *file, char __user *buf, 564 size_t count, loff_t *ppos) 565 { 566 struct damon_ctx *ctx = file->private_data; 567 char *kbuf; 568 ssize_t len; 569 570 kbuf = kmalloc(count, GFP_KERNEL | __GFP_NOWARN); 571 if (!kbuf) 572 return -ENOMEM; 573 574 mutex_lock(&ctx->kdamond_lock); 575 if (ctx->kdamond) { 576 mutex_unlock(&ctx->kdamond_lock); 577 len = -EBUSY; 578 goto out; 579 } 580 581 len = sprint_init_regions(ctx, kbuf, count); 582 mutex_unlock(&ctx->kdamond_lock); 583 if (len < 0) 584 goto out; 585 len = simple_read_from_buffer(buf, count, ppos, kbuf, len); 586 587 out: 588 kfree(kbuf); 589 return len; 590 } 591 592 static int add_init_region(struct damon_ctx *c, int target_idx, 593 struct damon_addr_range *ar) 594 { 595 struct damon_target *t; 596 struct damon_region *r, *prev; 597 unsigned long idx = 0; 598 int rc = -EINVAL; 599 600 if (ar->start >= ar->end) 601 return -EINVAL; 602 603 damon_for_each_target(t, c) { 604 if (idx++ == target_idx) { 605 r = damon_new_region(ar->start, ar->end); 606 if (!r) 607 return -ENOMEM; 608 damon_add_region(r, t); 609 if (damon_nr_regions(t) > 1) { 610 prev = damon_prev_region(r); 611 if (prev->ar.end > r->ar.start) { 612 damon_destroy_region(r, t); 613 return -EINVAL; 614 } 615 } 616 rc = 0; 617 } 618 } 619 return rc; 620 } 621 622 static int set_init_regions(struct damon_ctx *c, const char *str, ssize_t len) 623 { 624 struct damon_target *t; 625 struct damon_region *r, *next; 626 int pos = 0, parsed, ret; 627 int target_idx; 628 struct damon_addr_range ar; 629 int err; 630 631 damon_for_each_target(t, c) { 632 damon_for_each_region_safe(r, next, t) 633 damon_destroy_region(r, t); 634 } 635 636 while (pos < len) { 637 ret = sscanf(&str[pos], "%d %lu %lu%n", 638 &target_idx, &ar.start, &ar.end, &parsed); 639 if (ret != 3) 640 break; 641 err = add_init_region(c, target_idx, &ar); 642 if (err) 643 goto fail; 644 pos += parsed; 645 } 646 647 return 0; 648 649 fail: 650 damon_for_each_target(t, c) { 651 damon_for_each_region_safe(r, next, t) 652 damon_destroy_region(r, t); 653 } 654 return err; 655 } 656 657 static ssize_t dbgfs_init_regions_write(struct file *file, 658 const char __user *buf, size_t count, 659 loff_t *ppos) 660 { 661 struct damon_ctx *ctx = file->private_data; 662 char *kbuf; 663 ssize_t ret = count; 664 int err; 665 666 kbuf = user_input_str(buf, count, ppos); 667 if (IS_ERR(kbuf)) 668 return PTR_ERR(kbuf); 669 670 mutex_lock(&ctx->kdamond_lock); 671 if (ctx->kdamond) { 672 ret = -EBUSY; 673 goto unlock_out; 674 } 675 676 err = set_init_regions(ctx, kbuf, ret); 677 if (err) 678 ret = err; 679 680 unlock_out: 681 mutex_unlock(&ctx->kdamond_lock); 682 kfree(kbuf); 683 return ret; 684 } 685 686 static ssize_t dbgfs_kdamond_pid_read(struct file *file, 687 char __user *buf, size_t count, loff_t *ppos) 688 { 689 struct damon_ctx *ctx = file->private_data; 690 char *kbuf; 691 ssize_t len; 692 693 kbuf = kmalloc(count, GFP_KERNEL | __GFP_NOWARN); 694 if (!kbuf) 695 return -ENOMEM; 696 697 mutex_lock(&ctx->kdamond_lock); 698 if (ctx->kdamond) 699 len = scnprintf(kbuf, count, "%d\n", ctx->kdamond->pid); 700 else 701 len = scnprintf(kbuf, count, "none\n"); 702 mutex_unlock(&ctx->kdamond_lock); 703 if (!len) 704 goto out; 705 len = simple_read_from_buffer(buf, count, ppos, kbuf, len); 706 707 out: 708 kfree(kbuf); 709 return len; 710 } 711 712 static int damon_dbgfs_open(struct inode *inode, struct file *file) 713 { 714 file->private_data = inode->i_private; 715 716 return nonseekable_open(inode, file); 717 } 718 719 static const struct file_operations attrs_fops = { 720 .open = damon_dbgfs_open, 721 .read = dbgfs_attrs_read, 722 .write = dbgfs_attrs_write, 723 }; 724 725 static const struct file_operations schemes_fops = { 726 .open = damon_dbgfs_open, 727 .read = dbgfs_schemes_read, 728 .write = dbgfs_schemes_write, 729 }; 730 731 static const struct file_operations target_ids_fops = { 732 .open = damon_dbgfs_open, 733 .read = dbgfs_target_ids_read, 734 .write = dbgfs_target_ids_write, 735 }; 736 737 static const struct file_operations init_regions_fops = { 738 .open = damon_dbgfs_open, 739 .read = dbgfs_init_regions_read, 740 .write = dbgfs_init_regions_write, 741 }; 742 743 static const struct file_operations kdamond_pid_fops = { 744 .open = damon_dbgfs_open, 745 .read = dbgfs_kdamond_pid_read, 746 }; 747 748 static void dbgfs_fill_ctx_dir(struct dentry *dir, struct damon_ctx *ctx) 749 { 750 const char * const file_names[] = {"attrs", "schemes", "target_ids", 751 "init_regions", "kdamond_pid"}; 752 const struct file_operations *fops[] = {&attrs_fops, &schemes_fops, 753 &target_ids_fops, &init_regions_fops, &kdamond_pid_fops}; 754 int i; 755 756 for (i = 0; i < ARRAY_SIZE(file_names); i++) 757 debugfs_create_file(file_names[i], 0600, dir, ctx, fops[i]); 758 } 759 760 static void dbgfs_before_terminate(struct damon_ctx *ctx) 761 { 762 struct damon_target *t, *next; 763 764 if (!damon_target_has_pid(ctx)) 765 return; 766 767 mutex_lock(&ctx->kdamond_lock); 768 damon_for_each_target_safe(t, next, ctx) { 769 put_pid(t->pid); 770 damon_destroy_target(t); 771 } 772 mutex_unlock(&ctx->kdamond_lock); 773 } 774 775 static struct damon_ctx *dbgfs_new_ctx(void) 776 { 777 struct damon_ctx *ctx; 778 779 ctx = damon_new_ctx(); 780 if (!ctx) 781 return NULL; 782 783 if (damon_select_ops(ctx, DAMON_OPS_VADDR) && 784 damon_select_ops(ctx, DAMON_OPS_PADDR)) { 785 damon_destroy_ctx(ctx); 786 return NULL; 787 } 788 ctx->callback.before_terminate = dbgfs_before_terminate; 789 return ctx; 790 } 791 792 static void dbgfs_destroy_ctx(struct damon_ctx *ctx) 793 { 794 damon_destroy_ctx(ctx); 795 } 796 797 /* 798 * Make a context of @name and create a debugfs directory for it. 799 * 800 * This function should be called while holding damon_dbgfs_lock. 801 * 802 * Returns 0 on success, negative error code otherwise. 803 */ 804 static int dbgfs_mk_context(char *name) 805 { 806 struct dentry *root, **new_dirs, *new_dir; 807 struct damon_ctx **new_ctxs, *new_ctx; 808 809 if (damon_nr_running_ctxs()) 810 return -EBUSY; 811 812 new_ctxs = krealloc(dbgfs_ctxs, sizeof(*dbgfs_ctxs) * 813 (dbgfs_nr_ctxs + 1), GFP_KERNEL); 814 if (!new_ctxs) 815 return -ENOMEM; 816 dbgfs_ctxs = new_ctxs; 817 818 new_dirs = krealloc(dbgfs_dirs, sizeof(*dbgfs_dirs) * 819 (dbgfs_nr_ctxs + 1), GFP_KERNEL); 820 if (!new_dirs) 821 return -ENOMEM; 822 dbgfs_dirs = new_dirs; 823 824 root = dbgfs_dirs[0]; 825 if (!root) 826 return -ENOENT; 827 828 new_dir = debugfs_create_dir(name, root); 829 /* Below check is required for a potential duplicated name case */ 830 if (IS_ERR(new_dir)) 831 return PTR_ERR(new_dir); 832 dbgfs_dirs[dbgfs_nr_ctxs] = new_dir; 833 834 new_ctx = dbgfs_new_ctx(); 835 if (!new_ctx) { 836 debugfs_remove(new_dir); 837 dbgfs_dirs[dbgfs_nr_ctxs] = NULL; 838 return -ENOMEM; 839 } 840 841 dbgfs_ctxs[dbgfs_nr_ctxs] = new_ctx; 842 dbgfs_fill_ctx_dir(dbgfs_dirs[dbgfs_nr_ctxs], 843 dbgfs_ctxs[dbgfs_nr_ctxs]); 844 dbgfs_nr_ctxs++; 845 846 return 0; 847 } 848 849 static ssize_t dbgfs_mk_context_write(struct file *file, 850 const char __user *buf, size_t count, loff_t *ppos) 851 { 852 char *kbuf; 853 char *ctx_name; 854 ssize_t ret; 855 856 kbuf = user_input_str(buf, count, ppos); 857 if (IS_ERR(kbuf)) 858 return PTR_ERR(kbuf); 859 ctx_name = kmalloc(count + 1, GFP_KERNEL); 860 if (!ctx_name) { 861 kfree(kbuf); 862 return -ENOMEM; 863 } 864 865 /* Trim white space */ 866 if (sscanf(kbuf, "%s", ctx_name) != 1) { 867 ret = -EINVAL; 868 goto out; 869 } 870 871 mutex_lock(&damon_dbgfs_lock); 872 ret = dbgfs_mk_context(ctx_name); 873 if (!ret) 874 ret = count; 875 mutex_unlock(&damon_dbgfs_lock); 876 877 out: 878 kfree(kbuf); 879 kfree(ctx_name); 880 return ret; 881 } 882 883 /* 884 * Remove a context of @name and its debugfs directory. 885 * 886 * This function should be called while holding damon_dbgfs_lock. 887 * 888 * Return 0 on success, negative error code otherwise. 889 */ 890 static int dbgfs_rm_context(char *name) 891 { 892 struct dentry *root, *dir, **new_dirs; 893 struct inode *inode; 894 struct damon_ctx **new_ctxs; 895 int i, j; 896 int ret = 0; 897 898 if (damon_nr_running_ctxs()) 899 return -EBUSY; 900 901 root = dbgfs_dirs[0]; 902 if (!root) 903 return -ENOENT; 904 905 dir = debugfs_lookup(name, root); 906 if (!dir) 907 return -ENOENT; 908 909 inode = d_inode(dir); 910 if (!S_ISDIR(inode->i_mode)) { 911 ret = -EINVAL; 912 goto out_dput; 913 } 914 915 new_dirs = kmalloc_array(dbgfs_nr_ctxs - 1, sizeof(*dbgfs_dirs), 916 GFP_KERNEL); 917 if (!new_dirs) { 918 ret = -ENOMEM; 919 goto out_dput; 920 } 921 922 new_ctxs = kmalloc_array(dbgfs_nr_ctxs - 1, sizeof(*dbgfs_ctxs), 923 GFP_KERNEL); 924 if (!new_ctxs) { 925 ret = -ENOMEM; 926 goto out_new_dirs; 927 } 928 929 for (i = 0, j = 0; i < dbgfs_nr_ctxs; i++) { 930 if (dbgfs_dirs[i] == dir) { 931 debugfs_remove(dbgfs_dirs[i]); 932 dbgfs_destroy_ctx(dbgfs_ctxs[i]); 933 continue; 934 } 935 new_dirs[j] = dbgfs_dirs[i]; 936 new_ctxs[j++] = dbgfs_ctxs[i]; 937 } 938 939 kfree(dbgfs_dirs); 940 kfree(dbgfs_ctxs); 941 942 dbgfs_dirs = new_dirs; 943 dbgfs_ctxs = new_ctxs; 944 dbgfs_nr_ctxs--; 945 946 goto out_dput; 947 948 out_new_dirs: 949 kfree(new_dirs); 950 out_dput: 951 dput(dir); 952 return ret; 953 } 954 955 static ssize_t dbgfs_rm_context_write(struct file *file, 956 const char __user *buf, size_t count, loff_t *ppos) 957 { 958 char *kbuf; 959 ssize_t ret; 960 char *ctx_name; 961 962 kbuf = user_input_str(buf, count, ppos); 963 if (IS_ERR(kbuf)) 964 return PTR_ERR(kbuf); 965 ctx_name = kmalloc(count + 1, GFP_KERNEL); 966 if (!ctx_name) { 967 kfree(kbuf); 968 return -ENOMEM; 969 } 970 971 /* Trim white space */ 972 if (sscanf(kbuf, "%s", ctx_name) != 1) { 973 ret = -EINVAL; 974 goto out; 975 } 976 977 mutex_lock(&damon_dbgfs_lock); 978 ret = dbgfs_rm_context(ctx_name); 979 if (!ret) 980 ret = count; 981 mutex_unlock(&damon_dbgfs_lock); 982 983 out: 984 kfree(kbuf); 985 kfree(ctx_name); 986 return ret; 987 } 988 989 static ssize_t dbgfs_monitor_on_read(struct file *file, 990 char __user *buf, size_t count, loff_t *ppos) 991 { 992 char monitor_on_buf[5]; 993 bool monitor_on = damon_nr_running_ctxs() != 0; 994 int len; 995 996 len = scnprintf(monitor_on_buf, 5, monitor_on ? "on\n" : "off\n"); 997 998 return simple_read_from_buffer(buf, count, ppos, monitor_on_buf, len); 999 } 1000 1001 static ssize_t dbgfs_monitor_on_write(struct file *file, 1002 const char __user *buf, size_t count, loff_t *ppos) 1003 { 1004 ssize_t ret; 1005 char *kbuf; 1006 1007 kbuf = user_input_str(buf, count, ppos); 1008 if (IS_ERR(kbuf)) 1009 return PTR_ERR(kbuf); 1010 1011 /* Remove white space */ 1012 if (sscanf(kbuf, "%s", kbuf) != 1) { 1013 kfree(kbuf); 1014 return -EINVAL; 1015 } 1016 1017 mutex_lock(&damon_dbgfs_lock); 1018 if (!strncmp(kbuf, "on", count)) { 1019 int i; 1020 1021 for (i = 0; i < dbgfs_nr_ctxs; i++) { 1022 if (damon_targets_empty(dbgfs_ctxs[i])) { 1023 kfree(kbuf); 1024 mutex_unlock(&damon_dbgfs_lock); 1025 return -EINVAL; 1026 } 1027 } 1028 ret = damon_start(dbgfs_ctxs, dbgfs_nr_ctxs, true); 1029 } else if (!strncmp(kbuf, "off", count)) { 1030 ret = damon_stop(dbgfs_ctxs, dbgfs_nr_ctxs); 1031 } else { 1032 ret = -EINVAL; 1033 } 1034 mutex_unlock(&damon_dbgfs_lock); 1035 1036 if (!ret) 1037 ret = count; 1038 kfree(kbuf); 1039 return ret; 1040 } 1041 1042 static const struct file_operations mk_contexts_fops = { 1043 .write = dbgfs_mk_context_write, 1044 }; 1045 1046 static const struct file_operations rm_contexts_fops = { 1047 .write = dbgfs_rm_context_write, 1048 }; 1049 1050 static const struct file_operations monitor_on_fops = { 1051 .read = dbgfs_monitor_on_read, 1052 .write = dbgfs_monitor_on_write, 1053 }; 1054 1055 static int __init __damon_dbgfs_init(void) 1056 { 1057 struct dentry *dbgfs_root; 1058 const char * const file_names[] = {"mk_contexts", "rm_contexts", 1059 "monitor_on"}; 1060 const struct file_operations *fops[] = {&mk_contexts_fops, 1061 &rm_contexts_fops, &monitor_on_fops}; 1062 int i; 1063 1064 dbgfs_root = debugfs_create_dir("damon", NULL); 1065 1066 for (i = 0; i < ARRAY_SIZE(file_names); i++) 1067 debugfs_create_file(file_names[i], 0600, dbgfs_root, NULL, 1068 fops[i]); 1069 dbgfs_fill_ctx_dir(dbgfs_root, dbgfs_ctxs[0]); 1070 1071 dbgfs_dirs = kmalloc(sizeof(dbgfs_root), GFP_KERNEL); 1072 if (!dbgfs_dirs) { 1073 debugfs_remove(dbgfs_root); 1074 return -ENOMEM; 1075 } 1076 dbgfs_dirs[0] = dbgfs_root; 1077 1078 return 0; 1079 } 1080 1081 /* 1082 * Functions for the initialization 1083 */ 1084 1085 static int __init damon_dbgfs_init(void) 1086 { 1087 int rc = -ENOMEM; 1088 1089 mutex_lock(&damon_dbgfs_lock); 1090 dbgfs_ctxs = kmalloc(sizeof(*dbgfs_ctxs), GFP_KERNEL); 1091 if (!dbgfs_ctxs) 1092 goto out; 1093 dbgfs_ctxs[0] = dbgfs_new_ctx(); 1094 if (!dbgfs_ctxs[0]) { 1095 kfree(dbgfs_ctxs); 1096 goto out; 1097 } 1098 dbgfs_nr_ctxs = 1; 1099 1100 rc = __damon_dbgfs_init(); 1101 if (rc) { 1102 kfree(dbgfs_ctxs[0]); 1103 kfree(dbgfs_ctxs); 1104 pr_err("%s: dbgfs init failed\n", __func__); 1105 } 1106 1107 out: 1108 mutex_unlock(&damon_dbgfs_lock); 1109 return rc; 1110 } 1111 1112 module_init(damon_dbgfs_init); 1113 1114 #include "dbgfs-test.h" 1115