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