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