linux/include/linux/vtime.h
<<
>>
Prefs
   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 */
 163