hc
2024-05-10 61598093bbdd283a7edc367d900f223070ead8d2
kernel/kernel/sched/cpuacct.c
....@@ -21,15 +21,11 @@
2121 [CPUACCT_STAT_SYSTEM] = "system",
2222 };
2323
24
-struct cpuacct_usage {
25
- u64 usages[CPUACCT_STAT_NSTATS];
26
-};
27
-
2824 /* track CPU usage of a group of tasks and its child groups */
2925 struct cpuacct {
3026 struct cgroup_subsys_state css;
3127 /* cpuusage holds pointer to a u64-type object on every CPU */
32
- struct cpuacct_usage __percpu *cpuusage;
28
+ u64 __percpu *cpuusage;
3329 struct kernel_cpustat __percpu *cpustat;
3430 };
3531
....@@ -49,7 +45,7 @@
4945 return css_ca(ca->css.parent);
5046 }
5147
52
-static DEFINE_PER_CPU(struct cpuacct_usage, root_cpuacct_cpuusage);
48
+static DEFINE_PER_CPU(u64, root_cpuacct_cpuusage);
5349 static struct cpuacct root_cpuacct = {
5450 .cpustat = &kernel_cpustat,
5551 .cpuusage = &root_cpuacct_cpuusage,
....@@ -68,7 +64,7 @@
6864 if (!ca)
6965 goto out;
7066
71
- ca->cpuusage = alloc_percpu(struct cpuacct_usage);
67
+ ca->cpuusage = alloc_percpu(u64);
7268 if (!ca->cpuusage)
7369 goto out_free_ca;
7470
....@@ -99,7 +95,8 @@
9995 static u64 cpuacct_cpuusage_read(struct cpuacct *ca, int cpu,
10096 enum cpuacct_stat_index index)
10197 {
102
- struct cpuacct_usage *cpuusage = per_cpu_ptr(ca->cpuusage, cpu);
98
+ u64 *cpuusage = per_cpu_ptr(ca->cpuusage, cpu);
99
+ u64 *cpustat = per_cpu_ptr(ca->cpustat, cpu)->cpustat;
103100 u64 data;
104101
105102 /*
....@@ -115,14 +112,17 @@
115112 raw_spin_lock_irq(&cpu_rq(cpu)->lock);
116113 #endif
117114
118
- if (index == CPUACCT_STAT_NSTATS) {
119
- int i = 0;
120
-
121
- data = 0;
122
- for (i = 0; i < CPUACCT_STAT_NSTATS; i++)
123
- data += cpuusage->usages[i];
124
- } else {
125
- data = cpuusage->usages[index];
115
+ switch (index) {
116
+ case CPUACCT_STAT_USER:
117
+ data = cpustat[CPUTIME_USER] + cpustat[CPUTIME_NICE];
118
+ break;
119
+ case CPUACCT_STAT_SYSTEM:
120
+ data = cpustat[CPUTIME_SYSTEM] + cpustat[CPUTIME_IRQ] +
121
+ cpustat[CPUTIME_SOFTIRQ];
122
+ break;
123
+ case CPUACCT_STAT_NSTATS:
124
+ data = *cpuusage;
125
+ break;
126126 }
127127
128128 #ifndef CONFIG_64BIT
....@@ -132,10 +132,14 @@
132132 return data;
133133 }
134134
135
-static void cpuacct_cpuusage_write(struct cpuacct *ca, int cpu, u64 val)
135
+static void cpuacct_cpuusage_write(struct cpuacct *ca, int cpu)
136136 {
137
- struct cpuacct_usage *cpuusage = per_cpu_ptr(ca->cpuusage, cpu);
138
- int i;
137
+ u64 *cpuusage = per_cpu_ptr(ca->cpuusage, cpu);
138
+ u64 *cpustat = per_cpu_ptr(ca->cpustat, cpu)->cpustat;
139
+
140
+ /* Don't allow to reset global kernel_cpustat */
141
+ if (ca == &root_cpuacct)
142
+ return;
139143
140144 #ifndef CONFIG_64BIT
141145 /*
....@@ -143,9 +147,10 @@
143147 */
144148 raw_spin_lock_irq(&cpu_rq(cpu)->lock);
145149 #endif
146
-
147
- for (i = 0; i < CPUACCT_STAT_NSTATS; i++)
148
- cpuusage->usages[i] = val;
150
+ *cpuusage = 0;
151
+ cpustat[CPUTIME_USER] = cpustat[CPUTIME_NICE] = 0;
152
+ cpustat[CPUTIME_SYSTEM] = cpustat[CPUTIME_IRQ] = 0;
153
+ cpustat[CPUTIME_SOFTIRQ] = 0;
149154
150155 #ifndef CONFIG_64BIT
151156 raw_spin_unlock_irq(&cpu_rq(cpu)->lock);
....@@ -196,7 +201,7 @@
196201 return -EINVAL;
197202
198203 for_each_possible_cpu(cpu)
199
- cpuacct_cpuusage_write(ca, cpu, 0);
204
+ cpuacct_cpuusage_write(ca, cpu);
200205
201206 return 0;
202207 }
....@@ -243,25 +248,10 @@
243248 seq_puts(m, "\n");
244249
245250 for_each_possible_cpu(cpu) {
246
- struct cpuacct_usage *cpuusage = per_cpu_ptr(ca->cpuusage, cpu);
247
-
248251 seq_printf(m, "%d", cpu);
249
-
250
- for (index = 0; index < CPUACCT_STAT_NSTATS; index++) {
251
-#ifndef CONFIG_64BIT
252
- /*
253
- * Take rq->lock to make 64-bit read safe on 32-bit
254
- * platforms.
255
- */
256
- raw_spin_lock_irq(&cpu_rq(cpu)->lock);
257
-#endif
258
-
259
- seq_printf(m, " %llu", cpuusage->usages[index]);
260
-
261
-#ifndef CONFIG_64BIT
262
- raw_spin_unlock_irq(&cpu_rq(cpu)->lock);
263
-#endif
264
- }
252
+ for (index = 0; index < CPUACCT_STAT_NSTATS; index++)
253
+ seq_printf(m, " %llu",
254
+ cpuacct_cpuusage_read(ca, cpu, index));
265255 seq_puts(m, "\n");
266256 }
267257 return 0;
....@@ -338,19 +328,13 @@
338328 */
339329 void cpuacct_charge(struct task_struct *tsk, u64 cputime)
340330 {
331
+ unsigned int cpu = task_cpu(tsk);
341332 struct cpuacct *ca;
342
- int index = CPUACCT_STAT_SYSTEM;
343
- struct pt_regs *regs = get_irq_regs() ? : task_pt_regs(tsk);
344333
345
- if (regs && user_mode(regs))
346
- index = CPUACCT_STAT_USER;
347
-
348
- rcu_read_lock();
334
+ lockdep_assert_held(&cpu_rq(cpu)->lock);
349335
350336 for (ca = task_ca(tsk); ca; ca = parent_ca(ca))
351
- __this_cpu_add(ca->cpuusage->usages[index], cputime);
352
-
353
- rcu_read_unlock();
337
+ *per_cpu_ptr(ca->cpuusage, cpu) += cputime;
354338 }
355339
356340 /*