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