git://ftp.safe.ca
/
safe
/
jmp
/
linux-2.6
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
rcu: improve RCU CPU stall-warning messages
[safe/jmp/linux-2.6]
/
kernel
/
posix-cpu-timers.c
diff --git
a/kernel/posix-cpu-timers.c
b/kernel/posix-cpu-timers.c
index
18bdde6
..
bc7704b
100644
(file)
--- a/
kernel/posix-cpu-timers.c
+++ b/
kernel/posix-cpu-timers.c
@@
-8,6
+8,7
@@
#include <linux/math64.h>
#include <asm/uaccess.h>
#include <linux/kernel_stat.h>
#include <linux/math64.h>
#include <asm/uaccess.h>
#include <linux/kernel_stat.h>
+#include <trace/events/timer.h>
/*
* Called after updating RLIMIT_CPU to set timer expiration if necessary.
/*
* Called after updating RLIMIT_CPU to set timer expiration if necessary.
@@
-383,7
+384,8
@@
int posix_cpu_clock_get(const clockid_t which_clock, struct timespec *tp)
/*
* Validate the clockid_t for a new CPU-clock timer, and initialize the timer.
/*
* Validate the clockid_t for a new CPU-clock timer, and initialize the timer.
- * This is called from sys_timer_create with the new timer already locked.
+ * This is called from sys_timer_create() and do_cpu_nanosleep() with the
+ * new timer already all-zeros initialized.
*/
int posix_cpu_timer_create(struct k_itimer *new_timer)
{
*/
int posix_cpu_timer_create(struct k_itimer *new_timer)
{
@@
-395,8
+397,6
@@
int posix_cpu_timer_create(struct k_itimer *new_timer)
return -EINVAL;
INIT_LIST_HEAD(&new_timer->it.cpu.entry);
return -EINVAL;
INIT_LIST_HEAD(&new_timer->it.cpu.entry);
- new_timer->it.cpu.incr.sched = 0;
- new_timer->it.cpu.expires.sched = 0;
read_lock(&tasklist_lock);
if (CPUCLOCK_PERTHREAD(new_timer->it_clock)) {
read_lock(&tasklist_lock);
if (CPUCLOCK_PERTHREAD(new_timer->it_clock)) {
@@
-521,11
+521,12
@@
void posix_cpu_timers_exit(struct task_struct *tsk)
}
void posix_cpu_timers_exit_group(struct task_struct *tsk)
{
}
void posix_cpu_timers_exit_group(struct task_struct *tsk)
{
- struct
task_cputime cputime
;
+ struct
signal_struct *const sig = tsk->signal
;
- thread_group_cputimer(tsk, &cputime);
cleanup_timers(tsk->signal->cpu_timers,
cleanup_timers(tsk->signal->cpu_timers,
- cputime.utime, cputime.stime, cputime.sum_exec_runtime);
+ cputime_add(tsk->utime, sig->utime),
+ cputime_add(tsk->stime, sig->stime),
+ tsk->se.sum_exec_runtime + sig->sum_sched_runtime);
}
static void clear_dead_task(struct k_itimer *timer, union cpu_time_count now)
}
static void clear_dead_task(struct k_itimer *timer, union cpu_time_count now)
@@
-981,6
+982,7
@@
static void check_thread_timers(struct task_struct *tsk,
int maxfire;
struct list_head *timers = tsk->cpu_timers;
struct signal_struct *const sig = tsk->signal;
int maxfire;
struct list_head *timers = tsk->cpu_timers;
struct signal_struct *const sig = tsk->signal;
+ unsigned long soft;
maxfire = 20;
tsk->cputime_expires.prof_exp = cputime_zero;
maxfire = 20;
tsk->cputime_expires.prof_exp = cputime_zero;
@@
-1029,9
+1031,10
@@
static void check_thread_timers(struct task_struct *tsk,
/*
* Check for the special case thread timers.
*/
/*
* Check for the special case thread timers.
*/
- if (sig->rlim[RLIMIT_RTTIME].rlim_cur != RLIM_INFINITY) {
- unsigned long hard = sig->rlim[RLIMIT_RTTIME].rlim_max;
- unsigned long *soft = &sig->rlim[RLIMIT_RTTIME].rlim_cur;
+ soft = ACCESS_ONCE(sig->rlim[RLIMIT_RTTIME].rlim_cur);
+ if (soft != RLIM_INFINITY) {
+ unsigned long hard =
+ ACCESS_ONCE(sig->rlim[RLIMIT_RTTIME].rlim_max);
if (hard != RLIM_INFINITY &&
tsk->rt.timeout > DIV_ROUND_UP(hard, USEC_PER_SEC/HZ)) {
if (hard != RLIM_INFINITY &&
tsk->rt.timeout > DIV_ROUND_UP(hard, USEC_PER_SEC/HZ)) {
@@
-1042,14
+1045,13
@@
static void check_thread_timers(struct task_struct *tsk,
__group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
return;
}
__group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
return;
}
- if (tsk->rt.timeout > DIV_ROUND_UP(
*
soft, USEC_PER_SEC/HZ)) {
+ if (tsk->rt.timeout > DIV_ROUND_UP(soft, USEC_PER_SEC/HZ)) {
/*
* At the soft limit, send a SIGXCPU every second.
*/
/*
* At the soft limit, send a SIGXCPU every second.
*/
- if (sig->rlim[RLIMIT_RTTIME].rlim_cur
- < sig->rlim[RLIMIT_RTTIME].rlim_max) {
- sig->rlim[RLIMIT_RTTIME].rlim_cur +=
- USEC_PER_SEC;
+ if (soft < hard) {
+ soft += USEC_PER_SEC;
+ sig->rlim[RLIMIT_RTTIME].rlim_cur = soft;
}
printk(KERN_INFO
"RT Watchdog Timeout: %s[%d]\n",
}
printk(KERN_INFO
"RT Watchdog Timeout: %s[%d]\n",
@@
-1059,9
+1061,9
@@
static void check_thread_timers(struct task_struct *tsk,
}
}
}
}
-static void stop_process_timers(struct
task_struct *tsk
)
+static void stop_process_timers(struct
signal_struct *sig
)
{
{
- struct thread_group_cputimer *cputimer = &
tsk->signal
->cputimer;
+ struct thread_group_cputimer *cputimer = &
sig
->cputimer;
unsigned long flags;
if (!cputimer->running)
unsigned long flags;
if (!cputimer->running)
@@
-1070,6
+1072,10
@@
static void stop_process_timers(struct task_struct *tsk)
spin_lock_irqsave(&cputimer->lock, flags);
cputimer->running = 0;
spin_unlock_irqrestore(&cputimer->lock, flags);
spin_lock_irqsave(&cputimer->lock, flags);
cputimer->running = 0;
spin_unlock_irqrestore(&cputimer->lock, flags);
+
+ sig->cputime_expires.prof_exp = cputime_zero;
+ sig->cputime_expires.virt_exp = cputime_zero;
+ sig->cputime_expires.sched_exp = 0;
}
static u32 onecputick;
}
static u32 onecputick;
@@
-1089,9
+1095,13
@@
static void check_cpu_itimer(struct task_struct *tsk, struct cpu_itimer *it,
cputime_one_jiffy);
it->error -= onecputick;
}
cputime_one_jiffy);
it->error -= onecputick;
}
- } else
+ } else
{
it->expires = cputime_zero;
it->expires = cputime_zero;
+ }
+ trace_itimer_expire(signo == SIGPROF ?
+ ITIMER_PROF : ITIMER_VIRTUAL,
+ tsk->signal->leader_pid, cur_time);
__group_send_sig_info(signo, SEND_SIG_PRIV, tsk);
}
__group_send_sig_info(signo, SEND_SIG_PRIV, tsk);
}
@@
-1116,6
+1126,7
@@
static void check_process_timers(struct task_struct *tsk,
unsigned long long sum_sched_runtime, sched_expires;
struct list_head *timers = sig->cpu_timers;
struct task_cputime cputime;
unsigned long long sum_sched_runtime, sched_expires;
struct list_head *timers = sig->cpu_timers;
struct task_cputime cputime;
+ unsigned long soft;
/*
* Don't sample the current process CPU clocks if there are no timers.
/*
* Don't sample the current process CPU clocks if there are no timers.
@@
-1126,7
+1137,7
@@
static void check_process_timers(struct task_struct *tsk,
list_empty(&timers[CPUCLOCK_VIRT]) &&
cputime_eq(sig->it[CPUCLOCK_VIRT].expires, cputime_zero) &&
list_empty(&timers[CPUCLOCK_SCHED])) {
list_empty(&timers[CPUCLOCK_VIRT]) &&
cputime_eq(sig->it[CPUCLOCK_VIRT].expires, cputime_zero) &&
list_empty(&timers[CPUCLOCK_SCHED])) {
- stop_process_timers(
tsk
);
+ stop_process_timers(
sig
);
return;
}
return;
}
@@
-1188,11
+1199,13
@@
static void check_process_timers(struct task_struct *tsk,
SIGPROF);
check_cpu_itimer(tsk, &sig->it[CPUCLOCK_VIRT], &virt_expires, utime,
SIGVTALRM);
SIGPROF);
check_cpu_itimer(tsk, &sig->it[CPUCLOCK_VIRT], &virt_expires, utime,
SIGVTALRM);
-
- if (s
ig->rlim[RLIMIT_CPU].rlim_cur
!= RLIM_INFINITY) {
+ soft = ACCESS_ONCE(sig->rlim[RLIMIT_CPU].rlim_cur);
+ if (s
oft
!= RLIM_INFINITY) {
unsigned long psecs = cputime_to_secs(ptime);
unsigned long psecs = cputime_to_secs(ptime);
+ unsigned long hard =
+ ACCESS_ONCE(sig->rlim[RLIMIT_CPU].rlim_max);
cputime_t x;
cputime_t x;
- if (psecs >=
sig->rlim[RLIMIT_CPU].rlim_max
) {
+ if (psecs >=
hard
) {
/*
* At the hard limit, we just die.
* No need to calculate anything else now.
/*
* At the hard limit, we just die.
* No need to calculate anything else now.
@@
-1200,17
+1213,17
@@
static void check_process_timers(struct task_struct *tsk,
__group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
return;
}
__group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
return;
}
- if (psecs >= s
ig->rlim[RLIMIT_CPU].rlim_cur
) {
+ if (psecs >= s
oft
) {
/*
* At the soft limit, send a SIGXCPU every second.
*/
__group_send_sig_info(SIGXCPU, SEND_SIG_PRIV, tsk);
/*
* At the soft limit, send a SIGXCPU every second.
*/
__group_send_sig_info(SIGXCPU, SEND_SIG_PRIV, tsk);
- if (s
ig->rlim[RLIMIT_CPU].rlim_cur
- < sig->rlim[RLIMIT_CPU].rlim_max) {
- sig->rlim[RLIMIT_CPU].rlim_cur
++
;
+ if (s
oft < hard) {
+ soft++;
+ sig->rlim[RLIMIT_CPU].rlim_cur
= soft
;
}
}
}
}
- x = secs_to_cputime(s
ig->rlim[RLIMIT_CPU].rlim_cur
);
+ x = secs_to_cputime(s
oft
);
if (cputime_eq(prof_expires, cputime_zero) ||
cputime_lt(x, prof_expires)) {
prof_expires = x;
if (cputime_eq(prof_expires, cputime_zero) ||
cputime_lt(x, prof_expires)) {
prof_expires = x;