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_cgrp_id)); 45 } 46 47 static inline struct cpuacct *parent_ca(struct cpuacct *ca) 48 { 49 return css_ca(ca->css.parent); 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 val) 149 { 150 struct cpuacct *ca = css_ca(css); 151 int err = 0; 152 int i; 153 154 /* 155 * Only allow '0' here to do a reset. 156 */ 157 if (val) { 158 err = -EINVAL; 159 goto out; 160 } 161 162 for_each_present_cpu(i) 163 cpuacct_cpuusage_write(ca, i, 0); 164 165 out: 166 return err; 167 } 168 169 static int cpuacct_percpu_seq_show(struct seq_file *m, void *V) 170 { 171 struct cpuacct *ca = css_ca(seq_css(m)); 172 u64 percpu; 173 int i; 174 175 for_each_present_cpu(i) { 176 percpu = cpuacct_cpuusage_read(ca, i); 177 seq_printf(m, "%llu ", (unsigned long long) percpu); 178 } 179 seq_printf(m, "\n"); 180 return 0; 181 } 182 183 static const char * const cpuacct_stat_desc[] = { 184 [CPUACCT_STAT_USER] = "user", 185 [CPUACCT_STAT_SYSTEM] = "system", 186 }; 187 188 static int cpuacct_stats_show(struct seq_file *sf, void *v) 189 { 190 struct cpuacct *ca = css_ca(seq_css(sf)); 191 int cpu; 192 s64 val = 0; 193 194 for_each_online_cpu(cpu) { 195 struct kernel_cpustat *kcpustat = per_cpu_ptr(ca->cpustat, cpu); 196 val += kcpustat->cpustat[CPUTIME_USER]; 197 val += kcpustat->cpustat[CPUTIME_NICE]; 198 } 199 val = cputime64_to_clock_t(val); 200 seq_printf(sf, "%s %lld\n", cpuacct_stat_desc[CPUACCT_STAT_USER], val); 201 202 val = 0; 203 for_each_online_cpu(cpu) { 204 struct kernel_cpustat *kcpustat = per_cpu_ptr(ca->cpustat, cpu); 205 val += kcpustat->cpustat[CPUTIME_SYSTEM]; 206 val += kcpustat->cpustat[CPUTIME_IRQ]; 207 val += kcpustat->cpustat[CPUTIME_SOFTIRQ]; 208 } 209 210 val = cputime64_to_clock_t(val); 211 seq_printf(sf, "%s %lld\n", cpuacct_stat_desc[CPUACCT_STAT_SYSTEM], val); 212 213 return 0; 214 } 215 216 static struct cftype files[] = { 217 { 218 .name = "usage", 219 .read_u64 = cpuusage_read, 220 .write_u64 = cpuusage_write, 221 }, 222 { 223 .name = "usage_percpu", 224 .seq_show = cpuacct_percpu_seq_show, 225 }, 226 { 227 .name = "stat", 228 .seq_show = cpuacct_stats_show, 229 }, 230 { } /* terminate */ 231 }; 232 233 /* 234 * charge this task's execution time to its accounting group. 235 * 236 * called with rq->lock held. 237 */ 238 void cpuacct_charge(struct task_struct *tsk, u64 cputime) 239 { 240 struct cpuacct *ca; 241 242 rcu_read_lock(); 243 for (ca = task_ca(tsk); ca; ca = parent_ca(ca)) 244 *this_cpu_ptr(ca->cpuusage) += cputime; 245 rcu_read_unlock(); 246 } 247 248 /* 249 * Add user/system time to cpuacct. 250 * 251 * Note: it's the caller that updates the account of the root cgroup. 252 */ 253 void cpuacct_account_field(struct task_struct *tsk, int index, u64 val) 254 { 255 struct cpuacct *ca; 256 257 rcu_read_lock(); 258 for (ca = task_ca(tsk); ca != &root_cpuacct; ca = parent_ca(ca)) 259 this_cpu_ptr(ca->cpustat)->cpustat[index] += val; 260 rcu_read_unlock(); 261 } 262 263 struct cgroup_subsys cpuacct_cgrp_subsys = { 264 .css_alloc = cpuacct_css_alloc, 265 .css_free = cpuacct_css_free, 266 .legacy_cftypes = files, 267 .early_init = true, 268 }; 269