diff options
Diffstat (limited to 'kernel/posix-cpu-timers.c')
-rw-r--r-- | kernel/posix-cpu-timers.c | 41 |
1 files changed, 22 insertions, 19 deletions
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index 5c9dc228747b..1a22dfd42df9 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c | |||
@@ -384,7 +384,8 @@ int posix_cpu_clock_get(const clockid_t which_clock, struct timespec *tp) | |||
384 | 384 | ||
385 | /* | 385 | /* |
386 | * Validate the clockid_t for a new CPU-clock timer, and initialize the timer. | 386 | * Validate the clockid_t for a new CPU-clock timer, and initialize the timer. |
387 | * This is called from sys_timer_create with the new timer already locked. | 387 | * This is called from sys_timer_create() and do_cpu_nanosleep() with the |
388 | * new timer already all-zeros initialized. | ||
388 | */ | 389 | */ |
389 | int posix_cpu_timer_create(struct k_itimer *new_timer) | 390 | int posix_cpu_timer_create(struct k_itimer *new_timer) |
390 | { | 391 | { |
@@ -396,8 +397,6 @@ int posix_cpu_timer_create(struct k_itimer *new_timer) | |||
396 | return -EINVAL; | 397 | return -EINVAL; |
397 | 398 | ||
398 | INIT_LIST_HEAD(&new_timer->it.cpu.entry); | 399 | INIT_LIST_HEAD(&new_timer->it.cpu.entry); |
399 | new_timer->it.cpu.incr.sched = 0; | ||
400 | new_timer->it.cpu.expires.sched = 0; | ||
401 | 400 | ||
402 | read_lock(&tasklist_lock); | 401 | read_lock(&tasklist_lock); |
403 | if (CPUCLOCK_PERTHREAD(new_timer->it_clock)) { | 402 | if (CPUCLOCK_PERTHREAD(new_timer->it_clock)) { |
@@ -983,6 +982,7 @@ static void check_thread_timers(struct task_struct *tsk, | |||
983 | int maxfire; | 982 | int maxfire; |
984 | struct list_head *timers = tsk->cpu_timers; | 983 | struct list_head *timers = tsk->cpu_timers; |
985 | struct signal_struct *const sig = tsk->signal; | 984 | struct signal_struct *const sig = tsk->signal; |
985 | unsigned long soft; | ||
986 | 986 | ||
987 | maxfire = 20; | 987 | maxfire = 20; |
988 | tsk->cputime_expires.prof_exp = cputime_zero; | 988 | tsk->cputime_expires.prof_exp = cputime_zero; |
@@ -1031,9 +1031,10 @@ static void check_thread_timers(struct task_struct *tsk, | |||
1031 | /* | 1031 | /* |
1032 | * Check for the special case thread timers. | 1032 | * Check for the special case thread timers. |
1033 | */ | 1033 | */ |
1034 | if (sig->rlim[RLIMIT_RTTIME].rlim_cur != RLIM_INFINITY) { | 1034 | soft = ACCESS_ONCE(sig->rlim[RLIMIT_RTTIME].rlim_cur); |
1035 | unsigned long hard = sig->rlim[RLIMIT_RTTIME].rlim_max; | 1035 | if (soft != RLIM_INFINITY) { |
1036 | unsigned long *soft = &sig->rlim[RLIMIT_RTTIME].rlim_cur; | 1036 | unsigned long hard = |
1037 | ACCESS_ONCE(sig->rlim[RLIMIT_RTTIME].rlim_max); | ||
1037 | 1038 | ||
1038 | if (hard != RLIM_INFINITY && | 1039 | if (hard != RLIM_INFINITY && |
1039 | tsk->rt.timeout > DIV_ROUND_UP(hard, USEC_PER_SEC/HZ)) { | 1040 | tsk->rt.timeout > DIV_ROUND_UP(hard, USEC_PER_SEC/HZ)) { |
@@ -1044,14 +1045,13 @@ static void check_thread_timers(struct task_struct *tsk, | |||
1044 | __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk); | 1045 | __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk); |
1045 | return; | 1046 | return; |
1046 | } | 1047 | } |
1047 | if (tsk->rt.timeout > DIV_ROUND_UP(*soft, USEC_PER_SEC/HZ)) { | 1048 | if (tsk->rt.timeout > DIV_ROUND_UP(soft, USEC_PER_SEC/HZ)) { |
1048 | /* | 1049 | /* |
1049 | * At the soft limit, send a SIGXCPU every second. | 1050 | * At the soft limit, send a SIGXCPU every second. |
1050 | */ | 1051 | */ |
1051 | if (sig->rlim[RLIMIT_RTTIME].rlim_cur | 1052 | if (soft < hard) { |
1052 | < sig->rlim[RLIMIT_RTTIME].rlim_max) { | 1053 | soft += USEC_PER_SEC; |
1053 | sig->rlim[RLIMIT_RTTIME].rlim_cur += | 1054 | sig->rlim[RLIMIT_RTTIME].rlim_cur = soft; |
1054 | USEC_PER_SEC; | ||
1055 | } | 1055 | } |
1056 | printk(KERN_INFO | 1056 | printk(KERN_INFO |
1057 | "RT Watchdog Timeout: %s[%d]\n", | 1057 | "RT Watchdog Timeout: %s[%d]\n", |
@@ -1122,6 +1122,7 @@ static void check_process_timers(struct task_struct *tsk, | |||
1122 | unsigned long long sum_sched_runtime, sched_expires; | 1122 | unsigned long long sum_sched_runtime, sched_expires; |
1123 | struct list_head *timers = sig->cpu_timers; | 1123 | struct list_head *timers = sig->cpu_timers; |
1124 | struct task_cputime cputime; | 1124 | struct task_cputime cputime; |
1125 | unsigned long soft; | ||
1125 | 1126 | ||
1126 | /* | 1127 | /* |
1127 | * Don't sample the current process CPU clocks if there are no timers. | 1128 | * Don't sample the current process CPU clocks if there are no timers. |
@@ -1194,11 +1195,13 @@ static void check_process_timers(struct task_struct *tsk, | |||
1194 | SIGPROF); | 1195 | SIGPROF); |
1195 | check_cpu_itimer(tsk, &sig->it[CPUCLOCK_VIRT], &virt_expires, utime, | 1196 | check_cpu_itimer(tsk, &sig->it[CPUCLOCK_VIRT], &virt_expires, utime, |
1196 | SIGVTALRM); | 1197 | SIGVTALRM); |
1197 | 1198 | soft = ACCESS_ONCE(sig->rlim[RLIMIT_CPU].rlim_cur); | |
1198 | if (sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) { | 1199 | if (soft != RLIM_INFINITY) { |
1199 | unsigned long psecs = cputime_to_secs(ptime); | 1200 | unsigned long psecs = cputime_to_secs(ptime); |
1201 | unsigned long hard = | ||
1202 | ACCESS_ONCE(sig->rlim[RLIMIT_CPU].rlim_max); | ||
1200 | cputime_t x; | 1203 | cputime_t x; |
1201 | if (psecs >= sig->rlim[RLIMIT_CPU].rlim_max) { | 1204 | if (psecs >= hard) { |
1202 | /* | 1205 | /* |
1203 | * At the hard limit, we just die. | 1206 | * At the hard limit, we just die. |
1204 | * No need to calculate anything else now. | 1207 | * No need to calculate anything else now. |
@@ -1206,17 +1209,17 @@ static void check_process_timers(struct task_struct *tsk, | |||
1206 | __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk); | 1209 | __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk); |
1207 | return; | 1210 | return; |
1208 | } | 1211 | } |
1209 | if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) { | 1212 | if (psecs >= soft) { |
1210 | /* | 1213 | /* |
1211 | * At the soft limit, send a SIGXCPU every second. | 1214 | * At the soft limit, send a SIGXCPU every second. |
1212 | */ | 1215 | */ |
1213 | __group_send_sig_info(SIGXCPU, SEND_SIG_PRIV, tsk); | 1216 | __group_send_sig_info(SIGXCPU, SEND_SIG_PRIV, tsk); |
1214 | if (sig->rlim[RLIMIT_CPU].rlim_cur | 1217 | if (soft < hard) { |
1215 | < sig->rlim[RLIMIT_CPU].rlim_max) { | 1218 | soft++; |
1216 | sig->rlim[RLIMIT_CPU].rlim_cur++; | 1219 | sig->rlim[RLIMIT_CPU].rlim_cur = soft; |
1217 | } | 1220 | } |
1218 | } | 1221 | } |
1219 | x = secs_to_cputime(sig->rlim[RLIMIT_CPU].rlim_cur); | 1222 | x = secs_to_cputime(soft); |
1220 | if (cputime_eq(prof_expires, cputime_zero) || | 1223 | if (cputime_eq(prof_expires, cputime_zero) || |
1221 | cputime_lt(x, prof_expires)) { | 1224 | cputime_lt(x, prof_expires)) { |
1222 | prof_expires = x; | 1225 | prof_expires = x; |