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