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