~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/kernel/sched/cpuacct.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /kernel/sched/cpuacct.c (Version linux-6.12-rc7) and /kernel/sched/cpuacct.c (Version linux-5.4.284)


** Warning: Cannot open xref database.

  1 // SPDX-License-Identifier: GPL-2.0                 1 
  2                                                   
  3 /*                                                
  4  * CPU accounting code for task groups.           
  5  *                                                
  6  * Based on the work by Paul Menage (menage@go    
  7  * (balbir@in.ibm.com).                           
  8  */                                               
  9                                                   
 10 /* Time spent by the tasks of the CPU accounti    
 11 enum cpuacct_stat_index {                         
 12         CPUACCT_STAT_USER,      /* ... user mo    
 13         CPUACCT_STAT_SYSTEM,    /* ... kernel     
 14                                                   
 15         CPUACCT_STAT_NSTATS,                      
 16 };                                                
 17                                                   
 18 static const char * const cpuacct_stat_desc[]     
 19         [CPUACCT_STAT_USER] = "user",             
 20         [CPUACCT_STAT_SYSTEM] = "system",         
 21 };                                                
 22                                                   
 23 /* track CPU usage of a group of tasks and its    
 24 struct cpuacct {                                  
 25         struct cgroup_subsys_state      css;      
 26         /* cpuusage holds pointer to a u64-typ    
 27         u64 __percpu    *cpuusage;                
 28         struct kernel_cpustat __percpu  *cpust    
 29 };                                                
 30                                                   
 31 static inline struct cpuacct *css_ca(struct cg    
 32 {                                                 
 33         return css ? container_of(css, struct     
 34 }                                                 
 35                                                   
 36 /* Return CPU accounting group to which this t    
 37 static inline struct cpuacct *task_ca(struct t    
 38 {                                                 
 39         return css_ca(task_css(tsk, cpuacct_cg    
 40 }                                                 
 41                                                   
 42 static inline struct cpuacct *parent_ca(struct    
 43 {                                                 
 44         return css_ca(ca->css.parent);            
 45 }                                                 
 46                                                   
 47 static DEFINE_PER_CPU(u64, root_cpuacct_cpuusa    
 48 static struct cpuacct root_cpuacct = {            
 49         .cpustat        = &kernel_cpustat,        
 50         .cpuusage       = &root_cpuacct_cpuusa    
 51 };                                                
 52                                                   
 53 /* Create a new CPU accounting group */           
 54 static struct cgroup_subsys_state *               
 55 cpuacct_css_alloc(struct cgroup_subsys_state *    
 56 {                                                 
 57         struct cpuacct *ca;                       
 58                                                   
 59         if (!parent_css)                          
 60                 return &root_cpuacct.css;         
 61                                                   
 62         ca = kzalloc(sizeof(*ca), GFP_KERNEL);    
 63         if (!ca)                                  
 64                 goto out;                         
 65                                                   
 66         ca->cpuusage = alloc_percpu(u64);         
 67         if (!ca->cpuusage)                        
 68                 goto out_free_ca;                 
 69                                                   
 70         ca->cpustat = alloc_percpu(struct kern    
 71         if (!ca->cpustat)                         
 72                 goto out_free_cpuusage;           
 73                                                   
 74         return &ca->css;                          
 75                                                   
 76 out_free_cpuusage:                                
 77         free_percpu(ca->cpuusage);                
 78 out_free_ca:                                      
 79         kfree(ca);                                
 80 out:                                              
 81         return ERR_PTR(-ENOMEM);                  
 82 }                                                 
 83                                                   
 84 /* Destroy an existing CPU accounting group */    
 85 static void cpuacct_css_free(struct cgroup_sub    
 86 {                                                 
 87         struct cpuacct *ca = css_ca(css);         
 88                                                   
 89         free_percpu(ca->cpustat);                 
 90         free_percpu(ca->cpuusage);                
 91         kfree(ca);                                
 92 }                                                 
 93                                                   
 94 static u64 cpuacct_cpuusage_read(struct cpuacc    
 95                                  enum cpuacct_    
 96 {                                                 
 97         u64 *cpuusage = per_cpu_ptr(ca->cpuusa    
 98         u64 *cpustat = per_cpu_ptr(ca->cpustat    
 99         u64 data;                                 
100                                                   
101         /*                                        
102          * We allow index == CPUACCT_STAT_NSTA    
103          * the sum of usages.                     
104          */                                       
105         if (WARN_ON_ONCE(index > CPUACCT_STAT_    
106                 return 0;                         
107                                                   
108 #ifndef CONFIG_64BIT                              
109         /*                                        
110          * Take rq->lock to make 64-bit read s    
111          */                                       
112         raw_spin_rq_lock_irq(cpu_rq(cpu));        
113 #endif                                            
114                                                   
115         switch (index) {                          
116         case CPUACCT_STAT_USER:                   
117                 data = cpustat[CPUTIME_USER] +    
118                 break;                            
119         case CPUACCT_STAT_SYSTEM:                 
120                 data = cpustat[CPUTIME_SYSTEM]    
121                         cpustat[CPUTIME_SOFTIR    
122                 break;                            
123         case CPUACCT_STAT_NSTATS:                 
124                 data = *cpuusage;                 
125                 break;                            
126         }                                         
127                                                   
128 #ifndef CONFIG_64BIT                              
129         raw_spin_rq_unlock_irq(cpu_rq(cpu));      
130 #endif                                            
131                                                   
132         return data;                              
133 }                                                 
134                                                   
135 static void cpuacct_cpuusage_write(struct cpua    
136 {                                                 
137         u64 *cpuusage = per_cpu_ptr(ca->cpuusa    
138         u64 *cpustat = per_cpu_ptr(ca->cpustat    
139                                                   
140         /* Don't allow to reset global kernel_    
141         if (ca == &root_cpuacct)                  
142                 return;                           
143                                                   
144 #ifndef CONFIG_64BIT                              
145         /*                                        
146          * Take rq->lock to make 64-bit write     
147          */                                       
148         raw_spin_rq_lock_irq(cpu_rq(cpu));        
149 #endif                                            
150         *cpuusage = 0;                            
151         cpustat[CPUTIME_USER] = cpustat[CPUTIM    
152         cpustat[CPUTIME_SYSTEM] = cpustat[CPUT    
153         cpustat[CPUTIME_SOFTIRQ] = 0;             
154                                                   
155 #ifndef CONFIG_64BIT                              
156         raw_spin_rq_unlock_irq(cpu_rq(cpu));      
157 #endif                                            
158 }                                                 
159                                                   
160 /* Return total CPU usage (in nanoseconds) of     
161 static u64 __cpuusage_read(struct cgroup_subsy    
162                            enum cpuacct_stat_i    
163 {                                                 
164         struct cpuacct *ca = css_ca(css);         
165         u64 totalcpuusage = 0;                    
166         int i;                                    
167                                                   
168         for_each_possible_cpu(i)                  
169                 totalcpuusage += cpuacct_cpuus    
170                                                   
171         return totalcpuusage;                     
172 }                                                 
173                                                   
174 static u64 cpuusage_user_read(struct cgroup_su    
175                               struct cftype *c    
176 {                                                 
177         return __cpuusage_read(css, CPUACCT_ST    
178 }                                                 
179                                                   
180 static u64 cpuusage_sys_read(struct cgroup_sub    
181                              struct cftype *cf    
182 {                                                 
183         return __cpuusage_read(css, CPUACCT_ST    
184 }                                                 
185                                                   
186 static u64 cpuusage_read(struct cgroup_subsys_    
187 {                                                 
188         return __cpuusage_read(css, CPUACCT_ST    
189 }                                                 
190                                                   
191 static int cpuusage_write(struct cgroup_subsys    
192                           u64 val)                
193 {                                                 
194         struct cpuacct *ca = css_ca(css);         
195         int cpu;                                  
196                                                   
197         /*                                        
198          * Only allow '' here to do a reset.      
199          */                                       
200         if (val)                                  
201                 return -EINVAL;                   
202                                                   
203         for_each_possible_cpu(cpu)                
204                 cpuacct_cpuusage_write(ca, cpu    
205                                                   
206         return 0;                                 
207 }                                                 
208                                                   
209 static int __cpuacct_percpu_seq_show(struct se    
210                                      enum cpua    
211 {                                                 
212         struct cpuacct *ca = css_ca(seq_css(m)    
213         u64 percpu;                               
214         int i;                                    
215                                                   
216         for_each_possible_cpu(i) {                
217                 percpu = cpuacct_cpuusage_read    
218                 seq_printf(m, "%llu ", (unsign    
219         }                                         
220         seq_printf(m, "\n");                      
221         return 0;                                 
222 }                                                 
223                                                   
224 static int cpuacct_percpu_user_seq_show(struct    
225 {                                                 
226         return __cpuacct_percpu_seq_show(m, CP    
227 }                                                 
228                                                   
229 static int cpuacct_percpu_sys_seq_show(struct     
230 {                                                 
231         return __cpuacct_percpu_seq_show(m, CP    
232 }                                                 
233                                                   
234 static int cpuacct_percpu_seq_show(struct seq_    
235 {                                                 
236         return __cpuacct_percpu_seq_show(m, CP    
237 }                                                 
238                                                   
239 static int cpuacct_all_seq_show(struct seq_fil    
240 {                                                 
241         struct cpuacct *ca = css_ca(seq_css(m)    
242         int index;                                
243         int cpu;                                  
244                                                   
245         seq_puts(m, "cpu");                       
246         for (index = 0; index < CPUACCT_STAT_N    
247                 seq_printf(m, " %s", cpuacct_s    
248         seq_puts(m, "\n");                        
249                                                   
250         for_each_possible_cpu(cpu) {              
251                 seq_printf(m, "%d", cpu);         
252                 for (index = 0; index < CPUACC    
253                         seq_printf(m, " %llu",    
254                                    cpuacct_cpu    
255                 seq_puts(m, "\n");                
256         }                                         
257         return 0;                                 
258 }                                                 
259                                                   
260 static int cpuacct_stats_show(struct seq_file     
261 {                                                 
262         struct cpuacct *ca = css_ca(seq_css(sf    
263         struct task_cputime cputime;              
264         u64 val[CPUACCT_STAT_NSTATS];             
265         int cpu;                                  
266         int stat;                                 
267                                                   
268         memset(&cputime, 0, sizeof(cputime));     
269         for_each_possible_cpu(cpu) {              
270                 u64 *cpustat = per_cpu_ptr(ca-    
271                                                   
272                 cputime.utime += cpustat[CPUTI    
273                 cputime.utime += cpustat[CPUTI    
274                 cputime.stime += cpustat[CPUTI    
275                 cputime.stime += cpustat[CPUTI    
276                 cputime.stime += cpustat[CPUTI    
277                                                   
278                 cputime.sum_exec_runtime += *p    
279         }                                         
280                                                   
281         cputime_adjust(&cputime, &seq_css(sf)-    
282                 &val[CPUACCT_STAT_USER], &val[    
283                                                   
284         for (stat = 0; stat < CPUACCT_STAT_NST    
285                 seq_printf(sf, "%s %llu\n", cp    
286                         nsec_to_clock_t(val[st    
287         }                                         
288                                                   
289         return 0;                                 
290 }                                                 
291                                                   
292 static struct cftype files[] = {                  
293         {                                         
294                 .name = "usage",                  
295                 .read_u64 = cpuusage_read,        
296                 .write_u64 = cpuusage_write,      
297         },                                        
298         {                                         
299                 .name = "usage_user",             
300                 .read_u64 = cpuusage_user_read    
301         },                                        
302         {                                         
303                 .name = "usage_sys",              
304                 .read_u64 = cpuusage_sys_read,    
305         },                                        
306         {                                         
307                 .name = "usage_percpu",           
308                 .seq_show = cpuacct_percpu_seq    
309         },                                        
310         {                                         
311                 .name = "usage_percpu_user",      
312                 .seq_show = cpuacct_percpu_use    
313         },                                        
314         {                                         
315                 .name = "usage_percpu_sys",       
316                 .seq_show = cpuacct_percpu_sys    
317         },                                        
318         {                                         
319                 .name = "usage_all",              
320                 .seq_show = cpuacct_all_seq_sh    
321         },                                        
322         {                                         
323                 .name = "stat",                   
324                 .seq_show = cpuacct_stats_show    
325         },                                        
326         { }     /* terminate */                   
327 };                                                
328                                                   
329 /*                                                
330  * charge this task's execution time to its ac    
331  *                                                
332  * called with rq->lock held.                     
333  */                                               
334 void cpuacct_charge(struct task_struct *tsk, u    
335 {                                                 
336         unsigned int cpu = task_cpu(tsk);         
337         struct cpuacct *ca;                       
338                                                   
339         lockdep_assert_rq_held(cpu_rq(cpu));      
340                                                   
341         for (ca = task_ca(tsk); ca; ca = paren    
342                 *per_cpu_ptr(ca->cpuusage, cpu    
343 }                                                 
344                                                   
345 /*                                                
346  * Add user/system time to cpuacct.               
347  *                                                
348  * Note: it's the caller that updates the acco    
349  */                                               
350 void cpuacct_account_field(struct task_struct     
351 {                                                 
352         struct cpuacct *ca;                       
353                                                   
354         for (ca = task_ca(tsk); ca != &root_cp    
355                 __this_cpu_add(ca->cpustat->cp    
356 }                                                 
357                                                   
358 struct cgroup_subsys cpuacct_cgrp_subsys = {      
359         .css_alloc      = cpuacct_css_alloc,      
360         .css_free       = cpuacct_css_free,       
361         .legacy_cftypes = files,                  
362         .early_init     = true,                   
363 };                                                
364                                                   

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php