taskstats.c (16155B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * taskstats.c - Export per-task statistics to userland 4 * 5 * Copyright (C) Shailabh Nagar, IBM Corp. 2006 6 * (C) Balbir Singh, IBM Corp. 2006 7 */ 8 9#include <linux/kernel.h> 10#include <linux/taskstats_kern.h> 11#include <linux/tsacct_kern.h> 12#include <linux/acct.h> 13#include <linux/delayacct.h> 14#include <linux/cpumask.h> 15#include <linux/percpu.h> 16#include <linux/slab.h> 17#include <linux/cgroupstats.h> 18#include <linux/cgroup.h> 19#include <linux/fs.h> 20#include <linux/file.h> 21#include <linux/pid_namespace.h> 22#include <net/genetlink.h> 23#include <linux/atomic.h> 24#include <linux/sched/cputime.h> 25 26/* 27 * Maximum length of a cpumask that can be specified in 28 * the TASKSTATS_CMD_ATTR_REGISTER/DEREGISTER_CPUMASK attribute 29 */ 30#define TASKSTATS_CPUMASK_MAXLEN (100+6*NR_CPUS) 31 32static DEFINE_PER_CPU(__u32, taskstats_seqnum); 33static int family_registered; 34struct kmem_cache *taskstats_cache; 35 36static struct genl_family family; 37 38static const struct nla_policy taskstats_cmd_get_policy[] = { 39 [TASKSTATS_CMD_ATTR_PID] = { .type = NLA_U32 }, 40 [TASKSTATS_CMD_ATTR_TGID] = { .type = NLA_U32 }, 41 [TASKSTATS_CMD_ATTR_REGISTER_CPUMASK] = { .type = NLA_STRING }, 42 [TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK] = { .type = NLA_STRING },}; 43 44static const struct nla_policy cgroupstats_cmd_get_policy[] = { 45 [CGROUPSTATS_CMD_ATTR_FD] = { .type = NLA_U32 }, 46}; 47 48struct listener { 49 struct list_head list; 50 pid_t pid; 51 char valid; 52}; 53 54struct listener_list { 55 struct rw_semaphore sem; 56 struct list_head list; 57}; 58static DEFINE_PER_CPU(struct listener_list, listener_array); 59 60enum actions { 61 REGISTER, 62 DEREGISTER, 63 CPU_DONT_CARE 64}; 65 66static int prepare_reply(struct genl_info *info, u8 cmd, struct sk_buff **skbp, 67 size_t size) 68{ 69 struct sk_buff *skb; 70 void *reply; 71 72 /* 73 * If new attributes are added, please revisit this allocation 74 */ 75 skb = genlmsg_new(size, GFP_KERNEL); 76 if (!skb) 77 return -ENOMEM; 78 79 if (!info) { 80 int seq = this_cpu_inc_return(taskstats_seqnum) - 1; 81 82 reply = genlmsg_put(skb, 0, seq, &family, 0, cmd); 83 } else 84 reply = genlmsg_put_reply(skb, info, &family, 0, cmd); 85 if (reply == NULL) { 86 nlmsg_free(skb); 87 return -EINVAL; 88 } 89 90 *skbp = skb; 91 return 0; 92} 93 94/* 95 * Send taskstats data in @skb to listener with nl_pid @pid 96 */ 97static int send_reply(struct sk_buff *skb, struct genl_info *info) 98{ 99 struct genlmsghdr *genlhdr = nlmsg_data(nlmsg_hdr(skb)); 100 void *reply = genlmsg_data(genlhdr); 101 102 genlmsg_end(skb, reply); 103 104 return genlmsg_reply(skb, info); 105} 106 107/* 108 * Send taskstats data in @skb to listeners registered for @cpu's exit data 109 */ 110static void send_cpu_listeners(struct sk_buff *skb, 111 struct listener_list *listeners) 112{ 113 struct genlmsghdr *genlhdr = nlmsg_data(nlmsg_hdr(skb)); 114 struct listener *s, *tmp; 115 struct sk_buff *skb_next, *skb_cur = skb; 116 void *reply = genlmsg_data(genlhdr); 117 int delcount = 0; 118 119 genlmsg_end(skb, reply); 120 121 down_read(&listeners->sem); 122 list_for_each_entry(s, &listeners->list, list) { 123 int rc; 124 125 skb_next = NULL; 126 if (!list_is_last(&s->list, &listeners->list)) { 127 skb_next = skb_clone(skb_cur, GFP_KERNEL); 128 if (!skb_next) 129 break; 130 } 131 rc = genlmsg_unicast(&init_net, skb_cur, s->pid); 132 if (rc == -ECONNREFUSED) { 133 s->valid = 0; 134 delcount++; 135 } 136 skb_cur = skb_next; 137 } 138 up_read(&listeners->sem); 139 140 if (skb_cur) 141 nlmsg_free(skb_cur); 142 143 if (!delcount) 144 return; 145 146 /* Delete invalidated entries */ 147 down_write(&listeners->sem); 148 list_for_each_entry_safe(s, tmp, &listeners->list, list) { 149 if (!s->valid) { 150 list_del(&s->list); 151 kfree(s); 152 } 153 } 154 up_write(&listeners->sem); 155} 156 157static void exe_add_tsk(struct taskstats *stats, struct task_struct *tsk) 158{ 159 /* No idea if I'm allowed to access that here, now. */ 160 struct file *exe_file = get_task_exe_file(tsk); 161 162 if (exe_file) { 163 /* Following cp_new_stat64() in stat.c . */ 164 stats->ac_exe_dev = 165 huge_encode_dev(exe_file->f_inode->i_sb->s_dev); 166 stats->ac_exe_inode = exe_file->f_inode->i_ino; 167 fput(exe_file); 168 } else { 169 stats->ac_exe_dev = 0; 170 stats->ac_exe_inode = 0; 171 } 172} 173 174static void fill_stats(struct user_namespace *user_ns, 175 struct pid_namespace *pid_ns, 176 struct task_struct *tsk, struct taskstats *stats) 177{ 178 memset(stats, 0, sizeof(*stats)); 179 /* 180 * Each accounting subsystem adds calls to its functions to 181 * fill in relevant parts of struct taskstsats as follows 182 * 183 * per-task-foo(stats, tsk); 184 */ 185 186 delayacct_add_tsk(stats, tsk); 187 188 /* fill in basic acct fields */ 189 stats->version = TASKSTATS_VERSION; 190 stats->nvcsw = tsk->nvcsw; 191 stats->nivcsw = tsk->nivcsw; 192 bacct_add_tsk(user_ns, pid_ns, stats, tsk); 193 194 /* fill in extended acct fields */ 195 xacct_add_tsk(stats, tsk); 196 197 /* add executable info */ 198 exe_add_tsk(stats, tsk); 199} 200 201static int fill_stats_for_pid(pid_t pid, struct taskstats *stats) 202{ 203 struct task_struct *tsk; 204 205 tsk = find_get_task_by_vpid(pid); 206 if (!tsk) 207 return -ESRCH; 208 fill_stats(current_user_ns(), task_active_pid_ns(current), tsk, stats); 209 put_task_struct(tsk); 210 return 0; 211} 212 213static int fill_stats_for_tgid(pid_t tgid, struct taskstats *stats) 214{ 215 struct task_struct *tsk, *first; 216 unsigned long flags; 217 int rc = -ESRCH; 218 u64 delta, utime, stime; 219 u64 start_time; 220 221 /* 222 * Add additional stats from live tasks except zombie thread group 223 * leaders who are already counted with the dead tasks 224 */ 225 rcu_read_lock(); 226 first = find_task_by_vpid(tgid); 227 228 if (!first || !lock_task_sighand(first, &flags)) 229 goto out; 230 231 if (first->signal->stats) 232 memcpy(stats, first->signal->stats, sizeof(*stats)); 233 else 234 memset(stats, 0, sizeof(*stats)); 235 236 tsk = first; 237 start_time = ktime_get_ns(); 238 do { 239 if (tsk->exit_state) 240 continue; 241 /* 242 * Accounting subsystem can call its functions here to 243 * fill in relevant parts of struct taskstsats as follows 244 * 245 * per-task-foo(stats, tsk); 246 */ 247 delayacct_add_tsk(stats, tsk); 248 249 /* calculate task elapsed time in nsec */ 250 delta = start_time - tsk->start_time; 251 /* Convert to micro seconds */ 252 do_div(delta, NSEC_PER_USEC); 253 stats->ac_etime += delta; 254 255 task_cputime(tsk, &utime, &stime); 256 stats->ac_utime += div_u64(utime, NSEC_PER_USEC); 257 stats->ac_stime += div_u64(stime, NSEC_PER_USEC); 258 259 stats->nvcsw += tsk->nvcsw; 260 stats->nivcsw += tsk->nivcsw; 261 } while_each_thread(first, tsk); 262 263 unlock_task_sighand(first, &flags); 264 rc = 0; 265out: 266 rcu_read_unlock(); 267 268 stats->version = TASKSTATS_VERSION; 269 /* 270 * Accounting subsystems can also add calls here to modify 271 * fields of taskstats. 272 */ 273 return rc; 274} 275 276static void fill_tgid_exit(struct task_struct *tsk) 277{ 278 unsigned long flags; 279 280 spin_lock_irqsave(&tsk->sighand->siglock, flags); 281 if (!tsk->signal->stats) 282 goto ret; 283 284 /* 285 * Each accounting subsystem calls its functions here to 286 * accumalate its per-task stats for tsk, into the per-tgid structure 287 * 288 * per-task-foo(tsk->signal->stats, tsk); 289 */ 290 delayacct_add_tsk(tsk->signal->stats, tsk); 291ret: 292 spin_unlock_irqrestore(&tsk->sighand->siglock, flags); 293 return; 294} 295 296static int add_del_listener(pid_t pid, const struct cpumask *mask, int isadd) 297{ 298 struct listener_list *listeners; 299 struct listener *s, *tmp, *s2; 300 unsigned int cpu; 301 int ret = 0; 302 303 if (!cpumask_subset(mask, cpu_possible_mask)) 304 return -EINVAL; 305 306 if (current_user_ns() != &init_user_ns) 307 return -EINVAL; 308 309 if (task_active_pid_ns(current) != &init_pid_ns) 310 return -EINVAL; 311 312 if (isadd == REGISTER) { 313 for_each_cpu(cpu, mask) { 314 s = kmalloc_node(sizeof(struct listener), 315 GFP_KERNEL, cpu_to_node(cpu)); 316 if (!s) { 317 ret = -ENOMEM; 318 goto cleanup; 319 } 320 s->pid = pid; 321 s->valid = 1; 322 323 listeners = &per_cpu(listener_array, cpu); 324 down_write(&listeners->sem); 325 list_for_each_entry(s2, &listeners->list, list) { 326 if (s2->pid == pid && s2->valid) 327 goto exists; 328 } 329 list_add(&s->list, &listeners->list); 330 s = NULL; 331exists: 332 up_write(&listeners->sem); 333 kfree(s); /* nop if NULL */ 334 } 335 return 0; 336 } 337 338 /* Deregister or cleanup */ 339cleanup: 340 for_each_cpu(cpu, mask) { 341 listeners = &per_cpu(listener_array, cpu); 342 down_write(&listeners->sem); 343 list_for_each_entry_safe(s, tmp, &listeners->list, list) { 344 if (s->pid == pid) { 345 list_del(&s->list); 346 kfree(s); 347 break; 348 } 349 } 350 up_write(&listeners->sem); 351 } 352 return ret; 353} 354 355static int parse(struct nlattr *na, struct cpumask *mask) 356{ 357 char *data; 358 int len; 359 int ret; 360 361 if (na == NULL) 362 return 1; 363 len = nla_len(na); 364 if (len > TASKSTATS_CPUMASK_MAXLEN) 365 return -E2BIG; 366 if (len < 1) 367 return -EINVAL; 368 data = kmalloc(len, GFP_KERNEL); 369 if (!data) 370 return -ENOMEM; 371 nla_strscpy(data, na, len); 372 ret = cpulist_parse(data, mask); 373 kfree(data); 374 return ret; 375} 376 377static struct taskstats *mk_reply(struct sk_buff *skb, int type, u32 pid) 378{ 379 struct nlattr *na, *ret; 380 int aggr; 381 382 aggr = (type == TASKSTATS_TYPE_PID) 383 ? TASKSTATS_TYPE_AGGR_PID 384 : TASKSTATS_TYPE_AGGR_TGID; 385 386 na = nla_nest_start_noflag(skb, aggr); 387 if (!na) 388 goto err; 389 390 if (nla_put(skb, type, sizeof(pid), &pid) < 0) { 391 nla_nest_cancel(skb, na); 392 goto err; 393 } 394 ret = nla_reserve_64bit(skb, TASKSTATS_TYPE_STATS, 395 sizeof(struct taskstats), TASKSTATS_TYPE_NULL); 396 if (!ret) { 397 nla_nest_cancel(skb, na); 398 goto err; 399 } 400 nla_nest_end(skb, na); 401 402 return nla_data(ret); 403err: 404 return NULL; 405} 406 407static int cgroupstats_user_cmd(struct sk_buff *skb, struct genl_info *info) 408{ 409 int rc = 0; 410 struct sk_buff *rep_skb; 411 struct cgroupstats *stats; 412 struct nlattr *na; 413 size_t size; 414 u32 fd; 415 struct fd f; 416 417 na = info->attrs[CGROUPSTATS_CMD_ATTR_FD]; 418 if (!na) 419 return -EINVAL; 420 421 fd = nla_get_u32(info->attrs[CGROUPSTATS_CMD_ATTR_FD]); 422 f = fdget(fd); 423 if (!f.file) 424 return 0; 425 426 size = nla_total_size(sizeof(struct cgroupstats)); 427 428 rc = prepare_reply(info, CGROUPSTATS_CMD_NEW, &rep_skb, 429 size); 430 if (rc < 0) 431 goto err; 432 433 na = nla_reserve(rep_skb, CGROUPSTATS_TYPE_CGROUP_STATS, 434 sizeof(struct cgroupstats)); 435 if (na == NULL) { 436 nlmsg_free(rep_skb); 437 rc = -EMSGSIZE; 438 goto err; 439 } 440 441 stats = nla_data(na); 442 memset(stats, 0, sizeof(*stats)); 443 444 rc = cgroupstats_build(stats, f.file->f_path.dentry); 445 if (rc < 0) { 446 nlmsg_free(rep_skb); 447 goto err; 448 } 449 450 rc = send_reply(rep_skb, info); 451 452err: 453 fdput(f); 454 return rc; 455} 456 457static int cmd_attr_register_cpumask(struct genl_info *info) 458{ 459 cpumask_var_t mask; 460 int rc; 461 462 if (!alloc_cpumask_var(&mask, GFP_KERNEL)) 463 return -ENOMEM; 464 rc = parse(info->attrs[TASKSTATS_CMD_ATTR_REGISTER_CPUMASK], mask); 465 if (rc < 0) 466 goto out; 467 rc = add_del_listener(info->snd_portid, mask, REGISTER); 468out: 469 free_cpumask_var(mask); 470 return rc; 471} 472 473static int cmd_attr_deregister_cpumask(struct genl_info *info) 474{ 475 cpumask_var_t mask; 476 int rc; 477 478 if (!alloc_cpumask_var(&mask, GFP_KERNEL)) 479 return -ENOMEM; 480 rc = parse(info->attrs[TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK], mask); 481 if (rc < 0) 482 goto out; 483 rc = add_del_listener(info->snd_portid, mask, DEREGISTER); 484out: 485 free_cpumask_var(mask); 486 return rc; 487} 488 489static size_t taskstats_packet_size(void) 490{ 491 size_t size; 492 493 size = nla_total_size(sizeof(u32)) + 494 nla_total_size_64bit(sizeof(struct taskstats)) + 495 nla_total_size(0); 496 497 return size; 498} 499 500static int cmd_attr_pid(struct genl_info *info) 501{ 502 struct taskstats *stats; 503 struct sk_buff *rep_skb; 504 size_t size; 505 u32 pid; 506 int rc; 507 508 size = taskstats_packet_size(); 509 510 rc = prepare_reply(info, TASKSTATS_CMD_NEW, &rep_skb, size); 511 if (rc < 0) 512 return rc; 513 514 rc = -EINVAL; 515 pid = nla_get_u32(info->attrs[TASKSTATS_CMD_ATTR_PID]); 516 stats = mk_reply(rep_skb, TASKSTATS_TYPE_PID, pid); 517 if (!stats) 518 goto err; 519 520 rc = fill_stats_for_pid(pid, stats); 521 if (rc < 0) 522 goto err; 523 return send_reply(rep_skb, info); 524err: 525 nlmsg_free(rep_skb); 526 return rc; 527} 528 529static int cmd_attr_tgid(struct genl_info *info) 530{ 531 struct taskstats *stats; 532 struct sk_buff *rep_skb; 533 size_t size; 534 u32 tgid; 535 int rc; 536 537 size = taskstats_packet_size(); 538 539 rc = prepare_reply(info, TASKSTATS_CMD_NEW, &rep_skb, size); 540 if (rc < 0) 541 return rc; 542 543 rc = -EINVAL; 544 tgid = nla_get_u32(info->attrs[TASKSTATS_CMD_ATTR_TGID]); 545 stats = mk_reply(rep_skb, TASKSTATS_TYPE_TGID, tgid); 546 if (!stats) 547 goto err; 548 549 rc = fill_stats_for_tgid(tgid, stats); 550 if (rc < 0) 551 goto err; 552 return send_reply(rep_skb, info); 553err: 554 nlmsg_free(rep_skb); 555 return rc; 556} 557 558static int taskstats_user_cmd(struct sk_buff *skb, struct genl_info *info) 559{ 560 if (info->attrs[TASKSTATS_CMD_ATTR_REGISTER_CPUMASK]) 561 return cmd_attr_register_cpumask(info); 562 else if (info->attrs[TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK]) 563 return cmd_attr_deregister_cpumask(info); 564 else if (info->attrs[TASKSTATS_CMD_ATTR_PID]) 565 return cmd_attr_pid(info); 566 else if (info->attrs[TASKSTATS_CMD_ATTR_TGID]) 567 return cmd_attr_tgid(info); 568 else 569 return -EINVAL; 570} 571 572static struct taskstats *taskstats_tgid_alloc(struct task_struct *tsk) 573{ 574 struct signal_struct *sig = tsk->signal; 575 struct taskstats *stats_new, *stats; 576 577 /* Pairs with smp_store_release() below. */ 578 stats = smp_load_acquire(&sig->stats); 579 if (stats || thread_group_empty(tsk)) 580 return stats; 581 582 /* No problem if kmem_cache_zalloc() fails */ 583 stats_new = kmem_cache_zalloc(taskstats_cache, GFP_KERNEL); 584 585 spin_lock_irq(&tsk->sighand->siglock); 586 stats = sig->stats; 587 if (!stats) { 588 /* 589 * Pairs with smp_store_release() above and order the 590 * kmem_cache_zalloc(). 591 */ 592 smp_store_release(&sig->stats, stats_new); 593 stats = stats_new; 594 stats_new = NULL; 595 } 596 spin_unlock_irq(&tsk->sighand->siglock); 597 598 if (stats_new) 599 kmem_cache_free(taskstats_cache, stats_new); 600 601 return stats; 602} 603 604/* Send pid data out on exit */ 605void taskstats_exit(struct task_struct *tsk, int group_dead) 606{ 607 int rc; 608 struct listener_list *listeners; 609 struct taskstats *stats; 610 struct sk_buff *rep_skb; 611 size_t size; 612 int is_thread_group; 613 614 if (!family_registered) 615 return; 616 617 /* 618 * Size includes space for nested attributes 619 */ 620 size = taskstats_packet_size(); 621 622 is_thread_group = !!taskstats_tgid_alloc(tsk); 623 if (is_thread_group) { 624 /* PID + STATS + TGID + STATS */ 625 size = 2 * size; 626 /* fill the tsk->signal->stats structure */ 627 fill_tgid_exit(tsk); 628 } 629 630 listeners = raw_cpu_ptr(&listener_array); 631 if (list_empty(&listeners->list)) 632 return; 633 634 rc = prepare_reply(NULL, TASKSTATS_CMD_NEW, &rep_skb, size); 635 if (rc < 0) 636 return; 637 638 stats = mk_reply(rep_skb, TASKSTATS_TYPE_PID, 639 task_pid_nr_ns(tsk, &init_pid_ns)); 640 if (!stats) 641 goto err; 642 643 fill_stats(&init_user_ns, &init_pid_ns, tsk, stats); 644 if (group_dead) 645 stats->ac_flag |= AGROUP; 646 647 /* 648 * Doesn't matter if tsk is the leader or the last group member leaving 649 */ 650 if (!is_thread_group || !group_dead) 651 goto send; 652 653 stats = mk_reply(rep_skb, TASKSTATS_TYPE_TGID, 654 task_tgid_nr_ns(tsk, &init_pid_ns)); 655 if (!stats) 656 goto err; 657 658 memcpy(stats, tsk->signal->stats, sizeof(*stats)); 659 660send: 661 send_cpu_listeners(rep_skb, listeners); 662 return; 663err: 664 nlmsg_free(rep_skb); 665} 666 667static const struct genl_ops taskstats_ops[] = { 668 { 669 .cmd = TASKSTATS_CMD_GET, 670 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 671 .doit = taskstats_user_cmd, 672 .policy = taskstats_cmd_get_policy, 673 .maxattr = ARRAY_SIZE(taskstats_cmd_get_policy) - 1, 674 .flags = GENL_ADMIN_PERM, 675 }, 676 { 677 .cmd = CGROUPSTATS_CMD_GET, 678 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 679 .doit = cgroupstats_user_cmd, 680 .policy = cgroupstats_cmd_get_policy, 681 .maxattr = ARRAY_SIZE(cgroupstats_cmd_get_policy) - 1, 682 }, 683}; 684 685static struct genl_family family __ro_after_init = { 686 .name = TASKSTATS_GENL_NAME, 687 .version = TASKSTATS_GENL_VERSION, 688 .module = THIS_MODULE, 689 .ops = taskstats_ops, 690 .n_ops = ARRAY_SIZE(taskstats_ops), 691 .netnsok = true, 692}; 693 694/* Needed early in initialization */ 695void __init taskstats_init_early(void) 696{ 697 unsigned int i; 698 699 taskstats_cache = KMEM_CACHE(taskstats, SLAB_PANIC); 700 for_each_possible_cpu(i) { 701 INIT_LIST_HEAD(&(per_cpu(listener_array, i).list)); 702 init_rwsem(&(per_cpu(listener_array, i).sem)); 703 } 704} 705 706static int __init taskstats_init(void) 707{ 708 int rc; 709 710 rc = genl_register_family(&family); 711 if (rc) 712 return rc; 713 714 family_registered = 1; 715 pr_info("registered taskstats version %d\n", TASKSTATS_GENL_VERSION); 716 return 0; 717} 718 719/* 720 * late initcall ensures initialization of statistics collection 721 * mechanisms precedes initialization of the taskstats interface 722 */ 723late_initcall(taskstats_init);