xref: /linux-6.15/include/linux/vtime.h (revision 08a36a48)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2dcbf832eSFrederic Weisbecker #ifndef _LINUX_KERNEL_VTIME_H
3dcbf832eSFrederic Weisbecker #define _LINUX_KERNEL_VTIME_H
4dcbf832eSFrederic Weisbecker 
5b0493406SFrederic Weisbecker #include <linux/context_tracking_state.h>
6*6f922b89SSean Christopherson #include <linux/sched.h>
7*6f922b89SSean Christopherson 
8b0493406SFrederic Weisbecker /*
9b41c723bSSean Christopherson  * Common vtime APIs
10b41c723bSSean Christopherson  */
11b41c723bSSean Christopherson #ifdef CONFIG_VIRT_CPU_ACCOUNTING
12b41c723bSSean Christopherson extern void vtime_account_kernel(struct task_struct *tsk);
13b41c723bSSean Christopherson extern void vtime_account_idle(struct task_struct *tsk);
14b41c723bSSean Christopherson #endif /* !CONFIG_VIRT_CPU_ACCOUNTING */
15b41c723bSSean Christopherson 
16b41c723bSSean Christopherson #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
17b41c723bSSean Christopherson extern void vtime_user_enter(struct task_struct *tsk);
18b41c723bSSean Christopherson extern void vtime_user_exit(struct task_struct *tsk);
19b41c723bSSean Christopherson extern void vtime_guest_enter(struct task_struct *tsk);
20b41c723bSSean Christopherson extern void vtime_guest_exit(struct task_struct *tsk);
21b41c723bSSean Christopherson extern void vtime_init_idle(struct task_struct *tsk, int cpu);
22b41c723bSSean Christopherson #else /* !CONFIG_VIRT_CPU_ACCOUNTING_GEN  */
vtime_user_enter(struct task_struct * tsk)23b41c723bSSean Christopherson static inline void vtime_user_enter(struct task_struct *tsk) { }
vtime_user_exit(struct task_struct * tsk)24b41c723bSSean Christopherson static inline void vtime_user_exit(struct task_struct *tsk) { }
vtime_guest_enter(struct task_struct * tsk)25b41c723bSSean Christopherson static inline void vtime_guest_enter(struct task_struct *tsk) { }
vtime_guest_exit(struct task_struct * tsk)26b41c723bSSean Christopherson static inline void vtime_guest_exit(struct task_struct *tsk) { }
vtime_init_idle(struct task_struct * tsk,int cpu)27b41c723bSSean Christopherson static inline void vtime_init_idle(struct task_struct *tsk, int cpu) { }
28b41c723bSSean Christopherson #endif
29b41c723bSSean Christopherson 
30b41c723bSSean Christopherson #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
31b41c723bSSean Christopherson extern void vtime_account_irq(struct task_struct *tsk, unsigned int offset);
32b41c723bSSean Christopherson extern void vtime_account_softirq(struct task_struct *tsk);
33b41c723bSSean Christopherson extern void vtime_account_hardirq(struct task_struct *tsk);
34b41c723bSSean Christopherson extern void vtime_flush(struct task_struct *tsk);
35b41c723bSSean Christopherson #else /* !CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
vtime_account_irq(struct task_struct * tsk,unsigned int offset)36b41c723bSSean Christopherson static inline void vtime_account_irq(struct task_struct *tsk, unsigned int offset) { }
vtime_account_softirq(struct task_struct * tsk)37b41c723bSSean Christopherson static inline void vtime_account_softirq(struct task_struct *tsk) { }
vtime_account_hardirq(struct task_struct * tsk)38b41c723bSSean Christopherson static inline void vtime_account_hardirq(struct task_struct *tsk) { }
vtime_flush(struct task_struct * tsk)39b41c723bSSean Christopherson static inline void vtime_flush(struct task_struct *tsk) { }
40b41c723bSSean Christopherson #endif
41b41c723bSSean Christopherson 
42b41c723bSSean Christopherson /*
43e44fcb4bSFrederic Weisbecker  * vtime_accounting_enabled_this_cpu() definitions/declarations
44b0493406SFrederic Weisbecker  */
458612f17aSFrederic Weisbecker #if defined(CONFIG_VIRT_CPU_ACCOUNTING_NATIVE)
468d495477SFrederic Weisbecker 
vtime_accounting_enabled_this_cpu(void)47e44fcb4bSFrederic Weisbecker static inline bool vtime_accounting_enabled_this_cpu(void) { return true; }
488d495477SFrederic Weisbecker extern void vtime_task_switch(struct task_struct *prev);
498d495477SFrederic Weisbecker 
vtime_account_guest_enter(void)50*6f922b89SSean Christopherson static __always_inline void vtime_account_guest_enter(void)
51*6f922b89SSean Christopherson {
52*6f922b89SSean Christopherson 	vtime_account_kernel(current);
53*6f922b89SSean Christopherson 	current->flags |= PF_VCPU;
54*6f922b89SSean Christopherson }
55*6f922b89SSean Christopherson 
vtime_account_guest_exit(void)56*6f922b89SSean Christopherson static __always_inline void vtime_account_guest_exit(void)
57*6f922b89SSean Christopherson {
58*6f922b89SSean Christopherson 	vtime_account_kernel(current);
59*6f922b89SSean Christopherson 	current->flags &= ~PF_VCPU;
60*6f922b89SSean Christopherson }
61*6f922b89SSean Christopherson 
628612f17aSFrederic Weisbecker #elif defined(CONFIG_VIRT_CPU_ACCOUNTING_GEN)
638d495477SFrederic Weisbecker 
64e5925394SFrederic Weisbecker /*
65e5925394SFrederic Weisbecker  * Checks if vtime is enabled on some CPU. Cputime readers want to be careful
66e5925394SFrederic Weisbecker  * in that case and compute the tickless cputime.
67e5925394SFrederic Weisbecker  * For now vtime state is tied to context tracking. We might want to decouple
68e5925394SFrederic Weisbecker  * those later if necessary.
69e5925394SFrederic Weisbecker  */
vtime_accounting_enabled(void)70e5925394SFrederic Weisbecker static inline bool vtime_accounting_enabled(void)
71e5925394SFrederic Weisbecker {
7274c57875SFrederic Weisbecker 	return context_tracking_enabled();
73e5925394SFrederic Weisbecker }
74e5925394SFrederic Weisbecker 
vtime_accounting_enabled_cpu(int cpu)759adbb9ddSFrederic Weisbecker static inline bool vtime_accounting_enabled_cpu(int cpu)
76b0493406SFrederic Weisbecker {
77023e9debSFrederic Weisbecker 	return context_tracking_enabled_cpu(cpu);
78b0493406SFrederic Weisbecker }
79b0493406SFrederic Weisbecker 
vtime_accounting_enabled_this_cpu(void)809adbb9ddSFrederic Weisbecker static inline bool vtime_accounting_enabled_this_cpu(void)
819adbb9ddSFrederic Weisbecker {
82023e9debSFrederic Weisbecker 	return context_tracking_enabled_this_cpu();
83b0493406SFrederic Weisbecker }
84b0493406SFrederic Weisbecker 
858d495477SFrederic Weisbecker extern void vtime_task_switch_generic(struct task_struct *prev);
868d495477SFrederic Weisbecker 
vtime_task_switch(struct task_struct * prev)878d495477SFrederic Weisbecker static inline void vtime_task_switch(struct task_struct *prev)
888d495477SFrederic Weisbecker {
89e44fcb4bSFrederic Weisbecker 	if (vtime_accounting_enabled_this_cpu())
908d495477SFrederic Weisbecker 		vtime_task_switch_generic(prev);
918d495477SFrederic Weisbecker }
928d495477SFrederic Weisbecker 
vtime_account_guest_enter(void)93*6f922b89SSean Christopherson static __always_inline void vtime_account_guest_enter(void)
94*6f922b89SSean Christopherson {
95*6f922b89SSean Christopherson 	if (vtime_accounting_enabled_this_cpu())
96*6f922b89SSean Christopherson 		vtime_guest_enter(current);
97*6f922b89SSean Christopherson 	else
98*6f922b89SSean Christopherson 		current->flags |= PF_VCPU;
99*6f922b89SSean Christopherson }
100*6f922b89SSean Christopherson 
vtime_account_guest_exit(void)101*6f922b89SSean Christopherson static __always_inline void vtime_account_guest_exit(void)
102*6f922b89SSean Christopherson {
103*6f922b89SSean Christopherson 	if (vtime_accounting_enabled_this_cpu())
104*6f922b89SSean Christopherson 		vtime_guest_exit(current);
105*6f922b89SSean Christopherson 	else
106*6f922b89SSean Christopherson 		current->flags &= ~PF_VCPU;
107*6f922b89SSean Christopherson }
108*6f922b89SSean Christopherson 
1098d495477SFrederic Weisbecker #else /* !CONFIG_VIRT_CPU_ACCOUNTING */
1108d495477SFrederic Weisbecker 
vtime_accounting_enabled_this_cpu(void)111e44fcb4bSFrederic Weisbecker static inline bool vtime_accounting_enabled_this_cpu(void) { return false; }
vtime_task_switch(struct task_struct * prev)1128d495477SFrederic Weisbecker static inline void vtime_task_switch(struct task_struct *prev) { }
1138d495477SFrederic Weisbecker 
vtime_account_guest_enter(void)114*6f922b89SSean Christopherson static __always_inline void vtime_account_guest_enter(void)
115*6f922b89SSean Christopherson {
116*6f922b89SSean Christopherson 	current->flags |= PF_VCPU;
117*6f922b89SSean Christopherson }
118*6f922b89SSean Christopherson 
vtime_account_guest_exit(void)119*6f922b89SSean Christopherson static __always_inline void vtime_account_guest_exit(void)
120*6f922b89SSean Christopherson {
121*6f922b89SSean Christopherson 	current->flags &= ~PF_VCPU;
122*6f922b89SSean Christopherson }
123*6f922b89SSean Christopherson 
1248d495477SFrederic Weisbecker #endif
125b0493406SFrederic Weisbecker 
1268612f17aSFrederic Weisbecker 
1273e1df4f5SFrederic Weisbecker #ifdef CONFIG_IRQ_TIME_ACCOUNTING
128d3759e71SFrederic Weisbecker extern void irqtime_account_irq(struct task_struct *tsk, unsigned int offset);
129dcbf832eSFrederic Weisbecker #else
irqtime_account_irq(struct task_struct * tsk,unsigned int offset)130d3759e71SFrederic Weisbecker static inline void irqtime_account_irq(struct task_struct *tsk, unsigned int offset) { }
131dcbf832eSFrederic Weisbecker #endif
132dcbf832eSFrederic Weisbecker 
account_softirq_enter(struct task_struct * tsk)133d3759e71SFrederic Weisbecker static inline void account_softirq_enter(struct task_struct *tsk)
134fa5058f3SFrederic Weisbecker {
135d3759e71SFrederic Weisbecker 	vtime_account_irq(tsk, SOFTIRQ_OFFSET);
136d3759e71SFrederic Weisbecker 	irqtime_account_irq(tsk, SOFTIRQ_OFFSET);
137fa5058f3SFrederic Weisbecker }
138fa5058f3SFrederic Weisbecker 
account_softirq_exit(struct task_struct * tsk)139d3759e71SFrederic Weisbecker static inline void account_softirq_exit(struct task_struct *tsk)
140fa5058f3SFrederic Weisbecker {
141d3759e71SFrederic Weisbecker 	vtime_account_softirq(tsk);
142d3759e71SFrederic Weisbecker 	irqtime_account_irq(tsk, 0);
143d3759e71SFrederic Weisbecker }
144d3759e71SFrederic Weisbecker 
account_hardirq_enter(struct task_struct * tsk)145d3759e71SFrederic Weisbecker static inline void account_hardirq_enter(struct task_struct *tsk)
146d3759e71SFrederic Weisbecker {
147d3759e71SFrederic Weisbecker 	vtime_account_irq(tsk, HARDIRQ_OFFSET);
148d3759e71SFrederic Weisbecker 	irqtime_account_irq(tsk, HARDIRQ_OFFSET);
149d3759e71SFrederic Weisbecker }
150d3759e71SFrederic Weisbecker 
account_hardirq_exit(struct task_struct * tsk)151d3759e71SFrederic Weisbecker static inline void account_hardirq_exit(struct task_struct *tsk)
152d3759e71SFrederic Weisbecker {
153d3759e71SFrederic Weisbecker 	vtime_account_hardirq(tsk);
154d3759e71SFrederic Weisbecker 	irqtime_account_irq(tsk, 0);
155fa5058f3SFrederic Weisbecker }
156fa5058f3SFrederic Weisbecker 
157dcbf832eSFrederic Weisbecker #endif /* _LINUX_KERNEL_VTIME_H */
158