aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/posix-timers.h2
-rw-r--r--kernel/posix-cpu-timers.c41
2 files changed, 28 insertions, 15 deletions
diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h
index 042058fdb0af..3698d9d08978 100644
--- a/include/linux/posix-timers.h
+++ b/include/linux/posix-timers.h
@@ -122,6 +122,8 @@ void run_posix_cpu_timers(struct task_struct *task);
122void posix_cpu_timers_exit(struct task_struct *task); 122void posix_cpu_timers_exit(struct task_struct *task);
123void posix_cpu_timers_exit_group(struct task_struct *task); 123void posix_cpu_timers_exit_group(struct task_struct *task);
124 124
125bool posix_cpu_timers_can_stop_tick(struct task_struct *tsk);
126
125void set_process_cpu_timer(struct task_struct *task, unsigned int clock_idx, 127void set_process_cpu_timer(struct task_struct *task, unsigned int clock_idx,
126 cputime_t *newval, cputime_t *oldval); 128 cputime_t *newval, cputime_t *oldval);
127 129
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index 0bc33561a435..84d5cb372ed5 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -155,6 +155,21 @@ static void bump_cpu_timer(struct k_itimer *timer,
155 } 155 }
156} 156}
157 157
158/**
159 * task_cputime_zero - Check a task_cputime struct for all zero fields.
160 *
161 * @cputime: The struct to compare.
162 *
163 * Checks @cputime to see if all fields are zero. Returns true if all fields
164 * are zero, false if any field is nonzero.
165 */
166static inline int task_cputime_zero(const struct task_cputime *cputime)
167{
168 if (!cputime->utime && !cputime->stime && !cputime->sum_exec_runtime)
169 return 1;
170 return 0;
171}
172
158static inline cputime_t prof_ticks(struct task_struct *p) 173static inline cputime_t prof_ticks(struct task_struct *p)
159{ 174{
160 cputime_t utime, stime; 175 cputime_t utime, stime;
@@ -654,6 +669,17 @@ static void posix_cpu_timer_kick_nohz(void)
654{ 669{
655 schedule_work(&nohz_kick_work); 670 schedule_work(&nohz_kick_work);
656} 671}
672
673bool posix_cpu_timers_can_stop_tick(struct task_struct *tsk)
674{
675 if (!task_cputime_zero(&tsk->cputime_expires))
676 return true;
677
678 if (tsk->signal->cputimer.running)
679 return true;
680
681 return false;
682}
657#else 683#else
658static inline void posix_cpu_timer_kick_nohz(void) { } 684static inline void posix_cpu_timer_kick_nohz(void) { }
659#endif 685#endif
@@ -1032,21 +1058,6 @@ static void check_cpu_itimer(struct task_struct *tsk, struct cpu_itimer *it,
1032 } 1058 }
1033} 1059}
1034 1060
1035/**
1036 * task_cputime_zero - Check a task_cputime struct for all zero fields.
1037 *
1038 * @cputime: The struct to compare.
1039 *
1040 * Checks @cputime to see if all fields are zero. Returns true if all fields
1041 * are zero, false if any field is nonzero.
1042 */
1043static inline int task_cputime_zero(const struct task_cputime *cputime)
1044{
1045 if (!cputime->utime && !cputime->stime && !cputime->sum_exec_runtime)
1046 return 1;
1047 return 0;
1048}
1049
1050/* 1061/*
1051 * Check for any per-thread CPU timers that have fired and move them 1062 * Check for any per-thread CPU timers that have fired and move them
1052 * off the tsk->*_timers list onto the firing list. Per-thread timers 1063 * off the tsk->*_timers list onto the firing list. Per-thread timers