Branch data Line data Source code
1 : : /* SPDX-License-Identifier: GPL-2.0 */ 2 : : #ifndef _LINUX_SCHED_CPUTIME_H 3 : : #define _LINUX_SCHED_CPUTIME_H 4 : : 5 : : #include <linux/sched/signal.h> 6 : : 7 : : /* 8 : : * cputime accounting APIs: 9 : : */ 10 : : 11 : : #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE 12 : : #include <asm/cputime.h> 13 : : 14 : : #ifndef cputime_to_nsecs 15 : : # define cputime_to_nsecs(__ct) \ 16 : : (cputime_to_usecs(__ct) * NSEC_PER_USEC) 17 : : #endif 18 : : #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ 19 : : 20 : : #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN 21 : : extern void task_cputime(struct task_struct *t, 22 : : u64 *utime, u64 *stime); 23 : : extern u64 task_gtime(struct task_struct *t); 24 : : #else 25 : : static inline void task_cputime(struct task_struct *t, 26 : : u64 *utime, u64 *stime) 27 : : { 28 : 2132648 : *utime = t->utime; 29 : 2132648 : *stime = t->stime; 30 : : } 31 : : 32 : : static inline u64 task_gtime(struct task_struct *t) 33 : : { 34 : 625714 : return t->gtime; 35 : : } 36 : : #endif 37 : : 38 : : #ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME 39 : : static inline void task_cputime_scaled(struct task_struct *t, 40 : : u64 *utimescaled, 41 : : u64 *stimescaled) 42 : : { 43 : : *utimescaled = t->utimescaled; 44 : : *stimescaled = t->stimescaled; 45 : : } 46 : : #else 47 : : static inline void task_cputime_scaled(struct task_struct *t, 48 : : u64 *utimescaled, 49 : : u64 *stimescaled) 50 : : { 51 : : task_cputime(t, utimescaled, stimescaled); 52 : : } 53 : : #endif 54 : : 55 : : extern void task_cputime_adjusted(struct task_struct *p, u64 *ut, u64 *st); 56 : : extern void thread_group_cputime_adjusted(struct task_struct *p, u64 *ut, u64 *st); 57 : : extern void cputime_adjust(struct task_cputime *curr, struct prev_cputime *prev, 58 : : u64 *ut, u64 *st); 59 : : 60 : : /* 61 : : * Thread group CPU time accounting. 62 : : */ 63 : : void thread_group_cputime(struct task_struct *tsk, struct task_cputime *times); 64 : : void thread_group_sample_cputime(struct task_struct *tsk, u64 *samples); 65 : : 66 : : /* 67 : : * The following are functions that support scheduler-internal time accounting. 68 : : * These functions are generally called at the timer tick. None of this depends 69 : : * on CONFIG_SCHEDSTATS. 70 : : */ 71 : : 72 : : /** 73 : : * get_running_cputimer - return &tsk->signal->cputimer if cputimers are active 74 : : * 75 : : * @tsk: Pointer to target task. 76 : : */ 77 : : #ifdef CONFIG_POSIX_TIMERS 78 : : static inline 79 : : struct thread_group_cputimer *get_running_cputimer(struct task_struct *tsk) 80 : : { 81 : 51937848 : struct thread_group_cputimer *cputimer = &tsk->signal->cputimer; 82 : : 83 : : /* 84 : : * Check whether posix CPU timers are active. If not the thread 85 : : * group accounting is not active either. Lockless check. 86 : : */ 87 [ - + - + ]: 51937848 : if (!READ_ONCE(tsk->signal->posix_cputimers.timers_active)) 88 : : return NULL; 89 : : 90 : : /* 91 : : * After we flush the task's sum_exec_runtime to sig->sum_sched_runtime 92 : : * in __exit_signal(), we won't account to the signal struct further 93 : : * cputime consumed by that task, even though the task can still be 94 : : * ticking after __exit_signal(). 95 : : * 96 : : * In order to keep a consistent behaviour between thread group cputime 97 : : * and thread group cputimer accounting, lets also ignore the cputime 98 : : * elapsing after __exit_signal() in any thread group timer running. 99 : : * 100 : : * This makes sure that POSIX CPU clocks and timers are synchronized, so 101 : : * that a POSIX CPU timer won't expire while the corresponding POSIX CPU 102 : : * clock delta is behind the expiring timer value. 103 : : */ 104 [ # # # # ]: 0 : if (unlikely(!tsk->sighand)) 105 : : return NULL; 106 : : 107 : : return cputimer; 108 : : } 109 : : #else 110 : : static inline 111 : : struct thread_group_cputimer *get_running_cputimer(struct task_struct *tsk) 112 : : { 113 : : return NULL; 114 : : } 115 : : #endif 116 : : 117 : : /** 118 : : * account_group_user_time - Maintain utime for a thread group. 119 : : * 120 : : * @tsk: Pointer to task structure. 121 : : * @cputime: Time value by which to increment the utime field of the 122 : : * thread_group_cputime structure. 123 : : * 124 : : * If thread group time is being maintained, get the structure for the 125 : : * running CPU and update the utime field there. 126 : : */ 127 : 2652770 : static inline void account_group_user_time(struct task_struct *tsk, 128 : : u64 cputime) 129 : : { 130 : : struct thread_group_cputimer *cputimer = get_running_cputimer(tsk); 131 : : 132 [ - + ]: 2652770 : if (!cputimer) 133 : 2652770 : return; 134 : : 135 : 0 : atomic64_add(cputime, &cputimer->cputime_atomic.utime); 136 : : } 137 : : 138 : : /** 139 : : * account_group_system_time - Maintain stime for a thread group. 140 : : * 141 : : * @tsk: Pointer to task structure. 142 : : * @cputime: Time value by which to increment the stime field of the 143 : : * thread_group_cputime structure. 144 : : * 145 : : * If thread group time is being maintained, get the structure for the 146 : : * running CPU and update the stime field there. 147 : : */ 148 : 9961066 : static inline void account_group_system_time(struct task_struct *tsk, 149 : : u64 cputime) 150 : : { 151 : : struct thread_group_cputimer *cputimer = get_running_cputimer(tsk); 152 : : 153 [ - + ]: 9961066 : if (!cputimer) 154 : 9961066 : return; 155 : : 156 : 0 : atomic64_add(cputime, &cputimer->cputime_atomic.stime); 157 : : } 158 : : 159 : : /** 160 : : * account_group_exec_runtime - Maintain exec runtime for a thread group. 161 : : * 162 : : * @tsk: Pointer to task structure. 163 : : * @ns: Time value by which to increment the sum_exec_runtime field 164 : : * of the thread_group_cputime structure. 165 : : * 166 : : * If thread group time is being maintained, get the structure for the 167 : : * running CPU and update the sum_exec_runtime field there. 168 : : */ 169 : 39324012 : static inline void account_group_exec_runtime(struct task_struct *tsk, 170 : : unsigned long long ns) 171 : : { 172 : : struct thread_group_cputimer *cputimer = get_running_cputimer(tsk); 173 : : 174 [ - + ]: 39324012 : if (!cputimer) 175 : 39324012 : return; 176 : : 177 : 0 : atomic64_add(ns, &cputimer->cputime_atomic.sum_exec_runtime); 178 : : } 179 : : 180 : : static inline void prev_cputime_init(struct prev_cputime *prev) 181 : : { 182 : : #ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE 183 : 787660 : prev->utime = prev->stime = 0; 184 : 787660 : raw_spin_lock_init(&prev->lock); 185 : : #endif 186 : : } 187 : : 188 : : extern unsigned long long 189 : : task_sched_runtime(struct task_struct *task); 190 : : 191 : : #endif /* _LINUX_SCHED_CPUTIME_H */