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