1 #include <linux/cgroup.h> 2 #include <linux/slab.h> 3 #include <linux/percpu.h> 4 #include <linux/spinlock.h> 5 #include <linux/cpumask.h> 6 #include <linux/seq_file.h> 7 #include <linux/rcupdate.h> 8 #include <linux/kernel_stat.h> 9 #include <linux/err.h> 10 11 #include "sched.h" 12 13 /* 14 * CPU accounting code for task groups. 15 * 16 * Based on the work by Paul Menage (menage@google.com) and Balbir Singh 17 * (balbir@in.ibm.com). 18 */ 19 20 /* Time spent by the tasks of the cpu accounting group executing in ... */ 21 enum cpuacct_stat_index { 22 CPUACCT_STAT_USER, /* ... user mode */ 23 CPUACCT_STAT_SYSTEM, /* ... kernel mode */ 24 25 CPUACCT_STAT_NSTATS, 26 }; 27 28 /* track cpu usage of a group of tasks and its child groups */ 29 struct cpuacct { 30 struct cgroup_subsys_state css; 31 /* cpuusage holds pointer to a u64-type object on every cpu */ 32 u64 __percpu *cpuusage; 33 struct kernel_cpustat __percpu *cpustat; 34 }; 35 36 static inline struct cpuacct *css_ca(struct cgroup_subsys_state *css) 37 { 38 return css ? container_of(css, struct cpuacct, css) : NULL; 39 } 40 41 /* return cpu accounting group to which this task belongs */ 42 static inline struct cpuacct *task_ca(struct task_struct *tsk) 43 { 44 return css_ca(task_css(tsk, cpuacct_subsys_id)); 45 } 46 47 static inline struct cpuacct *parent_ca(struct cpuacct *ca) 48 { 49 return css_ca(css_parent(&ca->css)); 50 } 51 52 static DEFINE_PER_CPU(u64, root_cpuacct_cpuusage); 53 static struct cpuacct root_cpuacct = { 54 .cpustat = &kernel_cpustat, 55 .cpuusage = &root_cpuacct_cpuusage, 56 }; 57 58 /* create a new cpu accounting group */ 59 static struct cgroup_subsys_state * 60 cpuacct_css_alloc(struct cgroup_subsys_state *parent_css) 61 { 62 struct cpuacct *ca; 63 64 if (!parent_css) 65 return &root_cpuacct.css; 66 67 ca = kzalloc(sizeof(*ca), GFP_KERNEL); 68 if (!ca) 69 goto out; 70 71 ca->cpuusage = alloc_percpu(u64); 72 if (!ca->cpuusage) 73 goto out_free_ca; 74 75 ca->cpustat = alloc_percpu(struct kernel_cpustat); 76 if (!ca->cpustat) 77 goto out_free_cpuusage; 78 79 return &ca->css; 80 81 out_free_cpuusage: 82 free_percpu(ca->cpuusage); 83 out_free_ca: 84 kfree(ca); 85 out: 86 return ERR_PTR(-ENOMEM); 87 } 88 89 /* destroy an existing cpu accounting group */ 90 static void cpuacct_css_free(struct cgroup_subsys_state *css) 91 { 92 struct cpuacct *ca = css_ca(css); 93 94 free_percpu(ca->cpustat); 95 free_percpu(ca->cpuusage); 96 kfree(ca); 97 } 98 99 static u64 cpuacct_cpuusage_read(struct cpuacct *ca, int cpu) 100 { 101 u64 *cpuusage = per_cpu_ptr(ca->cpuusage, cpu); 102 u64 data; 103 104 #ifndef CONFIG_64BIT 105 /* 106 * Take rq->lock to make 64-bit read safe on 32-bit platforms. 107 */ 108 raw_spin_lock_irq(&cpu_rq(cpu)->lock); 109 data = *cpuusage; 110 raw_spin_unlock_irq(&cpu_rq(cpu)->lock); 111 #else 112 data = *cpuusage; 113 #endif 114 115 return data; 116 } 117 118 static void cpuacct_cpuusage_write(struct cpuacct *ca, int cpu, u64 val) 119 { 120 u64 *cpuusage = per_cpu_ptr(ca->cpuusage, cpu); 121 122 #ifndef CONFIG_64BIT 123 /* 124 * Take rq->lock to make 64-bit write safe on 32-bit platforms. 125 */ 126 raw_spin_lock_irq(&cpu_rq(cpu)->lock); 127 *cpuusage = val; 128 raw_spin_unlock_irq(&cpu_rq(cpu)->lock); 129 #else 130 *cpuusage = val; 131 #endif 132 } 133 134 /* return total cpu usage (in nanoseconds) of a group */ 135 static u64 cpuusage_read(struct cgroup_subsys_state *css, struct cftype *cft) 136 { 137 struct cpuacct *ca = css_ca(css); 138 u64 totalcpuusage = 0; 139 int i; 140 141 for_each_present_cpu(i) 142 totalcpuusage += cpuacct_cpuusage_read(ca, i); 143 144 return totalcpuusage; 145 } 146 147 static int cpuusage_write(struct cgroup_subsys_state *css, struct cftype *cft, 148 u64 reset) 149 { 150 struct cpuacct *ca = css_ca(css); 151 int err = 0; 152 int i; 153 154 if (reset) { 155 err = -EINVAL; 156 goto out; 157 } 158 159 for_each_present_cpu(i) 160 cpuacct_cpuusage_write(ca, i, 0); 161 162 out: 163 return err; 164 } 165 166 static int cpuacct_percpu_seq_read(struct cgroup_subsys_state *css, 167 struct cftype *cft, struct seq_file *m) 168 { 169 struct cpuacct *ca = css_ca(css); 170 u64 percpu; 171 int i; 172 173 for_each_present_cpu(i) { 174 percpu = cpuacct_cpuusage_read(ca, i); 175 seq_printf(m, "%llu ", (unsigned long long) percpu); 176 } 177 seq_printf(m, "\n"); 178 return 0; 179 } 180 181 static const char * const cpuacct_stat_desc[] = { 182 [CPUACCT_STAT_USER] = "user", 183 [CPUACCT_STAT_SYSTEM] = "system", 184 }; 185 186 static int cpuacct_stats_show(struct cgroup_subsys_state *css, 187 struct cftype *cft, struct cgroup_map_cb *cb) 188 { 189 struct cpuacct *ca = css_ca(css); 190 int cpu; 191 s64 val = 0; 192 193 for_each_online_cpu(cpu) { 194 struct kernel_cpustat *kcpustat = per_cpu_ptr(ca->cpustat, cpu); 195 val += kcpustat->cpustat[CPUTIME_USER]; 196 val += kcpustat->cpustat[CPUTIME_NICE]; 197 } 198 val = cputime64_to_clock_t(val); 199 cb->fill(cb, cpuacct_stat_desc[CPUACCT_STAT_USER], val); 200 201 val = 0; 202 for_each_online_cpu(cpu) { 203 struct kernel_cpustat *kcpustat = per_cpu_ptr(ca->cpustat, cpu); 204 val += kcpustat->cpustat[CPUTIME_SYSTEM]; 205 val += kcpustat->cpustat[CPUTIME_IRQ]; 206 val += kcpustat->cpustat[CPUTIME_SOFTIRQ]; 207 } 208 209 val = cputime64_to_clock_t(val); 210 cb->fill(cb, cpuacct_stat_desc[CPUACCT_STAT_SYSTEM], val); 211 212 return 0; 213 } 214 215 static struct cftype files[] = { 216 { 217 .name = "usage", 218 .read_u64 = cpuusage_read, 219 .write_u64 = cpuusage_write, 220 }, 221 { 222 .name = "usage_percpu", 223 .read_seq_string = cpuacct_percpu_seq_read, 224 }, 225 { 226 .name = "stat", 227 .read_map = cpuacct_stats_show, 228 }, 229 { } /* terminate */ 230 }; 231 232 /* 233 * charge this task's execution time to its accounting group. 234 * 235 * called with rq->lock held. 236 */ 237 void cpuacct_charge(struct task_struct *tsk, u64 cputime) 238 { 239 struct cpuacct *ca; 240 int cpu; 241 242 cpu = task_cpu(tsk); 243 244 rcu_read_lock(); 245 246 ca = task_ca(tsk); 247 248 while (true) { 249 u64 *cpuusage = per_cpu_ptr(ca->cpuusage, cpu); 250 *cpuusage += cputime; 251 252 ca = parent_ca(ca); 253 if (!ca) 254 break; 255 } 256 257 rcu_read_unlock(); 258 } 259 260 /* 261 * Add user/system time to cpuacct. 262 * 263 * Note: it's the caller that updates the account of the root cgroup. 264 */ 265 void cpuacct_account_field(struct task_struct *p, int index, u64 val) 266 { 267 struct kernel_cpustat *kcpustat; 268 struct cpuacct *ca; 269 270 rcu_read_lock(); 271 ca = task_ca(p); 272 while (ca != &root_cpuacct) { 273 kcpustat = this_cpu_ptr(ca->cpustat); 274 kcpustat->cpustat[index] += val; 275 ca = parent_ca(ca); 276 } 277 rcu_read_unlock(); 278 } 279 280 struct cgroup_subsys cpuacct_subsys = { 281 .name = "cpuacct", 282 .css_alloc = cpuacct_css_alloc, 283 .css_free = cpuacct_css_free, 284 .subsys_id = cpuacct_subsys_id, 285 .base_cftypes = files, 286 .early_init = 1, 287 }; 288