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 edec25a68e9e..bc7704b3a443 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", |
@@ -1125,6 +1126,7 @@ static void check_process_timers(struct task_struct *tsk, | |||
1125 | unsigned long long sum_sched_runtime, sched_expires; | 1126 | unsigned long long sum_sched_runtime, sched_expires; |
1126 | struct list_head *timers = sig->cpu_timers; | 1127 | struct list_head *timers = sig->cpu_timers; |
1127 | struct task_cputime cputime; | 1128 | struct task_cputime cputime; |
1129 | unsigned long soft; | ||
1128 | 1130 | ||
1129 | /* | 1131 | /* |
1130 | * Don't sample the current process CPU clocks if there are no timers. | 1132 | * Don't sample the current process CPU clocks if there are no timers. |
@@ -1197,11 +1199,13 @@ static void check_process_timers(struct task_struct *tsk, | |||
1197 | SIGPROF); | 1199 | SIGPROF); |
1198 | check_cpu_itimer(tsk, &sig->it[CPUCLOCK_VIRT], &virt_expires, utime, | 1200 | check_cpu_itimer(tsk, &sig->it[CPUCLOCK_VIRT], &virt_expires, utime, |
1199 | SIGVTALRM); | 1201 | SIGVTALRM); |
1200 | 1202 | soft = ACCESS_ONCE(sig->rlim[RLIMIT_CPU].rlim_cur); | |
1201 | if (sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) { | 1203 | if (soft != RLIM_INFINITY) { |
1202 | unsigned long psecs = cputime_to_secs(ptime); | 1204 | unsigned long psecs = cputime_to_secs(ptime); |
1205 | unsigned long hard = | ||
1206 | ACCESS_ONCE(sig->rlim[RLIMIT_CPU].rlim_max); | ||
1203 | cputime_t x; | 1207 | cputime_t x; |
1204 | if (psecs >= sig->rlim[RLIMIT_CPU].rlim_max) { | 1208 | if (psecs >= hard) { |
1205 | /* | 1209 | /* |
1206 | * At the hard limit, we just die. | 1210 | * At the hard limit, we just die. |
1207 | * No need to calculate anything else now. | 1211 | * No need to calculate anything else now. |
@@ -1209,17 +1213,17 @@ static void check_process_timers(struct task_struct *tsk, | |||
1209 | __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk); | 1213 | __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk); |
1210 | return; | 1214 | return; |
1211 | } | 1215 | } |
1212 | if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) { | 1216 | if (psecs >= soft) { |
1213 | /* | 1217 | /* |
1214 | * At the soft limit, send a SIGXCPU every second. | 1218 | * At the soft limit, send a SIGXCPU every second. |
1215 | */ | 1219 | */ |
1216 | __group_send_sig_info(SIGXCPU, SEND_SIG_PRIV, tsk); | 1220 | __group_send_sig_info(SIGXCPU, SEND_SIG_PRIV, tsk); |
1217 | if (sig->rlim[RLIMIT_CPU].rlim_cur | 1221 | if (soft < hard) { |
1218 | < sig->rlim[RLIMIT_CPU].rlim_max) { | 1222 | soft++; |
1219 | sig->rlim[RLIMIT_CPU].rlim_cur++; | 1223 | sig->rlim[RLIMIT_CPU].rlim_cur = soft; |
1220 | } | 1224 | } |
1221 | } | 1225 | } |
1222 | x = secs_to_cputime(sig->rlim[RLIMIT_CPU].rlim_cur); | 1226 | x = secs_to_cputime(soft); |
1223 | if (cputime_eq(prof_expires, cputime_zero) || | 1227 | if (cputime_eq(prof_expires, cputime_zero) || |
1224 | cputime_lt(x, prof_expires)) { | 1228 | cputime_lt(x, prof_expires)) { |
1225 | prof_expires = x; | 1229 | prof_expires = x; |