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 ret = damon_set_schemes(ctx, schemes, nr_schemes); 311 if (!ret) { 312 ret = count; 313 nr_schemes = 0; 314 } 315 316 unlock_out: 317 mutex_unlock(&ctx->kdamond_lock); 318 free_schemes_arr(schemes, nr_schemes); 319 out: 320 kfree(kbuf); 321 return ret; 322 } 323 324 static ssize_t sprint_target_ids(struct damon_ctx *ctx, char *buf, ssize_t len) 325 { 326 struct damon_target *t; 327 int id; 328 int written = 0; 329 int rc; 330 331 damon_for_each_target(t, ctx) { 332 if (damon_target_has_pid(ctx)) 333 /* Show pid numbers to debugfs users */ 334 id = pid_vnr(t->pid); 335 else 336 /* Show 42 for physical address space, just for fun */ 337 id = 42; 338 339 rc = scnprintf(&buf[written], len - written, "%d ", id); 340 if (!rc) 341 return -ENOMEM; 342 written += rc; 343 } 344 if (written) 345 written -= 1; 346 written += scnprintf(&buf[written], len - written, "\n"); 347 return written; 348 } 349 350 static ssize_t dbgfs_target_ids_read(struct file *file, 351 char __user *buf, size_t count, loff_t *ppos) 352 { 353 struct damon_ctx *ctx = file->private_data; 354 ssize_t len; 355 char ids_buf[320]; 356 357 mutex_lock(&ctx->kdamond_lock); 358 len = sprint_target_ids(ctx, ids_buf, 320); 359 mutex_unlock(&ctx->kdamond_lock); 360 if (len < 0) 361 return len; 362 363 return simple_read_from_buffer(buf, count, ppos, ids_buf, len); 364 } 365 366 /* 367 * Converts a string into an integers array 368 * 369 * Returns an array of integers array if the conversion success, or NULL 370 * otherwise. 371 */ 372 static int *str_to_ints(const char *str, ssize_t len, ssize_t *nr_ints) 373 { 374 int *array; 375 const int max_nr_ints = 32; 376 int nr; 377 int pos = 0, parsed, ret; 378 379 *nr_ints = 0; 380 array = kmalloc_array(max_nr_ints, sizeof(*array), GFP_KERNEL); 381 if (!array) 382 return NULL; 383 while (*nr_ints < max_nr_ints && pos < len) { 384 ret = sscanf(&str[pos], "%d%n", &nr, &parsed); 385 pos += parsed; 386 if (ret != 1) 387 break; 388 array[*nr_ints] = nr; 389 *nr_ints += 1; 390 } 391 392 return array; 393 } 394 395 static void dbgfs_put_pids(struct pid **pids, int nr_pids) 396 { 397 int i; 398 399 for (i = 0; i < nr_pids; i++) 400 put_pid(pids[i]); 401 } 402 403 /* 404 * Converts a string into an struct pid pointers array 405 * 406 * Returns an array of struct pid pointers if the conversion success, or NULL 407 * otherwise. 408 */ 409 static struct pid **str_to_pids(const char *str, ssize_t len, ssize_t *nr_pids) 410 { 411 int *ints; 412 ssize_t nr_ints; 413 struct pid **pids; 414 415 *nr_pids = 0; 416 417 ints = str_to_ints(str, len, &nr_ints); 418 if (!ints) 419 return NULL; 420 421 pids = kmalloc_array(nr_ints, sizeof(*pids), GFP_KERNEL); 422 if (!pids) 423 goto out; 424 425 for (; *nr_pids < nr_ints; (*nr_pids)++) { 426 pids[*nr_pids] = find_get_pid(ints[*nr_pids]); 427 if (!pids[*nr_pids]) { 428 dbgfs_put_pids(pids, *nr_pids); 429 kfree(ints); 430 kfree(pids); 431 return NULL; 432 } 433 } 434 435 out: 436 kfree(ints); 437 return pids; 438 } 439 440 /* 441 * dbgfs_set_targets() - Set monitoring targets. 442 * @ctx: monitoring context 443 * @nr_targets: number of targets 444 * @pids: array of target pids (size is same to @nr_targets) 445 * 446 * This function should not be called while the kdamond is running. @pids is 447 * ignored if the context is not configured to have pid in each target. On 448 * failure, reference counts of all pids in @pids are decremented. 449 * 450 * Return: 0 on success, negative error code otherwise. 451 */ 452 static int dbgfs_set_targets(struct damon_ctx *ctx, ssize_t nr_targets, 453 struct pid **pids) 454 { 455 ssize_t i; 456 struct damon_target *t, *next; 457 458 damon_for_each_target_safe(t, next, ctx) { 459 if (damon_target_has_pid(ctx)) 460 put_pid(t->pid); 461 damon_destroy_target(t); 462 } 463 464 for (i = 0; i < nr_targets; i++) { 465 t = damon_new_target(); 466 if (!t) { 467 damon_for_each_target_safe(t, next, ctx) 468 damon_destroy_target(t); 469 if (damon_target_has_pid(ctx)) 470 dbgfs_put_pids(pids, nr_targets); 471 return -ENOMEM; 472 } 473 if (damon_target_has_pid(ctx)) 474 t->pid = pids[i]; 475 damon_add_target(ctx, t); 476 } 477 478 return 0; 479 } 480 481 static ssize_t dbgfs_target_ids_write(struct file *file, 482 const char __user *buf, size_t count, loff_t *ppos) 483 { 484 struct damon_ctx *ctx = file->private_data; 485 bool id_is_pid = true; 486 char *kbuf; 487 struct pid **target_pids = NULL; 488 ssize_t nr_targets; 489 ssize_t ret; 490 491 kbuf = user_input_str(buf, count, ppos); 492 if (IS_ERR(kbuf)) 493 return PTR_ERR(kbuf); 494 495 if (!strncmp(kbuf, "paddr\n", count)) { 496 id_is_pid = false; 497 nr_targets = 1; 498 } 499 500 if (id_is_pid) { 501 target_pids = str_to_pids(kbuf, count, &nr_targets); 502 if (!target_pids) { 503 ret = -ENOMEM; 504 goto out; 505 } 506 } 507 508 mutex_lock(&ctx->kdamond_lock); 509 if (ctx->kdamond) { 510 if (id_is_pid) 511 dbgfs_put_pids(target_pids, nr_targets); 512 ret = -EBUSY; 513 goto unlock_out; 514 } 515 516 /* remove previously set targets */ 517 dbgfs_set_targets(ctx, 0, NULL); 518 if (!nr_targets) { 519 ret = count; 520 goto unlock_out; 521 } 522 523 /* Configure the context for the address space type */ 524 if (id_is_pid) 525 ret = damon_select_ops(ctx, DAMON_OPS_VADDR); 526 else 527 ret = damon_select_ops(ctx, DAMON_OPS_PADDR); 528 if (ret) 529 goto unlock_out; 530 531 ret = dbgfs_set_targets(ctx, nr_targets, target_pids); 532 if (!ret) 533 ret = count; 534 535 unlock_out: 536 mutex_unlock(&ctx->kdamond_lock); 537 kfree(target_pids); 538 out: 539 kfree(kbuf); 540 return ret; 541 } 542 543 static ssize_t sprint_init_regions(struct damon_ctx *c, char *buf, ssize_t len) 544 { 545 struct damon_target *t; 546 struct damon_region *r; 547 int target_idx = 0; 548 int written = 0; 549 int rc; 550 551 damon_for_each_target(t, c) { 552 damon_for_each_region(r, t) { 553 rc = scnprintf(&buf[written], len - written, 554 "%d %lu %lu\n", 555 target_idx, r->ar.start, r->ar.end); 556 if (!rc) 557 return -ENOMEM; 558 written += rc; 559 } 560 target_idx++; 561 } 562 return written; 563 } 564 565 static ssize_t dbgfs_init_regions_read(struct file *file, char __user *buf, 566 size_t count, loff_t *ppos) 567 { 568 struct damon_ctx *ctx = file->private_data; 569 char *kbuf; 570 ssize_t len; 571 572 kbuf = kmalloc(count, GFP_KERNEL | __GFP_NOWARN); 573 if (!kbuf) 574 return -ENOMEM; 575 576 mutex_lock(&ctx->kdamond_lock); 577 if (ctx->kdamond) { 578 mutex_unlock(&ctx->kdamond_lock); 579 len = -EBUSY; 580 goto out; 581 } 582 583 len = sprint_init_regions(ctx, kbuf, count); 584 mutex_unlock(&ctx->kdamond_lock); 585 if (len < 0) 586 goto out; 587 len = simple_read_from_buffer(buf, count, ppos, kbuf, len); 588 589 out: 590 kfree(kbuf); 591 return len; 592 } 593 594 static int add_init_region(struct damon_ctx *c, int target_idx, 595 struct damon_addr_range *ar) 596 { 597 struct damon_target *t; 598 struct damon_region *r, *prev; 599 unsigned long idx = 0; 600 int rc = -EINVAL; 601 602 if (ar->start >= ar->end) 603 return -EINVAL; 604 605 damon_for_each_target(t, c) { 606 if (idx++ == target_idx) { 607 r = damon_new_region(ar->start, ar->end); 608 if (!r) 609 return -ENOMEM; 610 damon_add_region(r, t); 611 if (damon_nr_regions(t) > 1) { 612 prev = damon_prev_region(r); 613 if (prev->ar.end > r->ar.start) { 614 damon_destroy_region(r, t); 615 return -EINVAL; 616 } 617 } 618 rc = 0; 619 } 620 } 621 return rc; 622 } 623 624 static int set_init_regions(struct damon_ctx *c, const char *str, ssize_t len) 625 { 626 struct damon_target *t; 627 struct damon_region *r, *next; 628 int pos = 0, parsed, ret; 629 int target_idx; 630 struct damon_addr_range ar; 631 int err; 632 633 damon_for_each_target(t, c) { 634 damon_for_each_region_safe(r, next, t) 635 damon_destroy_region(r, t); 636 } 637 638 while (pos < len) { 639 ret = sscanf(&str[pos], "%d %lu %lu%n", 640 &target_idx, &ar.start, &ar.end, &parsed); 641 if (ret != 3) 642 break; 643 err = add_init_region(c, target_idx, &ar); 644 if (err) 645 goto fail; 646 pos += parsed; 647 } 648 649 return 0; 650 651 fail: 652 damon_for_each_target(t, c) { 653 damon_for_each_region_safe(r, next, t) 654 damon_destroy_region(r, t); 655 } 656 return err; 657 } 658 659 static ssize_t dbgfs_init_regions_write(struct file *file, 660 const char __user *buf, size_t count, 661 loff_t *ppos) 662 { 663 struct damon_ctx *ctx = file->private_data; 664 char *kbuf; 665 ssize_t ret = count; 666 int err; 667 668 kbuf = user_input_str(buf, count, ppos); 669 if (IS_ERR(kbuf)) 670 return PTR_ERR(kbuf); 671 672 mutex_lock(&ctx->kdamond_lock); 673 if (ctx->kdamond) { 674 ret = -EBUSY; 675 goto unlock_out; 676 } 677 678 err = set_init_regions(ctx, kbuf, ret); 679 if (err) 680 ret = err; 681 682 unlock_out: 683 mutex_unlock(&ctx->kdamond_lock); 684 kfree(kbuf); 685 return ret; 686 } 687 688 static ssize_t dbgfs_kdamond_pid_read(struct file *file, 689 char __user *buf, size_t count, loff_t *ppos) 690 { 691 struct damon_ctx *ctx = file->private_data; 692 char *kbuf; 693 ssize_t len; 694 695 kbuf = kmalloc(count, GFP_KERNEL | __GFP_NOWARN); 696 if (!kbuf) 697 return -ENOMEM; 698 699 mutex_lock(&ctx->kdamond_lock); 700 if (ctx->kdamond) 701 len = scnprintf(kbuf, count, "%d\n", ctx->kdamond->pid); 702 else 703 len = scnprintf(kbuf, count, "none\n"); 704 mutex_unlock(&ctx->kdamond_lock); 705 if (!len) 706 goto out; 707 len = simple_read_from_buffer(buf, count, ppos, kbuf, len); 708 709 out: 710 kfree(kbuf); 711 return len; 712 } 713 714 static int damon_dbgfs_open(struct inode *inode, struct file *file) 715 { 716 file->private_data = inode->i_private; 717 718 return nonseekable_open(inode, file); 719 } 720 721 static const struct file_operations attrs_fops = { 722 .open = damon_dbgfs_open, 723 .read = dbgfs_attrs_read, 724 .write = dbgfs_attrs_write, 725 }; 726 727 static const struct file_operations schemes_fops = { 728 .open = damon_dbgfs_open, 729 .read = dbgfs_schemes_read, 730 .write = dbgfs_schemes_write, 731 }; 732 733 static const struct file_operations target_ids_fops = { 734 .open = damon_dbgfs_open, 735 .read = dbgfs_target_ids_read, 736 .write = dbgfs_target_ids_write, 737 }; 738 739 static const struct file_operations init_regions_fops = { 740 .open = damon_dbgfs_open, 741 .read = dbgfs_init_regions_read, 742 .write = dbgfs_init_regions_write, 743 }; 744 745 static const struct file_operations kdamond_pid_fops = { 746 .open = damon_dbgfs_open, 747 .read = dbgfs_kdamond_pid_read, 748 }; 749 750 static void dbgfs_fill_ctx_dir(struct dentry *dir, struct damon_ctx *ctx) 751 { 752 const char * const file_names[] = {"attrs", "schemes", "target_ids", 753 "init_regions", "kdamond_pid"}; 754 const struct file_operations *fops[] = {&attrs_fops, &schemes_fops, 755 &target_ids_fops, &init_regions_fops, &kdamond_pid_fops}; 756 int i; 757 758 for (i = 0; i < ARRAY_SIZE(file_names); i++) 759 debugfs_create_file(file_names[i], 0600, dir, ctx, fops[i]); 760 } 761 762 static void dbgfs_before_terminate(struct damon_ctx *ctx) 763 { 764 struct damon_target *t, *next; 765 766 if (!damon_target_has_pid(ctx)) 767 return; 768 769 mutex_lock(&ctx->kdamond_lock); 770 damon_for_each_target_safe(t, next, ctx) { 771 put_pid(t->pid); 772 damon_destroy_target(t); 773 } 774 mutex_unlock(&ctx->kdamond_lock); 775 } 776 777 static struct damon_ctx *dbgfs_new_ctx(void) 778 { 779 struct damon_ctx *ctx; 780 781 ctx = damon_new_ctx(); 782 if (!ctx) 783 return NULL; 784 785 if (damon_select_ops(ctx, DAMON_OPS_VADDR) && 786 damon_select_ops(ctx, DAMON_OPS_PADDR)) { 787 damon_destroy_ctx(ctx); 788 return NULL; 789 } 790 ctx->callback.before_terminate = dbgfs_before_terminate; 791 return ctx; 792 } 793 794 static void dbgfs_destroy_ctx(struct damon_ctx *ctx) 795 { 796 damon_destroy_ctx(ctx); 797 } 798 799 /* 800 * Make a context of @name and create a debugfs directory for it. 801 * 802 * This function should be called while holding damon_dbgfs_lock. 803 * 804 * Returns 0 on success, negative error code otherwise. 805 */ 806 static int dbgfs_mk_context(char *name) 807 { 808 struct dentry *root, **new_dirs, *new_dir; 809 struct damon_ctx **new_ctxs, *new_ctx; 810 811 if (damon_nr_running_ctxs()) 812 return -EBUSY; 813 814 new_ctxs = krealloc(dbgfs_ctxs, sizeof(*dbgfs_ctxs) * 815 (dbgfs_nr_ctxs + 1), GFP_KERNEL); 816 if (!new_ctxs) 817 return -ENOMEM; 818 dbgfs_ctxs = new_ctxs; 819 820 new_dirs = krealloc(dbgfs_dirs, sizeof(*dbgfs_dirs) * 821 (dbgfs_nr_ctxs + 1), GFP_KERNEL); 822 if (!new_dirs) 823 return -ENOMEM; 824 dbgfs_dirs = new_dirs; 825 826 root = dbgfs_dirs[0]; 827 if (!root) 828 return -ENOENT; 829 830 new_dir = debugfs_create_dir(name, root); 831 /* Below check is required for a potential duplicated name case */ 832 if (IS_ERR(new_dir)) 833 return PTR_ERR(new_dir); 834 dbgfs_dirs[dbgfs_nr_ctxs] = new_dir; 835 836 new_ctx = dbgfs_new_ctx(); 837 if (!new_ctx) { 838 debugfs_remove(new_dir); 839 dbgfs_dirs[dbgfs_nr_ctxs] = NULL; 840 return -ENOMEM; 841 } 842 843 dbgfs_ctxs[dbgfs_nr_ctxs] = new_ctx; 844 dbgfs_fill_ctx_dir(dbgfs_dirs[dbgfs_nr_ctxs], 845 dbgfs_ctxs[dbgfs_nr_ctxs]); 846 dbgfs_nr_ctxs++; 847 848 return 0; 849 } 850 851 static ssize_t dbgfs_mk_context_write(struct file *file, 852 const char __user *buf, size_t count, loff_t *ppos) 853 { 854 char *kbuf; 855 char *ctx_name; 856 ssize_t ret; 857 858 kbuf = user_input_str(buf, count, ppos); 859 if (IS_ERR(kbuf)) 860 return PTR_ERR(kbuf); 861 ctx_name = kmalloc(count + 1, GFP_KERNEL); 862 if (!ctx_name) { 863 kfree(kbuf); 864 return -ENOMEM; 865 } 866 867 /* Trim white space */ 868 if (sscanf(kbuf, "%s", ctx_name) != 1) { 869 ret = -EINVAL; 870 goto out; 871 } 872 873 mutex_lock(&damon_dbgfs_lock); 874 ret = dbgfs_mk_context(ctx_name); 875 if (!ret) 876 ret = count; 877 mutex_unlock(&damon_dbgfs_lock); 878 879 out: 880 kfree(kbuf); 881 kfree(ctx_name); 882 return ret; 883 } 884 885 /* 886 * Remove a context of @name and its debugfs directory. 887 * 888 * This function should be called while holding damon_dbgfs_lock. 889 * 890 * Return 0 on success, negative error code otherwise. 891 */ 892 static int dbgfs_rm_context(char *name) 893 { 894 struct dentry *root, *dir, **new_dirs; 895 struct damon_ctx **new_ctxs; 896 int i, j; 897 int ret = 0; 898 899 if (damon_nr_running_ctxs()) 900 return -EBUSY; 901 902 root = dbgfs_dirs[0]; 903 if (!root) 904 return -ENOENT; 905 906 dir = debugfs_lookup(name, root); 907 if (!dir) 908 return -ENOENT; 909 910 new_dirs = kmalloc_array(dbgfs_nr_ctxs - 1, sizeof(*dbgfs_dirs), 911 GFP_KERNEL); 912 if (!new_dirs) { 913 ret = -ENOMEM; 914 goto out_dput; 915 } 916 917 new_ctxs = kmalloc_array(dbgfs_nr_ctxs - 1, sizeof(*dbgfs_ctxs), 918 GFP_KERNEL); 919 if (!new_ctxs) { 920 ret = -ENOMEM; 921 goto out_new_dirs; 922 } 923 924 for (i = 0, j = 0; i < dbgfs_nr_ctxs; i++) { 925 if (dbgfs_dirs[i] == dir) { 926 debugfs_remove(dbgfs_dirs[i]); 927 dbgfs_destroy_ctx(dbgfs_ctxs[i]); 928 continue; 929 } 930 new_dirs[j] = dbgfs_dirs[i]; 931 new_ctxs[j++] = dbgfs_ctxs[i]; 932 } 933 934 kfree(dbgfs_dirs); 935 kfree(dbgfs_ctxs); 936 937 dbgfs_dirs = new_dirs; 938 dbgfs_ctxs = new_ctxs; 939 dbgfs_nr_ctxs--; 940 941 goto out_dput; 942 943 out_new_dirs: 944 kfree(new_dirs); 945 out_dput: 946 dput(dir); 947 return ret; 948 } 949 950 static ssize_t dbgfs_rm_context_write(struct file *file, 951 const char __user *buf, size_t count, loff_t *ppos) 952 { 953 char *kbuf; 954 ssize_t ret; 955 char *ctx_name; 956 957 kbuf = user_input_str(buf, count, ppos); 958 if (IS_ERR(kbuf)) 959 return PTR_ERR(kbuf); 960 ctx_name = kmalloc(count + 1, GFP_KERNEL); 961 if (!ctx_name) { 962 kfree(kbuf); 963 return -ENOMEM; 964 } 965 966 /* Trim white space */ 967 if (sscanf(kbuf, "%s", ctx_name) != 1) { 968 ret = -EINVAL; 969 goto out; 970 } 971 972 mutex_lock(&damon_dbgfs_lock); 973 ret = dbgfs_rm_context(ctx_name); 974 if (!ret) 975 ret = count; 976 mutex_unlock(&damon_dbgfs_lock); 977 978 out: 979 kfree(kbuf); 980 kfree(ctx_name); 981 return ret; 982 } 983 984 static ssize_t dbgfs_monitor_on_read(struct file *file, 985 char __user *buf, size_t count, loff_t *ppos) 986 { 987 char monitor_on_buf[5]; 988 bool monitor_on = damon_nr_running_ctxs() != 0; 989 int len; 990 991 len = scnprintf(monitor_on_buf, 5, monitor_on ? "on\n" : "off\n"); 992 993 return simple_read_from_buffer(buf, count, ppos, monitor_on_buf, len); 994 } 995 996 static ssize_t dbgfs_monitor_on_write(struct file *file, 997 const char __user *buf, size_t count, loff_t *ppos) 998 { 999 ssize_t ret; 1000 char *kbuf; 1001 1002 kbuf = user_input_str(buf, count, ppos); 1003 if (IS_ERR(kbuf)) 1004 return PTR_ERR(kbuf); 1005 1006 /* Remove white space */ 1007 if (sscanf(kbuf, "%s", kbuf) != 1) { 1008 kfree(kbuf); 1009 return -EINVAL; 1010 } 1011 1012 mutex_lock(&damon_dbgfs_lock); 1013 if (!strncmp(kbuf, "on", count)) { 1014 int i; 1015 1016 for (i = 0; i < dbgfs_nr_ctxs; i++) { 1017 if (damon_targets_empty(dbgfs_ctxs[i])) { 1018 kfree(kbuf); 1019 mutex_unlock(&damon_dbgfs_lock); 1020 return -EINVAL; 1021 } 1022 } 1023 ret = damon_start(dbgfs_ctxs, dbgfs_nr_ctxs, true); 1024 } else if (!strncmp(kbuf, "off", count)) { 1025 ret = damon_stop(dbgfs_ctxs, dbgfs_nr_ctxs); 1026 } else { 1027 ret = -EINVAL; 1028 } 1029 mutex_unlock(&damon_dbgfs_lock); 1030 1031 if (!ret) 1032 ret = count; 1033 kfree(kbuf); 1034 return ret; 1035 } 1036 1037 static const struct file_operations mk_contexts_fops = { 1038 .write = dbgfs_mk_context_write, 1039 }; 1040 1041 static const struct file_operations rm_contexts_fops = { 1042 .write = dbgfs_rm_context_write, 1043 }; 1044 1045 static const struct file_operations monitor_on_fops = { 1046 .read = dbgfs_monitor_on_read, 1047 .write = dbgfs_monitor_on_write, 1048 }; 1049 1050 static int __init __damon_dbgfs_init(void) 1051 { 1052 struct dentry *dbgfs_root; 1053 const char * const file_names[] = {"mk_contexts", "rm_contexts", 1054 "monitor_on"}; 1055 const struct file_operations *fops[] = {&mk_contexts_fops, 1056 &rm_contexts_fops, &monitor_on_fops}; 1057 int i; 1058 1059 dbgfs_root = debugfs_create_dir("damon", NULL); 1060 1061 for (i = 0; i < ARRAY_SIZE(file_names); i++) 1062 debugfs_create_file(file_names[i], 0600, dbgfs_root, NULL, 1063 fops[i]); 1064 dbgfs_fill_ctx_dir(dbgfs_root, dbgfs_ctxs[0]); 1065 1066 dbgfs_dirs = kmalloc(sizeof(dbgfs_root), GFP_KERNEL); 1067 if (!dbgfs_dirs) { 1068 debugfs_remove(dbgfs_root); 1069 return -ENOMEM; 1070 } 1071 dbgfs_dirs[0] = dbgfs_root; 1072 1073 return 0; 1074 } 1075 1076 /* 1077 * Functions for the initialization 1078 */ 1079 1080 static int __init damon_dbgfs_init(void) 1081 { 1082 int rc = -ENOMEM; 1083 1084 mutex_lock(&damon_dbgfs_lock); 1085 dbgfs_ctxs = kmalloc(sizeof(*dbgfs_ctxs), GFP_KERNEL); 1086 if (!dbgfs_ctxs) 1087 goto out; 1088 dbgfs_ctxs[0] = dbgfs_new_ctx(); 1089 if (!dbgfs_ctxs[0]) { 1090 kfree(dbgfs_ctxs); 1091 goto out; 1092 } 1093 dbgfs_nr_ctxs = 1; 1094 1095 rc = __damon_dbgfs_init(); 1096 if (rc) { 1097 kfree(dbgfs_ctxs[0]); 1098 kfree(dbgfs_ctxs); 1099 pr_err("%s: dbgfs init failed\n", __func__); 1100 } 1101 1102 out: 1103 mutex_unlock(&damon_dbgfs_lock); 1104 return rc; 1105 } 1106 1107 module_init(damon_dbgfs_init); 1108 1109 #include "dbgfs-test.h" 1110