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