1c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar/* 2c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar * taskstats.c - Export per-task statistics to userland 3c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar * 4c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar * Copyright (C) Shailabh Nagar, IBM Corp. 2006 5c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar * (C) Balbir Singh, IBM Corp. 2006 6c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar * 7c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar * This program is free software; you can redistribute it and/or modify 8c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar * it under the terms of the GNU General Public License as published by 9c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar * the Free Software Foundation; either version 2 of the License, or 10c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar * (at your option) any later version. 11c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar * 12c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar * This program is distributed in the hope that it will be useful, 13c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar * but WITHOUT ANY WARRANTY; without even the implied warranty of 14c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar * GNU General Public License for more details. 16c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar * 17c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar */ 18c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 19c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar#include <linux/kernel.h> 20c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar#include <linux/taskstats_kern.h> 21f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan#include <linux/tsacct_kern.h> 226f44993fe1d7b2b097f6ac60cd5835c6f5ca0874Shailabh Nagar#include <linux/delayacct.h> 23f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar#include <linux/cpumask.h> 24f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar#include <linux/percpu.h> 255a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 26846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singh#include <linux/cgroupstats.h> 27846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singh#include <linux/cgroup.h> 28846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singh#include <linux/fs.h> 29846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singh#include <linux/file.h> 304bd6e32acec66c55c6c1af4672f3216b2ac88e35Eric W. Biederman#include <linux/pid_namespace.h> 31c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar#include <net/genetlink.h> 3260063497a95e716c9a689af3be2687d261f115b4Arun Sharma#include <linux/atomic.h> 33c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 34f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar/* 35f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar * Maximum length of a cpumask that can be specified in 36f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar * the TASKSTATS_CMD_ATTR_REGISTER/DEREGISTER_CPUMASK attribute 37f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar */ 38f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar#define TASKSTATS_CPUMASK_MAXLEN (100+6*NR_CPUS) 39f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar 40b81f3ea92ba1fa676775677679889dc2a7f03c8bVegard Nossumstatic DEFINE_PER_CPU(__u32, taskstats_seqnum); 41c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagarstatic int family_registered; 42e18b890bb0881bbab6f4f1a6cd20d9c60d66b003Christoph Lameterstruct kmem_cache *taskstats_cache; 43c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 44c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagarstatic struct genl_family family = { 45c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar .id = GENL_ID_GENERATE, 46c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar .name = TASKSTATS_GENL_NAME, 47c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar .version = TASKSTATS_GENL_VERSION, 48c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar .maxattr = TASKSTATS_CMD_ATTR_MAX, 49c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar}; 50c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 51b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy taskstats_cmd_get_policy[TASKSTATS_CMD_ATTR_MAX+1] = { 52c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar [TASKSTATS_CMD_ATTR_PID] = { .type = NLA_U32 }, 53c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar [TASKSTATS_CMD_ATTR_TGID] = { .type = NLA_U32 }, 54f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar [TASKSTATS_CMD_ATTR_REGISTER_CPUMASK] = { .type = NLA_STRING }, 55f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar [TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK] = { .type = NLA_STRING },}; 56f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar 57b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy cgroupstats_cmd_get_policy[CGROUPSTATS_CMD_ATTR_MAX+1] = { 58846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singh [CGROUPSTATS_CMD_ATTR_FD] = { .type = NLA_U32 }, 59846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singh}; 60846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singh 61f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagarstruct listener { 62f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar struct list_head list; 63f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar pid_t pid; 64bb129994c3bff9c5e8df91f05d7e9b6402fbd83fShailabh Nagar char valid; 65c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar}; 66c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 67f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagarstruct listener_list { 68f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar struct rw_semaphore sem; 69f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar struct list_head list; 70f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar}; 71f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagarstatic DEFINE_PER_CPU(struct listener_list, listener_array); 72f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar 73f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagarenum actions { 74f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar REGISTER, 75f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar DEREGISTER, 76f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar CPU_DONT_CARE 77f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar}; 78c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 79c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagarstatic int prepare_reply(struct genl_info *info, u8 cmd, struct sk_buff **skbp, 8037167485302c8876cb0303af113696e88c2945aaOleg Nesterov size_t size) 81c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar{ 82c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar struct sk_buff *skb; 83c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar void *reply; 84c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 85c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar /* 86c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar * If new attributes are added, please revisit this allocation 87c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar */ 883dabc7157859e706770c825aa229f8943db4e0e1Thomas Graf skb = genlmsg_new(size, GFP_KERNEL); 89c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar if (!skb) 90c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar return -ENOMEM; 91c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 92c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar if (!info) { 93cd85fc58cd71bf6b89612efafb9a84e655ed7d66Christoph Lameter int seq = this_cpu_inc_return(taskstats_seqnum) - 1; 94c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 9517c157c889f4b07258af6bfec9e4e9dcf3c00178Thomas Graf reply = genlmsg_put(skb, 0, seq, &family, 0, cmd); 96c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar } else 9717c157c889f4b07258af6bfec9e4e9dcf3c00178Thomas Graf reply = genlmsg_put_reply(skb, info, &family, 0, cmd); 98c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar if (reply == NULL) { 99c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar nlmsg_free(skb); 100c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar return -EINVAL; 101c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar } 102c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 103c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar *skbp = skb; 104c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar return 0; 105c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar} 106c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 107f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar/* 108f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar * Send taskstats data in @skb to listener with nl_pid @pid 109f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar */ 110134e63756d5f3d0f7604dfcca847b09d1b14fd66Johannes Bergstatic int send_reply(struct sk_buff *skb, struct genl_info *info) 111c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar{ 112b529ccf2799c14346d1518e9bdf1f88f03643e99Arnaldo Carvalho de Melo struct genlmsghdr *genlhdr = nlmsg_data(nlmsg_hdr(skb)); 113f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar void *reply = genlmsg_data(genlhdr); 114c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar int rc; 115c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 116c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar rc = genlmsg_end(skb, reply); 117c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar if (rc < 0) { 118c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar nlmsg_free(skb); 119c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar return rc; 120c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar } 121c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 122134e63756d5f3d0f7604dfcca847b09d1b14fd66Johannes Berg return genlmsg_reply(skb, info); 123c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar} 124c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 125f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar/* 126f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar * Send taskstats data in @skb to listeners registered for @cpu's exit data 127f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar */ 128115085ea0794c0f339be8f9d25505c7f9861d824Oleg Nesterovstatic void send_cpu_listeners(struct sk_buff *skb, 129115085ea0794c0f339be8f9d25505c7f9861d824Oleg Nesterov struct listener_list *listeners) 130f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar{ 131b529ccf2799c14346d1518e9bdf1f88f03643e99Arnaldo Carvalho de Melo struct genlmsghdr *genlhdr = nlmsg_data(nlmsg_hdr(skb)); 132f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar struct listener *s, *tmp; 133f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar struct sk_buff *skb_next, *skb_cur = skb; 134f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar void *reply = genlmsg_data(genlhdr); 135d94a041519f3ab1ac023bf917619cd8c4a7d3c01Shailabh Nagar int rc, delcount = 0; 136f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar 137f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar rc = genlmsg_end(skb, reply); 138f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar if (rc < 0) { 139f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar nlmsg_free(skb); 140d94a041519f3ab1ac023bf917619cd8c4a7d3c01Shailabh Nagar return; 141f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar } 142f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar 143f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar rc = 0; 144bb129994c3bff9c5e8df91f05d7e9b6402fbd83fShailabh Nagar down_read(&listeners->sem); 145d94a041519f3ab1ac023bf917619cd8c4a7d3c01Shailabh Nagar list_for_each_entry(s, &listeners->list, list) { 146f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar skb_next = NULL; 147f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar if (!list_is_last(&s->list, &listeners->list)) { 148f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar skb_next = skb_clone(skb_cur, GFP_KERNEL); 149d94a041519f3ab1ac023bf917619cd8c4a7d3c01Shailabh Nagar if (!skb_next) 150f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar break; 151f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar } 152134e63756d5f3d0f7604dfcca847b09d1b14fd66Johannes Berg rc = genlmsg_unicast(&init_net, skb_cur, s->pid); 153d94a041519f3ab1ac023bf917619cd8c4a7d3c01Shailabh Nagar if (rc == -ECONNREFUSED) { 154bb129994c3bff9c5e8df91f05d7e9b6402fbd83fShailabh Nagar s->valid = 0; 155bb129994c3bff9c5e8df91f05d7e9b6402fbd83fShailabh Nagar delcount++; 156f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar } 157f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar skb_cur = skb_next; 158f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar } 159bb129994c3bff9c5e8df91f05d7e9b6402fbd83fShailabh Nagar up_read(&listeners->sem); 160f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar 161d94a041519f3ab1ac023bf917619cd8c4a7d3c01Shailabh Nagar if (skb_cur) 162d94a041519f3ab1ac023bf917619cd8c4a7d3c01Shailabh Nagar nlmsg_free(skb_cur); 163d94a041519f3ab1ac023bf917619cd8c4a7d3c01Shailabh Nagar 164bb129994c3bff9c5e8df91f05d7e9b6402fbd83fShailabh Nagar if (!delcount) 165d94a041519f3ab1ac023bf917619cd8c4a7d3c01Shailabh Nagar return; 166bb129994c3bff9c5e8df91f05d7e9b6402fbd83fShailabh Nagar 167bb129994c3bff9c5e8df91f05d7e9b6402fbd83fShailabh Nagar /* Delete invalidated entries */ 168bb129994c3bff9c5e8df91f05d7e9b6402fbd83fShailabh Nagar down_write(&listeners->sem); 169bb129994c3bff9c5e8df91f05d7e9b6402fbd83fShailabh Nagar list_for_each_entry_safe(s, tmp, &listeners->list, list) { 170bb129994c3bff9c5e8df91f05d7e9b6402fbd83fShailabh Nagar if (!s->valid) { 171bb129994c3bff9c5e8df91f05d7e9b6402fbd83fShailabh Nagar list_del(&s->list); 172bb129994c3bff9c5e8df91f05d7e9b6402fbd83fShailabh Nagar kfree(s); 173bb129994c3bff9c5e8df91f05d7e9b6402fbd83fShailabh Nagar } 174bb129994c3bff9c5e8df91f05d7e9b6402fbd83fShailabh Nagar } 175bb129994c3bff9c5e8df91f05d7e9b6402fbd83fShailabh Nagar up_write(&listeners->sem); 176f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar} 177f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar 1784bd6e32acec66c55c6c1af4672f3216b2ac88e35Eric W. Biedermanstatic void fill_stats(struct user_namespace *user_ns, 1794bd6e32acec66c55c6c1af4672f3216b2ac88e35Eric W. Biederman struct pid_namespace *pid_ns, 1804bd6e32acec66c55c6c1af4672f3216b2ac88e35Eric W. Biederman struct task_struct *tsk, struct taskstats *stats) 181c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar{ 18251de4d90852ba4cfa5743594ec4a7f158b52dc43Oleg Nesterov memset(stats, 0, sizeof(*stats)); 183c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar /* 184c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar * Each accounting subsystem adds calls to its functions to 185c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar * fill in relevant parts of struct taskstsats as follows 186c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar * 1877d94dddd438bcba97db44f120da39bb001b5249fShailabh Nagar * per-task-foo(stats, tsk); 188c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar */ 189c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 1907d94dddd438bcba97db44f120da39bb001b5249fShailabh Nagar delayacct_add_tsk(stats, tsk); 191f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan 192f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan /* fill in basic acct fields */ 1936f44993fe1d7b2b097f6ac60cd5835c6f5ca0874Shailabh Nagar stats->version = TASKSTATS_VERSION; 194b663a79c191508f27cd885224b592a878c0ba0f6Maxim Uvarov stats->nvcsw = tsk->nvcsw; 195b663a79c191508f27cd885224b592a878c0ba0f6Maxim Uvarov stats->nivcsw = tsk->nivcsw; 1964bd6e32acec66c55c6c1af4672f3216b2ac88e35Eric W. Biederman bacct_add_tsk(user_ns, pid_ns, stats, tsk); 1976f44993fe1d7b2b097f6ac60cd5835c6f5ca0874Shailabh Nagar 1989acc1853519a0473620d424105f9d49ea5b4e62eJay Lan /* fill in extended acct fields */ 1999acc1853519a0473620d424105f9d49ea5b4e62eJay Lan xacct_add_tsk(stats, tsk); 2003d9e0cf1fe007b88db55d43dfdb6839e1a029ca5Michael Holzheu} 2019acc1853519a0473620d424105f9d49ea5b4e62eJay Lan 2023d9e0cf1fe007b88db55d43dfdb6839e1a029ca5Michael Holzheustatic int fill_stats_for_pid(pid_t pid, struct taskstats *stats) 2033d9e0cf1fe007b88db55d43dfdb6839e1a029ca5Michael Holzheu{ 2043d9e0cf1fe007b88db55d43dfdb6839e1a029ca5Michael Holzheu struct task_struct *tsk; 205c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 2063d9e0cf1fe007b88db55d43dfdb6839e1a029ca5Michael Holzheu rcu_read_lock(); 2073d9e0cf1fe007b88db55d43dfdb6839e1a029ca5Michael Holzheu tsk = find_task_by_vpid(pid); 2083d9e0cf1fe007b88db55d43dfdb6839e1a029ca5Michael Holzheu if (tsk) 2093d9e0cf1fe007b88db55d43dfdb6839e1a029ca5Michael Holzheu get_task_struct(tsk); 2103d9e0cf1fe007b88db55d43dfdb6839e1a029ca5Michael Holzheu rcu_read_unlock(); 2113d9e0cf1fe007b88db55d43dfdb6839e1a029ca5Michael Holzheu if (!tsk) 2123d9e0cf1fe007b88db55d43dfdb6839e1a029ca5Michael Holzheu return -ESRCH; 2134bd6e32acec66c55c6c1af4672f3216b2ac88e35Eric W. Biederman fill_stats(current_user_ns(), task_active_pid_ns(current), tsk, stats); 2143d9e0cf1fe007b88db55d43dfdb6839e1a029ca5Michael Holzheu put_task_struct(tsk); 2153d9e0cf1fe007b88db55d43dfdb6839e1a029ca5Michael Holzheu return 0; 216c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar} 217c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 2183d9e0cf1fe007b88db55d43dfdb6839e1a029ca5Michael Holzheustatic int fill_stats_for_tgid(pid_t tgid, struct taskstats *stats) 219c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar{ 2203d9e0cf1fe007b88db55d43dfdb6839e1a029ca5Michael Holzheu struct task_struct *tsk, *first; 221ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagar unsigned long flags; 222a98b6094261c0112e9c455c96995972181bff049Oleg Nesterov int rc = -ESRCH; 223c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 224ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagar /* 225ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagar * Add additional stats from live tasks except zombie thread group 226ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagar * leaders who are already counted with the dead tasks 227ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagar */ 228a98b6094261c0112e9c455c96995972181bff049Oleg Nesterov rcu_read_lock(); 2293d9e0cf1fe007b88db55d43dfdb6839e1a029ca5Michael Holzheu first = find_task_by_vpid(tgid); 230ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagar 231a98b6094261c0112e9c455c96995972181bff049Oleg Nesterov if (!first || !lock_task_sighand(first, &flags)) 232a98b6094261c0112e9c455c96995972181bff049Oleg Nesterov goto out; 233ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagar 234a98b6094261c0112e9c455c96995972181bff049Oleg Nesterov if (first->signal->stats) 235a98b6094261c0112e9c455c96995972181bff049Oleg Nesterov memcpy(stats, first->signal->stats, sizeof(*stats)); 23651de4d90852ba4cfa5743594ec4a7f158b52dc43Oleg Nesterov else 23751de4d90852ba4cfa5743594ec4a7f158b52dc43Oleg Nesterov memset(stats, 0, sizeof(*stats)); 238fca178c0c6e8d52a1875be36b070f30884ebfae9Oleg Nesterov 239a98b6094261c0112e9c455c96995972181bff049Oleg Nesterov tsk = first; 240c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar do { 241d7c3f5f231c60d7e6ada5770b536df2b3ec1bd08Oleg Nesterov if (tsk->exit_state) 242ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagar continue; 243c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar /* 244ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagar * Accounting subsystem can call its functions here to 245c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar * fill in relevant parts of struct taskstsats as follows 246c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar * 247ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagar * per-task-foo(stats, tsk); 248c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar */ 249ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagar delayacct_add_tsk(stats, tsk); 2506f44993fe1d7b2b097f6ac60cd5835c6f5ca0874Shailabh Nagar 251b663a79c191508f27cd885224b592a878c0ba0f6Maxim Uvarov stats->nvcsw += tsk->nvcsw; 252b663a79c191508f27cd885224b592a878c0ba0f6Maxim Uvarov stats->nivcsw += tsk->nivcsw; 253c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar } while_each_thread(first, tsk); 2546f44993fe1d7b2b097f6ac60cd5835c6f5ca0874Shailabh Nagar 255a98b6094261c0112e9c455c96995972181bff049Oleg Nesterov unlock_task_sighand(first, &flags); 256a98b6094261c0112e9c455c96995972181bff049Oleg Nesterov rc = 0; 257a98b6094261c0112e9c455c96995972181bff049Oleg Nesterovout: 258a98b6094261c0112e9c455c96995972181bff049Oleg Nesterov rcu_read_unlock(); 259a98b6094261c0112e9c455c96995972181bff049Oleg Nesterov 260a98b6094261c0112e9c455c96995972181bff049Oleg Nesterov stats->version = TASKSTATS_VERSION; 261c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar /* 2623a4fa0a25da81600ea0bcd75692ae8ca6050d165Robert P. J. Day * Accounting subsystems can also add calls here to modify 263ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagar * fields of taskstats. 264c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar */ 265a98b6094261c0112e9c455c96995972181bff049Oleg Nesterov return rc; 266ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagar} 267ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagar 268ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagarstatic void fill_tgid_exit(struct task_struct *tsk) 269ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagar{ 270ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagar unsigned long flags; 271ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagar 272b8534d7bd89df0cd41cd47bcd6733a05ea9a691aOleg Nesterov spin_lock_irqsave(&tsk->sighand->siglock, flags); 273ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagar if (!tsk->signal->stats) 274ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagar goto ret; 275ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagar 276ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagar /* 277ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagar * Each accounting subsystem calls its functions here to 278ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagar * accumalate its per-task stats for tsk, into the per-tgid structure 279ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagar * 280ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagar * per-task-foo(tsk->signal->stats, tsk); 281ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagar */ 282ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagar delayacct_add_tsk(tsk->signal->stats, tsk); 283ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagarret: 284b8534d7bd89df0cd41cd47bcd6733a05ea9a691aOleg Nesterov spin_unlock_irqrestore(&tsk->sighand->siglock, flags); 285ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagar return; 286c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar} 287c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 28841c7bb9588904eb060a95bcad47bd3804a1ece25Rusty Russellstatic int add_del_listener(pid_t pid, const struct cpumask *mask, int isadd) 289f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar{ 290f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar struct listener_list *listeners; 29126c4caea9d697043cc5a458b96411b86d7f6babdVasiliy Kulikov struct listener *s, *tmp, *s2; 292f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar unsigned int cpu; 2930d20633b041041ecda39ae562e62087acf0092f1Chen Gang int ret = 0; 294ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagar 29541c7bb9588904eb060a95bcad47bd3804a1ece25Rusty Russell if (!cpumask_subset(mask, cpu_possible_mask)) 296f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar return -EINVAL; 297f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar 2984bd6e32acec66c55c6c1af4672f3216b2ac88e35Eric W. Biederman if (current_user_ns() != &init_user_ns) 2994bd6e32acec66c55c6c1af4672f3216b2ac88e35Eric W. Biederman return -EINVAL; 3004bd6e32acec66c55c6c1af4672f3216b2ac88e35Eric W. Biederman 3014bd6e32acec66c55c6c1af4672f3216b2ac88e35Eric W. Biederman if (task_active_pid_ns(current) != &init_pid_ns) 3024bd6e32acec66c55c6c1af4672f3216b2ac88e35Eric W. Biederman return -EINVAL; 3034bd6e32acec66c55c6c1af4672f3216b2ac88e35Eric W. Biederman 304f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar if (isadd == REGISTER) { 30541c7bb9588904eb060a95bcad47bd3804a1ece25Rusty Russell for_each_cpu(cpu, mask) { 306dfc428b656c4693a2334a8d9865b430beddb562aOleg Nesterov s = kmalloc_node(sizeof(struct listener), 307dfc428b656c4693a2334a8d9865b430beddb562aOleg Nesterov GFP_KERNEL, cpu_to_node(cpu)); 3080d20633b041041ecda39ae562e62087acf0092f1Chen Gang if (!s) { 3090d20633b041041ecda39ae562e62087acf0092f1Chen Gang ret = -ENOMEM; 310f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar goto cleanup; 3110d20633b041041ecda39ae562e62087acf0092f1Chen Gang } 312f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar s->pid = pid; 313bb129994c3bff9c5e8df91f05d7e9b6402fbd83fShailabh Nagar s->valid = 1; 314f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar 315f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar listeners = &per_cpu(listener_array, cpu); 316f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar down_write(&listeners->sem); 317dfc428b656c4693a2334a8d9865b430beddb562aOleg Nesterov list_for_each_entry(s2, &listeners->list, list) { 318a7295898a1d2e501427f557111c2b4bdfc90b1edOleg Nesterov if (s2->pid == pid && s2->valid) 319dfc428b656c4693a2334a8d9865b430beddb562aOleg Nesterov goto exists; 32026c4caea9d697043cc5a458b96411b86d7f6babdVasiliy Kulikov } 321f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar list_add(&s->list, &listeners->list); 32226c4caea9d697043cc5a458b96411b86d7f6babdVasiliy Kulikov s = NULL; 323dfc428b656c4693a2334a8d9865b430beddb562aOleg Nesterovexists: 324f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar up_write(&listeners->sem); 325dfc428b656c4693a2334a8d9865b430beddb562aOleg Nesterov kfree(s); /* nop if NULL */ 326f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar } 327f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar return 0; 328f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar } 329f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar 330f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar /* Deregister or cleanup */ 331f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagarcleanup: 33241c7bb9588904eb060a95bcad47bd3804a1ece25Rusty Russell for_each_cpu(cpu, mask) { 333f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar listeners = &per_cpu(listener_array, cpu); 334f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar down_write(&listeners->sem); 335f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar list_for_each_entry_safe(s, tmp, &listeners->list, list) { 336f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar if (s->pid == pid) { 337f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar list_del(&s->list); 338f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar kfree(s); 339f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar break; 340f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar } 341f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar } 342f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar up_write(&listeners->sem); 343f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar } 3440d20633b041041ecda39ae562e62087acf0092f1Chen Gang return ret; 345f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar} 346f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar 34741c7bb9588904eb060a95bcad47bd3804a1ece25Rusty Russellstatic int parse(struct nlattr *na, struct cpumask *mask) 348f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar{ 349f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar char *data; 350f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar int len; 351f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar int ret; 352f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar 353f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar if (na == NULL) 354f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar return 1; 355f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar len = nla_len(na); 356f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar if (len > TASKSTATS_CPUMASK_MAXLEN) 357f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar return -E2BIG; 358f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar if (len < 1) 359f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar return -EINVAL; 360f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar data = kmalloc(len, GFP_KERNEL); 361f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar if (!data) 362f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar return -ENOMEM; 363f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar nla_strlcpy(data, na, len); 36429c0177e6a4ac094302bed54a1d4bbb6b740a9efRusty Russell ret = cpulist_parse(data, mask); 365f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar kfree(data); 366f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar return ret; 367f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar} 368f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar 3699ab020cf07e457a8b425bf5af17e704f90f86d8bJeff Mahoney#if defined(CONFIG_64BIT) && !defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) 3704be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney#define TASKSTATS_NEEDS_PADDING 1 3714be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney#endif 3724be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney 37351de4d90852ba4cfa5743594ec4a7f158b52dc43Oleg Nesterovstatic struct taskstats *mk_reply(struct sk_buff *skb, int type, u32 pid) 37468062b86fc0f480b806d270a8278709a5a41bb67Oleg Nesterov{ 37551de4d90852ba4cfa5743594ec4a7f158b52dc43Oleg Nesterov struct nlattr *na, *ret; 37668062b86fc0f480b806d270a8278709a5a41bb67Oleg Nesterov int aggr; 37768062b86fc0f480b806d270a8278709a5a41bb67Oleg Nesterov 37837167485302c8876cb0303af113696e88c2945aaOleg Nesterov aggr = (type == TASKSTATS_TYPE_PID) 37937167485302c8876cb0303af113696e88c2945aaOleg Nesterov ? TASKSTATS_TYPE_AGGR_PID 38037167485302c8876cb0303af113696e88c2945aaOleg Nesterov : TASKSTATS_TYPE_AGGR_TGID; 38168062b86fc0f480b806d270a8278709a5a41bb67Oleg Nesterov 3824be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney /* 3834be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney * The taskstats structure is internally aligned on 8 byte 3844be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney * boundaries but the layout of the aggregrate reply, with 3854be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney * two NLA headers and the pid (each 4 bytes), actually 3864be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney * force the entire structure to be unaligned. This causes 3874be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney * the kernel to issue unaligned access warnings on some 3884be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney * architectures like ia64. Unfortunately, some software out there 3894be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney * doesn't properly unroll the NLA packet and assumes that the start 3904be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney * of the taskstats structure will always be 20 bytes from the start 3914be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney * of the netlink payload. Aligning the start of the taskstats 3924be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney * structure breaks this software, which we don't want. So, for now 3934be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney * the alignment only happens on architectures that require it 3944be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney * and those users will have to update to fixed versions of those 3954be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney * packages. Space is reserved in the packet only when needed. 3964be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney * This ifdef should be removed in several years e.g. 2012 once 3974be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney * we can be confident that fixed versions are installed on most 3984be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney * systems. We add the padding before the aggregate since the 3994be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney * aggregate is already a defined type. 4004be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney */ 4014be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney#ifdef TASKSTATS_NEEDS_PADDING 4024be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney if (nla_put(skb, TASKSTATS_TYPE_NULL, 0, NULL) < 0) 4034be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney goto err; 4044be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney#endif 40568062b86fc0f480b806d270a8278709a5a41bb67Oleg Nesterov na = nla_nest_start(skb, aggr); 40637167485302c8876cb0303af113696e88c2945aaOleg Nesterov if (!na) 40737167485302c8876cb0303af113696e88c2945aaOleg Nesterov goto err; 4084be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney 4093fa582663129330d57d15b97ae534dc1203fc3aaChen Gang if (nla_put(skb, type, sizeof(pid), &pid) < 0) { 4103fa582663129330d57d15b97ae534dc1203fc3aaChen Gang nla_nest_cancel(skb, na); 41151de4d90852ba4cfa5743594ec4a7f158b52dc43Oleg Nesterov goto err; 4123fa582663129330d57d15b97ae534dc1203fc3aaChen Gang } 41351de4d90852ba4cfa5743594ec4a7f158b52dc43Oleg Nesterov ret = nla_reserve(skb, TASKSTATS_TYPE_STATS, sizeof(struct taskstats)); 4143fa582663129330d57d15b97ae534dc1203fc3aaChen Gang if (!ret) { 4153fa582663129330d57d15b97ae534dc1203fc3aaChen Gang nla_nest_cancel(skb, na); 41651de4d90852ba4cfa5743594ec4a7f158b52dc43Oleg Nesterov goto err; 4173fa582663129330d57d15b97ae534dc1203fc3aaChen Gang } 41868062b86fc0f480b806d270a8278709a5a41bb67Oleg Nesterov nla_nest_end(skb, na); 41968062b86fc0f480b806d270a8278709a5a41bb67Oleg Nesterov 42051de4d90852ba4cfa5743594ec4a7f158b52dc43Oleg Nesterov return nla_data(ret); 42151de4d90852ba4cfa5743594ec4a7f158b52dc43Oleg Nesteroverr: 42251de4d90852ba4cfa5743594ec4a7f158b52dc43Oleg Nesterov return NULL; 42368062b86fc0f480b806d270a8278709a5a41bb67Oleg Nesterov} 42468062b86fc0f480b806d270a8278709a5a41bb67Oleg Nesterov 425846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singhstatic int cgroupstats_user_cmd(struct sk_buff *skb, struct genl_info *info) 426846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singh{ 427846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singh int rc = 0; 428846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singh struct sk_buff *rep_skb; 429846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singh struct cgroupstats *stats; 430846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singh struct nlattr *na; 431846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singh size_t size; 432846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singh u32 fd; 4332903ff019b346ab8d36ebbf54853c3aaf6590608Al Viro struct fd f; 434846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singh 435846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singh na = info->attrs[CGROUPSTATS_CMD_ATTR_FD]; 436846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singh if (!na) 437846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singh return -EINVAL; 438846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singh 439846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singh fd = nla_get_u32(info->attrs[CGROUPSTATS_CMD_ATTR_FD]); 4402903ff019b346ab8d36ebbf54853c3aaf6590608Al Viro f = fdget(fd); 4412903ff019b346ab8d36ebbf54853c3aaf6590608Al Viro if (!f.file) 442f96159840bc5f605aca5113ab2d24308d3dc2effAdrian Bunk return 0; 443846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singh 444f96159840bc5f605aca5113ab2d24308d3dc2effAdrian Bunk size = nla_total_size(sizeof(struct cgroupstats)); 445846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singh 446f96159840bc5f605aca5113ab2d24308d3dc2effAdrian Bunk rc = prepare_reply(info, CGROUPSTATS_CMD_NEW, &rep_skb, 447f96159840bc5f605aca5113ab2d24308d3dc2effAdrian Bunk size); 448f96159840bc5f605aca5113ab2d24308d3dc2effAdrian Bunk if (rc < 0) 449f96159840bc5f605aca5113ab2d24308d3dc2effAdrian Bunk goto err; 450846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singh 451f96159840bc5f605aca5113ab2d24308d3dc2effAdrian Bunk na = nla_reserve(rep_skb, CGROUPSTATS_TYPE_CGROUP_STATS, 452f96159840bc5f605aca5113ab2d24308d3dc2effAdrian Bunk sizeof(struct cgroupstats)); 45325353b3377d5a75d4b830477bb90a3691155de72Alan Cox if (na == NULL) { 4540324b5a450f8a58304e93c5d886add24ca3527bcJesper Juhl nlmsg_free(rep_skb); 45525353b3377d5a75d4b830477bb90a3691155de72Alan Cox rc = -EMSGSIZE; 45625353b3377d5a75d4b830477bb90a3691155de72Alan Cox goto err; 45725353b3377d5a75d4b830477bb90a3691155de72Alan Cox } 45825353b3377d5a75d4b830477bb90a3691155de72Alan Cox 459f96159840bc5f605aca5113ab2d24308d3dc2effAdrian Bunk stats = nla_data(na); 460f96159840bc5f605aca5113ab2d24308d3dc2effAdrian Bunk memset(stats, 0, sizeof(*stats)); 461846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singh 4622903ff019b346ab8d36ebbf54853c3aaf6590608Al Viro rc = cgroupstats_build(stats, f.file->f_dentry); 463f96159840bc5f605aca5113ab2d24308d3dc2effAdrian Bunk if (rc < 0) { 464f96159840bc5f605aca5113ab2d24308d3dc2effAdrian Bunk nlmsg_free(rep_skb); 465f96159840bc5f605aca5113ab2d24308d3dc2effAdrian Bunk goto err; 466846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singh } 467846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singh 468134e63756d5f3d0f7604dfcca847b09d1b14fd66Johannes Berg rc = send_reply(rep_skb, info); 469f96159840bc5f605aca5113ab2d24308d3dc2effAdrian Bunk 470846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singherr: 4712903ff019b346ab8d36ebbf54853c3aaf6590608Al Viro fdput(f); 472846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singh return rc; 473846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singh} 474846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singh 4759323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheustatic int cmd_attr_register_cpumask(struct genl_info *info) 476c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar{ 47741c7bb9588904eb060a95bcad47bd3804a1ece25Rusty Russell cpumask_var_t mask; 4789323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu int rc; 47941c7bb9588904eb060a95bcad47bd3804a1ece25Rusty Russell 48041c7bb9588904eb060a95bcad47bd3804a1ece25Rusty Russell if (!alloc_cpumask_var(&mask, GFP_KERNEL)) 48141c7bb9588904eb060a95bcad47bd3804a1ece25Rusty Russell return -ENOMEM; 48241c7bb9588904eb060a95bcad47bd3804a1ece25Rusty Russell rc = parse(info->attrs[TASKSTATS_CMD_ATTR_REGISTER_CPUMASK], mask); 483f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar if (rc < 0) 4849323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu goto out; 48515e473046cb6e5d18a4d0057e61d76315230382bEric W. Biederman rc = add_del_listener(info->snd_portid, mask, REGISTER); 4869323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheuout: 4879323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu free_cpumask_var(mask); 4889323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu return rc; 4899323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu} 4909323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu 4919323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheustatic int cmd_attr_deregister_cpumask(struct genl_info *info) 4929323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu{ 4939323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu cpumask_var_t mask; 4949323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu int rc; 495f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar 4969323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu if (!alloc_cpumask_var(&mask, GFP_KERNEL)) 4979323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu return -ENOMEM; 49841c7bb9588904eb060a95bcad47bd3804a1ece25Rusty Russell rc = parse(info->attrs[TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK], mask); 499f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar if (rc < 0) 5009323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu goto out; 50115e473046cb6e5d18a4d0057e61d76315230382bEric W. Biederman rc = add_del_listener(info->snd_portid, mask, DEREGISTER); 5029323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheuout: 50341c7bb9588904eb060a95bcad47bd3804a1ece25Rusty Russell free_cpumask_var(mask); 5049323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu return rc; 5059323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu} 5069323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu 5074be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoneystatic size_t taskstats_packet_size(void) 5084be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney{ 5094be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney size_t size; 5104be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney 5114be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney size = nla_total_size(sizeof(u32)) + 5124be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney nla_total_size(sizeof(struct taskstats)) + nla_total_size(0); 5134be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney#ifdef TASKSTATS_NEEDS_PADDING 5144be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney size += nla_total_size(0); /* Padding for alignment */ 5154be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney#endif 5164be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney return size; 5174be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney} 5184be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney 5199323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheustatic int cmd_attr_pid(struct genl_info *info) 5209323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu{ 5219323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu struct taskstats *stats; 5229323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu struct sk_buff *rep_skb; 5239323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu size_t size; 5249323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu u32 pid; 5259323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu int rc; 526c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 5274be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney size = taskstats_packet_size(); 528c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 52937167485302c8876cb0303af113696e88c2945aaOleg Nesterov rc = prepare_reply(info, TASKSTATS_CMD_NEW, &rep_skb, size); 530c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar if (rc < 0) 531c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar return rc; 532c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 53351de4d90852ba4cfa5743594ec4a7f158b52dc43Oleg Nesterov rc = -EINVAL; 5349323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu pid = nla_get_u32(info->attrs[TASKSTATS_CMD_ATTR_PID]); 5359323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu stats = mk_reply(rep_skb, TASKSTATS_TYPE_PID, pid); 5369323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu if (!stats) 537c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar goto err; 538c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 5393d9e0cf1fe007b88db55d43dfdb6839e1a029ca5Michael Holzheu rc = fill_stats_for_pid(pid, stats); 5409323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu if (rc < 0) 5419323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu goto err; 542134e63756d5f3d0f7604dfcca847b09d1b14fd66Johannes Berg return send_reply(rep_skb, info); 543c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagarerr: 544c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar nlmsg_free(rep_skb); 545c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar return rc; 546c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar} 547c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 5489323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheustatic int cmd_attr_tgid(struct genl_info *info) 5499323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu{ 5509323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu struct taskstats *stats; 5519323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu struct sk_buff *rep_skb; 5529323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu size_t size; 5539323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu u32 tgid; 5549323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu int rc; 5559323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu 5564be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney size = taskstats_packet_size(); 5579323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu 5589323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu rc = prepare_reply(info, TASKSTATS_CMD_NEW, &rep_skb, size); 5599323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu if (rc < 0) 5609323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu return rc; 5619323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu 5629323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu rc = -EINVAL; 5639323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu tgid = nla_get_u32(info->attrs[TASKSTATS_CMD_ATTR_TGID]); 5649323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu stats = mk_reply(rep_skb, TASKSTATS_TYPE_TGID, tgid); 5659323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu if (!stats) 5669323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu goto err; 5679323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu 5683d9e0cf1fe007b88db55d43dfdb6839e1a029ca5Michael Holzheu rc = fill_stats_for_tgid(tgid, stats); 5699323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu if (rc < 0) 5709323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu goto err; 5719323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu return send_reply(rep_skb, info); 5729323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheuerr: 5739323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu nlmsg_free(rep_skb); 5749323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu return rc; 5759323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu} 5769323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu 5779323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheustatic int taskstats_user_cmd(struct sk_buff *skb, struct genl_info *info) 5789323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu{ 5799323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu if (info->attrs[TASKSTATS_CMD_ATTR_REGISTER_CPUMASK]) 5809323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu return cmd_attr_register_cpumask(info); 5819323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu else if (info->attrs[TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK]) 5829323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu return cmd_attr_deregister_cpumask(info); 5839323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu else if (info->attrs[TASKSTATS_CMD_ATTR_PID]) 5849323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu return cmd_attr_pid(info); 5859323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu else if (info->attrs[TASKSTATS_CMD_ATTR_TGID]) 5869323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu return cmd_attr_tgid(info); 5879323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu else 5889323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu return -EINVAL; 5899323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu} 5909323312592cca636d7c2580dc85fa4846efa86a2Michael Holzheu 59134ec12349c8a9505adc59d72f92b4595bc2483ffOleg Nesterovstatic struct taskstats *taskstats_tgid_alloc(struct task_struct *tsk) 59234ec12349c8a9505adc59d72f92b4595bc2483ffOleg Nesterov{ 59334ec12349c8a9505adc59d72f92b4595bc2483ffOleg Nesterov struct signal_struct *sig = tsk->signal; 59434ec12349c8a9505adc59d72f92b4595bc2483ffOleg Nesterov struct taskstats *stats; 59534ec12349c8a9505adc59d72f92b4595bc2483ffOleg Nesterov 59634ec12349c8a9505adc59d72f92b4595bc2483ffOleg Nesterov if (sig->stats || thread_group_empty(tsk)) 59734ec12349c8a9505adc59d72f92b4595bc2483ffOleg Nesterov goto ret; 59834ec12349c8a9505adc59d72f92b4595bc2483ffOleg Nesterov 59934ec12349c8a9505adc59d72f92b4595bc2483ffOleg Nesterov /* No problem if kmem_cache_zalloc() fails */ 60034ec12349c8a9505adc59d72f92b4595bc2483ffOleg Nesterov stats = kmem_cache_zalloc(taskstats_cache, GFP_KERNEL); 60134ec12349c8a9505adc59d72f92b4595bc2483ffOleg Nesterov 60234ec12349c8a9505adc59d72f92b4595bc2483ffOleg Nesterov spin_lock_irq(&tsk->sighand->siglock); 60334ec12349c8a9505adc59d72f92b4595bc2483ffOleg Nesterov if (!sig->stats) { 60434ec12349c8a9505adc59d72f92b4595bc2483ffOleg Nesterov sig->stats = stats; 60534ec12349c8a9505adc59d72f92b4595bc2483ffOleg Nesterov stats = NULL; 60634ec12349c8a9505adc59d72f92b4595bc2483ffOleg Nesterov } 60734ec12349c8a9505adc59d72f92b4595bc2483ffOleg Nesterov spin_unlock_irq(&tsk->sighand->siglock); 60834ec12349c8a9505adc59d72f92b4595bc2483ffOleg Nesterov 60934ec12349c8a9505adc59d72f92b4595bc2483ffOleg Nesterov if (stats) 61034ec12349c8a9505adc59d72f92b4595bc2483ffOleg Nesterov kmem_cache_free(taskstats_cache, stats); 61134ec12349c8a9505adc59d72f92b4595bc2483ffOleg Nesterovret: 61234ec12349c8a9505adc59d72f92b4595bc2483ffOleg Nesterov return sig->stats; 61334ec12349c8a9505adc59d72f92b4595bc2483ffOleg Nesterov} 61434ec12349c8a9505adc59d72f92b4595bc2483ffOleg Nesterov 615c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar/* Send pid data out on exit */ 616115085ea0794c0f339be8f9d25505c7f9861d824Oleg Nesterovvoid taskstats_exit(struct task_struct *tsk, int group_dead) 617c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar{ 618c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar int rc; 619115085ea0794c0f339be8f9d25505c7f9861d824Oleg Nesterov struct listener_list *listeners; 62051de4d90852ba4cfa5743594ec4a7f158b52dc43Oleg Nesterov struct taskstats *stats; 621c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar struct sk_buff *rep_skb; 622c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar size_t size; 623c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar int is_thread_group; 624c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 6254a279ff1ea1cf325775ada983035123fcdc8e986Oleg Nesterov if (!family_registered) 626c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar return; 627c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 628c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar /* 629c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar * Size includes space for nested attributes 630c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar */ 6314be2c95d1f7706ca0e74499f2bd118e1cee19669Jeff Mahoney size = taskstats_packet_size(); 632c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 63334ec12349c8a9505adc59d72f92b4595bc2483ffOleg Nesterov is_thread_group = !!taskstats_tgid_alloc(tsk); 6344a279ff1ea1cf325775ada983035123fcdc8e986Oleg Nesterov if (is_thread_group) { 6354a279ff1ea1cf325775ada983035123fcdc8e986Oleg Nesterov /* PID + STATS + TGID + STATS */ 6364a279ff1ea1cf325775ada983035123fcdc8e986Oleg Nesterov size = 2 * size; 6374a279ff1ea1cf325775ada983035123fcdc8e986Oleg Nesterov /* fill the tsk->signal->stats structure */ 6384a279ff1ea1cf325775ada983035123fcdc8e986Oleg Nesterov fill_tgid_exit(tsk); 6394a279ff1ea1cf325775ada983035123fcdc8e986Oleg Nesterov } 6404a279ff1ea1cf325775ada983035123fcdc8e986Oleg Nesterov 6414a32fea9d78f2d2315c0072757b197d5a304dc8bChristoph Lameter listeners = raw_cpu_ptr(&listener_array); 642115085ea0794c0f339be8f9d25505c7f9861d824Oleg Nesterov if (list_empty(&listeners->list)) 643115085ea0794c0f339be8f9d25505c7f9861d824Oleg Nesterov return; 644115085ea0794c0f339be8f9d25505c7f9861d824Oleg Nesterov 64537167485302c8876cb0303af113696e88c2945aaOleg Nesterov rc = prepare_reply(NULL, TASKSTATS_CMD_NEW, &rep_skb, size); 646c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar if (rc < 0) 64751de4d90852ba4cfa5743594ec4a7f158b52dc43Oleg Nesterov return; 648c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 6494bd6e32acec66c55c6c1af4672f3216b2ac88e35Eric W. Biederman stats = mk_reply(rep_skb, TASKSTATS_TYPE_PID, 6504bd6e32acec66c55c6c1af4672f3216b2ac88e35Eric W. Biederman task_pid_nr_ns(tsk, &init_pid_ns)); 65151de4d90852ba4cfa5743594ec4a7f158b52dc43Oleg Nesterov if (!stats) 65237167485302c8876cb0303af113696e88c2945aaOleg Nesterov goto err; 653c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 6544bd6e32acec66c55c6c1af4672f3216b2ac88e35Eric W. Biederman fill_stats(&init_user_ns, &init_pid_ns, tsk, stats); 655c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 656c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar /* 657ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagar * Doesn't matter if tsk is the leader or the last group member leaving 658c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar */ 65968062b86fc0f480b806d270a8278709a5a41bb67Oleg Nesterov if (!is_thread_group || !group_dead) 660ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagar goto send; 661c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 6624bd6e32acec66c55c6c1af4672f3216b2ac88e35Eric W. Biederman stats = mk_reply(rep_skb, TASKSTATS_TYPE_TGID, 6634bd6e32acec66c55c6c1af4672f3216b2ac88e35Eric W. Biederman task_tgid_nr_ns(tsk, &init_pid_ns)); 66451de4d90852ba4cfa5743594ec4a7f158b52dc43Oleg Nesterov if (!stats) 66537167485302c8876cb0303af113696e88c2945aaOleg Nesterov goto err; 66651de4d90852ba4cfa5743594ec4a7f158b52dc43Oleg Nesterov 66751de4d90852ba4cfa5743594ec4a7f158b52dc43Oleg Nesterov memcpy(stats, tsk->signal->stats, sizeof(*stats)); 668c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 669ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagarsend: 670115085ea0794c0f339be8f9d25505c7f9861d824Oleg Nesterov send_cpu_listeners(rep_skb, listeners); 671ad4ecbcba72855a2b5319b96e2a3a65ed1ca3bfdShailabh Nagar return; 67237167485302c8876cb0303af113696e88c2945aaOleg Nesteroverr: 673c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar nlmsg_free(rep_skb); 674c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar} 675c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 6764534de8305b3f1460a527a0cda0e3dc2224c6f0cJohannes Bergstatic const struct genl_ops taskstats_ops[] = { 67788d36a9949513419de3a506e7fca8b82d1dc972aJohannes Berg { 67888d36a9949513419de3a506e7fca8b82d1dc972aJohannes Berg .cmd = TASKSTATS_CMD_GET, 67988d36a9949513419de3a506e7fca8b82d1dc972aJohannes Berg .doit = taskstats_user_cmd, 68088d36a9949513419de3a506e7fca8b82d1dc972aJohannes Berg .policy = taskstats_cmd_get_policy, 68188d36a9949513419de3a506e7fca8b82d1dc972aJohannes Berg .flags = GENL_ADMIN_PERM, 68288d36a9949513419de3a506e7fca8b82d1dc972aJohannes Berg }, 68388d36a9949513419de3a506e7fca8b82d1dc972aJohannes Berg { 68488d36a9949513419de3a506e7fca8b82d1dc972aJohannes Berg .cmd = CGROUPSTATS_CMD_GET, 68588d36a9949513419de3a506e7fca8b82d1dc972aJohannes Berg .doit = cgroupstats_user_cmd, 68688d36a9949513419de3a506e7fca8b82d1dc972aJohannes Berg .policy = cgroupstats_cmd_get_policy, 68788d36a9949513419de3a506e7fca8b82d1dc972aJohannes Berg }, 688846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singh}; 689846c7bb055747989891f5cd2bb6e8d56243ba1e7Balbir Singh 690c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar/* Needed early in initialization */ 691c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagarvoid __init taskstats_init_early(void) 692c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar{ 693f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar unsigned int i; 694f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar 6950a31bd5f2bbb6473ef9d24f0063ca91cfa678b64Christoph Lameter taskstats_cache = KMEM_CACHE(taskstats, SLAB_PANIC); 696f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar for_each_possible_cpu(i) { 697f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar INIT_LIST_HEAD(&(per_cpu(listener_array, i).list)); 698f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar init_rwsem(&(per_cpu(listener_array, i).sem)); 699f9fd8914c1acca0d98b69d831b128d5b52f03c51Shailabh Nagar } 700c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar} 701c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 702c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagarstatic int __init taskstats_init(void) 703c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar{ 704c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar int rc; 705c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 706c53ed7423619b4e8108914a9f31b426dd58ad591Johannes Berg rc = genl_register_family_with_ops(&family, taskstats_ops); 707c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar if (rc) 708c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar return rc; 709c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 710c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar family_registered = 1; 711f9b182e24ecb2b3bb33340f053ba31c8c4e1d895Mandeep Singh Baines pr_info("registered taskstats version %d\n", TASKSTATS_GENL_VERSION); 712c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar return 0; 713c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar} 714c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar 715c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar/* 716c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar * late initcall ensures initialization of statistics collection 717c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar * mechanisms precedes initialization of the taskstats interface 718c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagar */ 719c757249af152c59fd74b85e52e8c090acb33d9c0Shailabh Nagarlate_initcall(taskstats_init); 720