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