vtime.h (4709B)
1/* SPDX-License-Identifier: GPL-2.0 */ 2#ifndef _LINUX_KERNEL_VTIME_H 3#define _LINUX_KERNEL_VTIME_H 4 5#include <linux/context_tracking_state.h> 6#include <linux/sched.h> 7 8#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE 9#include <asm/vtime.h> 10#endif 11 12/* 13 * 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); 18#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/* 48 * vtime_accounting_enabled_this_cpu() definitions/declarations 49 */ 50#if defined(CONFIG_VIRT_CPU_ACCOUNTING_NATIVE) 51 52static inline bool vtime_accounting_enabled_this_cpu(void) { return true; } 53extern void vtime_task_switch(struct task_struct *prev); 54 55static __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 67#elif defined(CONFIG_VIRT_CPU_ACCOUNTING_GEN) 68 69/* 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{ 77 return context_tracking_enabled(); 78} 79 80static inline bool vtime_accounting_enabled_cpu(int cpu) 81{ 82 return context_tracking_enabled_cpu(cpu); 83} 84 85static inline bool vtime_accounting_enabled_this_cpu(void) 86{ 87 return context_tracking_enabled_this_cpu(); 88} 89 90extern void vtime_task_switch_generic(struct task_struct *prev); 91 92static inline void vtime_task_switch(struct task_struct *prev) 93{ 94 if (vtime_accounting_enabled_this_cpu()) 95 vtime_task_switch_generic(prev); 96} 97 98static __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 114#else /* !CONFIG_VIRT_CPU_ACCOUNTING */ 115 116static inline bool vtime_accounting_enabled_this_cpu(void) { return false; } 117static inline void vtime_task_switch(struct task_struct *prev) { } 118 119static __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 129#endif 130 131 132#ifdef CONFIG_IRQ_TIME_ACCOUNTING 133extern void irqtime_account_irq(struct task_struct *tsk, unsigned int offset); 134#else 135static inline void irqtime_account_irq(struct task_struct *tsk, unsigned int offset) { } 136#endif 137 138static inline void account_softirq_enter(struct task_struct *tsk) 139{ 140 vtime_account_irq(tsk, SOFTIRQ_OFFSET); 141 irqtime_account_irq(tsk, SOFTIRQ_OFFSET); 142} 143 144static inline void account_softirq_exit(struct task_struct *tsk) 145{ 146 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); 160} 161 162#endif /* _LINUX_KERNEL_VTIME_H */