diff options
Diffstat (limited to 'kernel/posix-cpu-timers.c')
-rw-r--r-- | kernel/posix-cpu-timers.c | 36 |
1 files changed, 20 insertions, 16 deletions
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index 438ff4523513..1a22dfd42df9 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c | |||
@@ -982,6 +982,7 @@ static void check_thread_timers(struct task_struct *tsk, | |||
982 | int maxfire; | 982 | int maxfire; |
983 | struct list_head *timers = tsk->cpu_timers; | 983 | struct list_head *timers = tsk->cpu_timers; |
984 | struct signal_struct *const sig = tsk->signal; | 984 | struct signal_struct *const sig = tsk->signal; |
985 | unsigned long soft; | ||
985 | 986 | ||
986 | maxfire = 20; | 987 | maxfire = 20; |
987 | tsk->cputime_expires.prof_exp = cputime_zero; | 988 | tsk->cputime_expires.prof_exp = cputime_zero; |
@@ -1030,9 +1031,10 @@ static void check_thread_timers(struct task_struct *tsk, | |||
1030 | /* | 1031 | /* |
1031 | * Check for the special case thread timers. | 1032 | * Check for the special case thread timers. |
1032 | */ | 1033 | */ |
1033 | if (sig->rlim[RLIMIT_RTTIME].rlim_cur != RLIM_INFINITY) { | 1034 | soft = ACCESS_ONCE(sig->rlim[RLIMIT_RTTIME].rlim_cur); |
1034 | unsigned long hard = sig->rlim[RLIMIT_RTTIME].rlim_max; | 1035 | if (soft != RLIM_INFINITY) { |
1035 | unsigned long *soft = &sig->rlim[RLIMIT_RTTIME].rlim_cur; | 1036 | unsigned long hard = |
1037 | ACCESS_ONCE(sig->rlim[RLIMIT_RTTIME].rlim_max); | ||
1036 | 1038 | ||
1037 | if (hard != RLIM_INFINITY && | 1039 | if (hard != RLIM_INFINITY && |
1038 | tsk->rt.timeout > DIV_ROUND_UP(hard, USEC_PER_SEC/HZ)) { | 1040 | tsk->rt.timeout > DIV_ROUND_UP(hard, USEC_PER_SEC/HZ)) { |
@@ -1043,14 +1045,13 @@ static void check_thread_timers(struct task_struct *tsk, | |||
1043 | __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk); | 1045 | __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk); |
1044 | return; | 1046 | return; |
1045 | } | 1047 | } |
1046 | 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)) { |
1047 | /* | 1049 | /* |
1048 | * At the soft limit, send a SIGXCPU every second. | 1050 | * At the soft limit, send a SIGXCPU every second. |
1049 | */ | 1051 | */ |
1050 | if (sig->rlim[RLIMIT_RTTIME].rlim_cur | 1052 | if (soft < hard) { |
1051 | < sig->rlim[RLIMIT_RTTIME].rlim_max) { | 1053 | soft += USEC_PER_SEC; |
1052 | sig->rlim[RLIMIT_RTTIME].rlim_cur += | 1054 | sig->rlim[RLIMIT_RTTIME].rlim_cur = soft; |
1053 | USEC_PER_SEC; | ||
1054 | } | 1055 | } |
1055 | printk(KERN_INFO | 1056 | printk(KERN_INFO |
1056 | "RT Watchdog Timeout: %s[%d]\n", | 1057 | "RT Watchdog Timeout: %s[%d]\n", |
@@ -1121,6 +1122,7 @@ static void check_process_timers(struct task_struct *tsk, | |||
1121 | unsigned long long sum_sched_runtime, sched_expires; | 1122 | unsigned long long sum_sched_runtime, sched_expires; |
1122 | struct list_head *timers = sig->cpu_timers; | 1123 | struct list_head *timers = sig->cpu_timers; |
1123 | struct task_cputime cputime; | 1124 | struct task_cputime cputime; |
1125 | unsigned long soft; | ||
1124 | 1126 | ||
1125 | /* | 1127 | /* |
1126 | * 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. |
@@ -1193,11 +1195,13 @@ static void check_process_timers(struct task_struct *tsk, | |||
1193 | SIGPROF); | 1195 | SIGPROF); |
1194 | check_cpu_itimer(tsk, &sig->it[CPUCLOCK_VIRT], &virt_expires, utime, | 1196 | check_cpu_itimer(tsk, &sig->it[CPUCLOCK_VIRT], &virt_expires, utime, |
1195 | SIGVTALRM); | 1197 | SIGVTALRM); |
1196 | 1198 | soft = ACCESS_ONCE(sig->rlim[RLIMIT_CPU].rlim_cur); | |
1197 | if (sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) { | 1199 | if (soft != RLIM_INFINITY) { |
1198 | 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); | ||
1199 | cputime_t x; | 1203 | cputime_t x; |
1200 | if (psecs >= sig->rlim[RLIMIT_CPU].rlim_max) { | 1204 | if (psecs >= hard) { |
1201 | /* | 1205 | /* |
1202 | * At the hard limit, we just die. | 1206 | * At the hard limit, we just die. |
1203 | * No need to calculate anything else now. | 1207 | * No need to calculate anything else now. |
@@ -1205,17 +1209,17 @@ static void check_process_timers(struct task_struct *tsk, | |||
1205 | __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk); | 1209 | __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk); |
1206 | return; | 1210 | return; |
1207 | } | 1211 | } |
1208 | if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) { | 1212 | if (psecs >= soft) { |
1209 | /* | 1213 | /* |
1210 | * At the soft limit, send a SIGXCPU every second. | 1214 | * At the soft limit, send a SIGXCPU every second. |
1211 | */ | 1215 | */ |
1212 | __group_send_sig_info(SIGXCPU, SEND_SIG_PRIV, tsk); | 1216 | __group_send_sig_info(SIGXCPU, SEND_SIG_PRIV, tsk); |
1213 | if (sig->rlim[RLIMIT_CPU].rlim_cur | 1217 | if (soft < hard) { |
1214 | < sig->rlim[RLIMIT_CPU].rlim_max) { | 1218 | soft++; |
1215 | sig->rlim[RLIMIT_CPU].rlim_cur++; | 1219 | sig->rlim[RLIMIT_CPU].rlim_cur = soft; |
1216 | } | 1220 | } |
1217 | } | 1221 | } |
1218 | x = secs_to_cputime(sig->rlim[RLIMIT_CPU].rlim_cur); | 1222 | x = secs_to_cputime(soft); |
1219 | if (cputime_eq(prof_expires, cputime_zero) || | 1223 | if (cputime_eq(prof_expires, cputime_zero) || |
1220 | cputime_lt(x, prof_expires)) { | 1224 | cputime_lt(x, prof_expires)) { |
1221 | prof_expires = x; | 1225 | prof_expires = x; |