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 #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE 7 #include <asm/vtime.h> 8 #endif 9 10 11 struct task_struct; 12 13 /* 14 * Common vtime APIs 15 */ 16 #ifdef CONFIG_VIRT_CPU_ACCOUNTING 17 extern void vtime_account_kernel(struct task_struct *tsk); 18 extern void vtime_account_idle(struct task_struct *tsk); 19 #else /* !CONFIG_VIRT_CPU_ACCOUNTING */ 20 static inline void vtime_account_kernel(struct task_struct *tsk) { } 21 #endif /* !CONFIG_VIRT_CPU_ACCOUNTING */ 22 23 #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN 24 extern void arch_vtime_task_switch(struct task_struct *tsk); 25 extern void vtime_user_enter(struct task_struct *tsk); 26 extern void vtime_user_exit(struct task_struct *tsk); 27 extern void vtime_guest_enter(struct task_struct *tsk); 28 extern void vtime_guest_exit(struct task_struct *tsk); 29 extern void vtime_init_idle(struct task_struct *tsk, int cpu); 30 #else /* !CONFIG_VIRT_CPU_ACCOUNTING_GEN */ 31 static inline void vtime_user_enter(struct task_struct *tsk) { } 32 static inline void vtime_user_exit(struct task_struct *tsk) { } 33 static inline void vtime_guest_enter(struct task_struct *tsk) { } 34 static inline void vtime_guest_exit(struct task_struct *tsk) { } 35 static inline void vtime_init_idle(struct task_struct *tsk, int cpu) { } 36 #endif 37 38 #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE 39 extern void vtime_account_irq(struct task_struct *tsk, unsigned int offset); 40 extern void vtime_account_softirq(struct task_struct *tsk); 41 extern void vtime_account_hardirq(struct task_struct *tsk); 42 extern void vtime_flush(struct task_struct *tsk); 43 #else /* !CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ 44 static inline void vtime_account_irq(struct task_struct *tsk, unsigned int offset) { } 45 static inline void vtime_account_softirq(struct task_struct *tsk) { } 46 static inline void vtime_account_hardirq(struct task_struct *tsk) { } 47 static inline void vtime_flush(struct task_struct *tsk) { } 48 #endif 49 50 /* 51 * vtime_accounting_enabled_this_cpu() definitions/declarations 52 */ 53 #if defined(CONFIG_VIRT_CPU_ACCOUNTING_NATIVE) 54 55 static inline bool vtime_accounting_enabled_this_cpu(void) { return true; } 56 extern void vtime_task_switch(struct task_struct *prev); 57 58 #elif defined(CONFIG_VIRT_CPU_ACCOUNTING_GEN) 59 60 /* 61 * Checks if vtime is enabled on some CPU. Cputime readers want to be careful 62 * in that case and compute the tickless cputime. 63 * For now vtime state is tied to context tracking. We might want to decouple 64 * those later if necessary. 65 */ 66 static inline bool vtime_accounting_enabled(void) 67 { 68 return context_tracking_enabled(); 69 } 70 71 static inline bool vtime_accounting_enabled_cpu(int cpu) 72 { 73 return context_tracking_enabled_cpu(cpu); 74 } 75 76 static inline bool vtime_accounting_enabled_this_cpu(void) 77 { 78 return context_tracking_enabled_this_cpu(); 79 } 80 81 extern void vtime_task_switch_generic(struct task_struct *prev); 82 83 static inline void vtime_task_switch(struct task_struct *prev) 84 { 85 if (vtime_accounting_enabled_this_cpu()) 86 vtime_task_switch_generic(prev); 87 } 88 89 #else /* !CONFIG_VIRT_CPU_ACCOUNTING */ 90 91 static inline bool vtime_accounting_enabled_cpu(int cpu) {return false; } 92 static inline bool vtime_accounting_enabled_this_cpu(void) { return false; } 93 static inline void vtime_task_switch(struct task_struct *prev) { } 94 95 #endif 96 97 98 #ifdef CONFIG_IRQ_TIME_ACCOUNTING 99 extern void irqtime_account_irq(struct task_struct *tsk, unsigned int offset); 100 #else 101 static inline void irqtime_account_irq(struct task_struct *tsk, unsigned int offset) { } 102 #endif 103 104 static inline void account_softirq_enter(struct task_struct *tsk) 105 { 106 vtime_account_irq(tsk, SOFTIRQ_OFFSET); 107 irqtime_account_irq(tsk, SOFTIRQ_OFFSET); 108 } 109 110 static inline void account_softirq_exit(struct task_struct *tsk) 111 { 112 vtime_account_softirq(tsk); 113 irqtime_account_irq(tsk, 0); 114 } 115 116 static inline void account_hardirq_enter(struct task_struct *tsk) 117 { 118 vtime_account_irq(tsk, HARDIRQ_OFFSET); 119 irqtime_account_irq(tsk, HARDIRQ_OFFSET); 120 } 121 122 static inline void account_hardirq_exit(struct task_struct *tsk) 123 { 124 vtime_account_hardirq(tsk); 125 irqtime_account_irq(tsk, 0); 126 } 127 128 #endif /* _LINUX_KERNEL_VTIME_H */ 129