xref: /linux/include/linux/kernel_stat.h (revision 6199f9999a9b62b2b84a1bf5b52a9fd0bb8de5af)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _LINUX_KERNEL_STAT_H
3 #define _LINUX_KERNEL_STAT_H
4 
5 #include <linux/smp.h>
6 #include <linux/threads.h>
7 #include <linux/percpu.h>
8 #include <linux/interrupt.h>
9 #include <linux/sched.h>
10 #include <linux/vtime.h>
11 #include <asm/irq.h>
12 
13 /*
14  * 'kernel_stat.h' contains the definitions needed for doing
15  * some kernel statistics (CPU usage, context switches ...),
16  * used by rstatd/perfmeter
17  */
18 
19 enum cpu_usage_stat {
20 	CPUTIME_USER,
21 	CPUTIME_NICE,
22 	CPUTIME_SYSTEM,
23 	CPUTIME_SOFTIRQ,
24 	CPUTIME_IRQ,
25 	CPUTIME_IDLE,
26 	CPUTIME_IOWAIT,
27 	CPUTIME_STEAL,
28 	CPUTIME_GUEST,
29 	CPUTIME_GUEST_NICE,
30 #ifdef CONFIG_SCHED_CORE
31 	CPUTIME_FORCEIDLE,
32 #endif
33 	NR_STATS,
34 };
35 
36 struct kernel_cpustat {
37 #ifdef CONFIG_NO_HZ_COMMON
38 	bool		idle_dyntick;
39 	bool		idle_elapse;
40 	seqcount_t	idle_sleeptime_seq;
41 	u64		idle_entrytime;
42 	u64		idle_stealtime[2];
43 #endif
44 	u64		cpustat[NR_STATS];
45 };
46 
47 struct kernel_stat {
48 	unsigned long irqs_sum;
49 	unsigned int softirqs[NR_SOFTIRQS];
50 };
51 
52 DECLARE_PER_CPU(struct kernel_stat, kstat);
53 DECLARE_PER_CPU(struct kernel_cpustat, kernel_cpustat);
54 
55 /* Must have preemption disabled for this to be meaningful. */
56 #define kstat_this_cpu this_cpu_ptr(&kstat)
57 #define kcpustat_this_cpu this_cpu_ptr(&kernel_cpustat)
58 #define kstat_cpu(cpu) per_cpu(kstat, cpu)
59 #define kcpustat_cpu(cpu) per_cpu(kernel_cpustat, cpu)
60 
61 extern unsigned long long nr_context_switches_cpu(int cpu);
62 extern unsigned long long nr_context_switches(void);
63 
64 extern unsigned int kstat_irqs_cpu(unsigned int irq, int cpu);
65 extern void kstat_incr_irq_this_cpu(unsigned int irq);
66 
67 static inline void kstat_incr_softirqs_this_cpu(unsigned int irq)
68 {
69 	__this_cpu_inc(kstat.softirqs[irq]);
70 }
71 
72 static inline unsigned int kstat_softirqs_cpu(unsigned int irq, int cpu)
73 {
74        return kstat_cpu(cpu).softirqs[irq];
75 }
76 
77 static inline unsigned int kstat_cpu_softirqs_sum(int cpu)
78 {
79 	int i;
80 	unsigned int sum = 0;
81 
82 	for (i = 0; i < NR_SOFTIRQS; i++)
83 		sum += kstat_softirqs_cpu(i, cpu);
84 
85 	return sum;
86 }
87 
88 #ifdef CONFIG_GENERIC_IRQ_STAT_SNAPSHOT
89 extern void kstat_snapshot_irqs(void);
90 extern unsigned int kstat_get_irq_since_snapshot(unsigned int irq);
91 #else
92 static inline void kstat_snapshot_irqs(void) { }
93 static inline unsigned int kstat_get_irq_since_snapshot(unsigned int irq) { return 0; }
94 #endif
95 
96 /*
97  * Number of interrupts per specific IRQ source, since bootup
98  */
99 extern unsigned int kstat_irqs_usr(unsigned int irq);
100 
101 /*
102  * Number of interrupts per cpu, since bootup
103  */
104 static inline unsigned long kstat_cpu_irqs_sum(unsigned int cpu)
105 {
106 	return kstat_cpu(cpu).irqs_sum;
107 }
108 
109 #ifdef CONFIG_NO_HZ_COMMON
110 extern void kcpustat_dyntick_start(u64 now);
111 extern void kcpustat_dyntick_stop(u64 now);
112 extern void kcpustat_irq_enter(u64 now);
113 extern void kcpustat_irq_exit(u64 now);
114 extern u64 kcpustat_field_idle(int cpu);
115 extern u64 kcpustat_field_iowait(int cpu);
116 
117 static inline bool kcpustat_idle_dyntick(void)
118 {
119 	return __this_cpu_read(kernel_cpustat.idle_dyntick);
120 }
121 #else
122 static inline u64 kcpustat_field_idle(int cpu)
123 {
124 	return kcpustat_cpu(cpu).cpustat[CPUTIME_IDLE];
125 }
126 static inline u64 kcpustat_field_iowait(int cpu)
127 {
128 	return kcpustat_cpu(cpu).cpustat[CPUTIME_IOWAIT];
129 }
130 
131 static inline bool kcpustat_idle_dyntick(void)
132 {
133 	return false;
134 }
135 #endif /* CONFIG_NO_HZ_COMMON */
136 
137 extern u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time);
138 extern u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_time);
139 
140 /* Fetch cputime values when vtime is disabled on a CPU */
141 static inline u64 kcpustat_field_default(enum cpu_usage_stat usage, int cpu)
142 {
143 	if (usage == CPUTIME_IDLE)
144 		return kcpustat_field_idle(cpu);
145 	if (usage == CPUTIME_IOWAIT)
146 		return kcpustat_field_iowait(cpu);
147 	return kcpustat_cpu(cpu).cpustat[usage];
148 }
149 
150 static inline void kcpustat_cpu_fetch_default(struct kernel_cpustat *dst, int cpu)
151 {
152 	*dst = kcpustat_cpu(cpu);
153 	dst->cpustat[CPUTIME_IDLE] = kcpustat_field_idle(cpu);
154 	dst->cpustat[CPUTIME_IOWAIT] = kcpustat_field_iowait(cpu);
155 }
156 
157 #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
158 extern u64 kcpustat_field(enum cpu_usage_stat usage, int cpu);
159 extern void kcpustat_cpu_fetch(struct kernel_cpustat *dst, int cpu);
160 #else
161 static inline u64 kcpustat_field(enum cpu_usage_stat usage, int cpu)
162 {
163 	return kcpustat_field_default(usage, cpu);
164 }
165 
166 static inline void kcpustat_cpu_fetch(struct kernel_cpustat *dst, int cpu)
167 {
168 	kcpustat_cpu_fetch_default(dst, cpu);
169 }
170 #endif /* !CONFIG_VIRT_CPU_ACCOUNTING_GEN */
171 
172 extern void account_user_time(struct task_struct *, u64);
173 extern void account_guest_time(struct task_struct *, u64);
174 extern void account_system_time(struct task_struct *, int, u64);
175 extern void account_system_index_time(struct task_struct *, u64,
176 				      enum cpu_usage_stat);
177 extern void account_steal_time(u64);
178 extern void account_idle_time(u64);
179 
180 #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
181 static inline void account_process_tick(struct task_struct *tsk, int user)
182 {
183 	if (!kcpustat_idle_dyntick())
184 		vtime_flush(tsk);
185 }
186 #else
187 extern void account_process_tick(struct task_struct *, int user);
188 #endif
189 
190 #ifdef CONFIG_SCHED_CORE
191 extern void __account_forceidle_time(struct task_struct *tsk, u64 delta);
192 #endif
193 
194 #endif /* _LINUX_KERNEL_STAT_H */
195