blob: 3684487d01e1c697287ed5f34975424732470d06 [file] [log] [blame]
Greg Kroah-Hartmanb2441312017-11-01 15:07:57 +01001/* SPDX-License-Identifier: GPL-2.0 */
Frederic Weisbeckerdcbf8322012-10-05 23:07:19 +02002#ifndef _LINUX_KERNEL_VTIME_H
3#define _LINUX_KERNEL_VTIME_H
4
Frederic Weisbeckerb0493402013-07-12 03:10:15 +02005#include <linux/context_tracking_state.h>
Sean Christopherson6f922b82021-05-04 17:27:32 -07006#include <linux/sched.h>
7
Frederic Weisbeckera5725ac2013-07-16 18:50:52 +02008#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
9#include <asm/vtime.h>
10#endif
11
Frederic Weisbeckerb0493402013-07-12 03:10:15 +020012/*
Sean Christophersonb41c7232021-05-04 17:27:31 -070013 * Common vtime APIs
14 */
15#ifdef CONFIG_VIRT_CPU_ACCOUNTING
16extern void vtime_account_kernel(struct task_struct *tsk);
17extern void vtime_account_idle(struct task_struct *tsk);
Sean Christophersonb41c7232021-05-04 17:27:31 -070018#endif /* !CONFIG_VIRT_CPU_ACCOUNTING */
19
20#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
21extern void arch_vtime_task_switch(struct task_struct *tsk);
22extern void vtime_user_enter(struct task_struct *tsk);
23extern void vtime_user_exit(struct task_struct *tsk);
24extern void vtime_guest_enter(struct task_struct *tsk);
25extern void vtime_guest_exit(struct task_struct *tsk);
26extern void vtime_init_idle(struct task_struct *tsk, int cpu);
27#else /* !CONFIG_VIRT_CPU_ACCOUNTING_GEN */
28static inline void vtime_user_enter(struct task_struct *tsk) { }
29static inline void vtime_user_exit(struct task_struct *tsk) { }
30static inline void vtime_guest_enter(struct task_struct *tsk) { }
31static inline void vtime_guest_exit(struct task_struct *tsk) { }
32static inline void vtime_init_idle(struct task_struct *tsk, int cpu) { }
33#endif
34
35#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
36extern void vtime_account_irq(struct task_struct *tsk, unsigned int offset);
37extern void vtime_account_softirq(struct task_struct *tsk);
38extern void vtime_account_hardirq(struct task_struct *tsk);
39extern void vtime_flush(struct task_struct *tsk);
40#else /* !CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
41static inline void vtime_account_irq(struct task_struct *tsk, unsigned int offset) { }
42static inline void vtime_account_softirq(struct task_struct *tsk) { }
43static inline void vtime_account_hardirq(struct task_struct *tsk) { }
44static inline void vtime_flush(struct task_struct *tsk) { }
45#endif
46
47/*
Frederic Weisbeckere44fcb42019-10-16 04:56:54 +020048 * vtime_accounting_enabled_this_cpu() definitions/declarations
Frederic Weisbeckerb0493402013-07-12 03:10:15 +020049 */
Frederic Weisbecker8612f172016-07-13 16:50:04 +020050#if defined(CONFIG_VIRT_CPU_ACCOUNTING_NATIVE)
Frederic Weisbecker8d495472019-10-03 18:17:45 +020051
Frederic Weisbeckere44fcb42019-10-16 04:56:54 +020052static inline bool vtime_accounting_enabled_this_cpu(void) { return true; }
Frederic Weisbecker8d495472019-10-03 18:17:45 +020053extern void vtime_task_switch(struct task_struct *prev);
54
Sean Christopherson6f922b82021-05-04 17:27:32 -070055static __always_inline void vtime_account_guest_enter(void)
56{
57 vtime_account_kernel(current);
58 current->flags |= PF_VCPU;
59}
60
61static __always_inline void vtime_account_guest_exit(void)
62{
63 vtime_account_kernel(current);
64 current->flags &= ~PF_VCPU;
65}
66
Frederic Weisbecker8612f172016-07-13 16:50:04 +020067#elif defined(CONFIG_VIRT_CPU_ACCOUNTING_GEN)
Frederic Weisbecker8d495472019-10-03 18:17:45 +020068
Frederic Weisbeckere5925392015-11-19 16:47:33 +010069/*
70 * Checks if vtime is enabled on some CPU. Cputime readers want to be careful
71 * in that case and compute the tickless cputime.
72 * For now vtime state is tied to context tracking. We might want to decouple
73 * those later if necessary.
74 */
75static inline bool vtime_accounting_enabled(void)
76{
Frederic Weisbecker74c57872019-10-16 04:56:51 +020077 return context_tracking_enabled();
Frederic Weisbeckere5925392015-11-19 16:47:33 +010078}
79
Frederic Weisbecker9adbb9d2019-10-16 04:56:55 +020080static inline bool vtime_accounting_enabled_cpu(int cpu)
81{
Frederic Weisbecker023e9de2019-10-16 04:56:56 +020082 return context_tracking_enabled_cpu(cpu);
Frederic Weisbecker9adbb9d2019-10-16 04:56:55 +020083}
84
Frederic Weisbeckere44fcb42019-10-16 04:56:54 +020085static inline bool vtime_accounting_enabled_this_cpu(void)
Frederic Weisbeckerb0493402013-07-12 03:10:15 +020086{
Frederic Weisbecker023e9de2019-10-16 04:56:56 +020087 return context_tracking_enabled_this_cpu();
Frederic Weisbeckerb0493402013-07-12 03:10:15 +020088}
Frederic Weisbeckerb0493402013-07-12 03:10:15 +020089
Frederic Weisbecker8d495472019-10-03 18:17:45 +020090extern void vtime_task_switch_generic(struct task_struct *prev);
91
92static inline void vtime_task_switch(struct task_struct *prev)
93{
Frederic Weisbeckere44fcb42019-10-16 04:56:54 +020094 if (vtime_accounting_enabled_this_cpu())
Frederic Weisbecker8d495472019-10-03 18:17:45 +020095 vtime_task_switch_generic(prev);
96}
97
Sean Christopherson6f922b82021-05-04 17:27:32 -070098static __always_inline void vtime_account_guest_enter(void)
99{
100 if (vtime_accounting_enabled_this_cpu())
101 vtime_guest_enter(current);
102 else
103 current->flags |= PF_VCPU;
104}
105
106static __always_inline void vtime_account_guest_exit(void)
107{
108 if (vtime_accounting_enabled_this_cpu())
109 vtime_guest_exit(current);
110 else
111 current->flags &= ~PF_VCPU;
112}
113
Frederic Weisbecker8d495472019-10-03 18:17:45 +0200114#else /* !CONFIG_VIRT_CPU_ACCOUNTING */
115
Frederic Weisbeckere44fcb42019-10-16 04:56:54 +0200116static inline bool vtime_accounting_enabled_this_cpu(void) { return false; }
Frederic Weisbecker8d495472019-10-03 18:17:45 +0200117static inline void vtime_task_switch(struct task_struct *prev) { }
118
Sean Christopherson6f922b82021-05-04 17:27:32 -0700119static __always_inline void vtime_account_guest_enter(void)
120{
121 current->flags |= PF_VCPU;
122}
123
124static __always_inline void vtime_account_guest_exit(void)
125{
126 current->flags &= ~PF_VCPU;
127}
128
Frederic Weisbecker8d495472019-10-03 18:17:45 +0200129#endif
Frederic Weisbeckerb0493402013-07-12 03:10:15 +0200130
Frederic Weisbecker8612f172016-07-13 16:50:04 +0200131
Frederic Weisbecker3e1df4f52012-10-06 05:23:22 +0200132#ifdef CONFIG_IRQ_TIME_ACCOUNTING
Frederic Weisbeckerd3759e72020-12-02 12:57:31 +0100133extern void irqtime_account_irq(struct task_struct *tsk, unsigned int offset);
Frederic Weisbeckerdcbf8322012-10-05 23:07:19 +0200134#else
Frederic Weisbeckerd3759e72020-12-02 12:57:31 +0100135static inline void irqtime_account_irq(struct task_struct *tsk, unsigned int offset) { }
Frederic Weisbeckerdcbf8322012-10-05 23:07:19 +0200136#endif
137
Frederic Weisbeckerd3759e72020-12-02 12:57:31 +0100138static inline void account_softirq_enter(struct task_struct *tsk)
Frederic Weisbeckerfa5058f2012-10-06 04:07:19 +0200139{
Frederic Weisbeckerd3759e72020-12-02 12:57:31 +0100140 vtime_account_irq(tsk, SOFTIRQ_OFFSET);
141 irqtime_account_irq(tsk, SOFTIRQ_OFFSET);
Frederic Weisbeckerfa5058f2012-10-06 04:07:19 +0200142}
143
Frederic Weisbeckerd3759e72020-12-02 12:57:31 +0100144static inline void account_softirq_exit(struct task_struct *tsk)
Frederic Weisbeckerfa5058f2012-10-06 04:07:19 +0200145{
Frederic Weisbeckerd3759e72020-12-02 12:57:31 +0100146 vtime_account_softirq(tsk);
147 irqtime_account_irq(tsk, 0);
148}
149
150static inline void account_hardirq_enter(struct task_struct *tsk)
151{
152 vtime_account_irq(tsk, HARDIRQ_OFFSET);
153 irqtime_account_irq(tsk, HARDIRQ_OFFSET);
154}
155
156static inline void account_hardirq_exit(struct task_struct *tsk)
157{
158 vtime_account_hardirq(tsk);
159 irqtime_account_irq(tsk, 0);
Frederic Weisbeckerfa5058f2012-10-06 04:07:19 +0200160}
161
Frederic Weisbeckerdcbf8322012-10-05 23:07:19 +0200162#endif /* _LINUX_KERNEL_VTIME_H */