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