timers: fix itimer/many thread hang, v3

- fix UP lockup
- another set of UP/SMP cleanups and simplifications

Signed-off-by: Frank Mayhar <fmayhar@google.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
Frank Mayhar 2008-09-12 09:54:39 -07:00 committed by Ingo Molnar
parent 31d9284569
commit 7086efe1c1
3 changed files with 38 additions and 90 deletions

View File

@ -2134,7 +2134,6 @@ static inline int thread_group_cputime_clone_thread(struct task_struct *curr)
return thread_group_cputime_alloc(curr); return thread_group_cputime_alloc(curr);
} }
static inline void thread_group_cputime_free(struct signal_struct *sig) static inline void thread_group_cputime_free(struct signal_struct *sig)
{ {
free_percpu(sig->cputime.totals); free_percpu(sig->cputime.totals);

View File

@ -4046,7 +4046,6 @@ unsigned long long task_delta_exec(struct task_struct *p)
unsigned long flags; unsigned long flags;
u64 ns = 0; u64 ns = 0;
rq = task_rq_lock(p, &flags);
if (task_current(rq, p)) { if (task_current(rq, p)) {
u64 delta_exec; u64 delta_exec;

View File

@ -276,133 +276,83 @@ sched_info_switch(struct task_struct *prev, struct task_struct *next)
* on CONFIG_SCHEDSTATS. * on CONFIG_SCHEDSTATS.
*/ */
#ifdef CONFIG_SMP
/** /**
* thread_group_cputime_account_user - Maintain utime for a thread group. * account_group_user_time - Maintain utime for a thread group.
* *
* @tgtimes: Pointer to thread_group_cputime structure. * @tsk: Pointer to task structure.
* @cputime: Time value by which to increment the utime field of that * @cputime: Time value by which to increment the utime field of the
* structure. * thread_group_cputime structure.
* *
* If thread group time is being maintained, get the structure for the * If thread group time is being maintained, get the structure for the
* running CPU and update the utime field there. * running CPU and update the utime field there.
*/ */
static inline void thread_group_cputime_account_user( static inline void account_group_user_time(struct task_struct *tsk,
struct thread_group_cputime *tgtimes, cputime_t cputime)
cputime_t cputime)
{ {
if (tgtimes->totals) { struct signal_struct *sig;
sig = tsk->signal;
if (unlikely(!sig))
return;
if (sig->cputime.totals) {
struct task_cputime *times; struct task_cputime *times;
times = per_cpu_ptr(tgtimes->totals, get_cpu()); times = per_cpu_ptr(sig->cputime.totals, get_cpu());
times->utime = cputime_add(times->utime, cputime); times->utime = cputime_add(times->utime, cputime);
put_cpu_no_resched(); put_cpu_no_resched();
} }
} }
/** /**
* thread_group_cputime_account_system - Maintain stime for a thread group. * account_group_system_time - Maintain stime for a thread group.
* *
* @tgtimes: Pointer to thread_group_cputime structure. * @tsk: Pointer to task structure.
* @cputime: Time value by which to increment the stime field of that * @cputime: Time value by which to increment the stime field of the
* structure. * thread_group_cputime structure.
* *
* If thread group time is being maintained, get the structure for the * If thread group time is being maintained, get the structure for the
* running CPU and update the stime field there. * running CPU and update the stime field there.
*/ */
static inline void thread_group_cputime_account_system( static inline void account_group_system_time(struct task_struct *tsk,
struct thread_group_cputime *tgtimes, cputime_t cputime)
cputime_t cputime)
{ {
if (tgtimes->totals) { struct signal_struct *sig;
sig = tsk->signal;
if (unlikely(!sig))
return;
if (sig->cputime.totals) {
struct task_cputime *times; struct task_cputime *times;
times = per_cpu_ptr(tgtimes->totals, get_cpu()); times = per_cpu_ptr(sig->cputime.totals, get_cpu());
times->stime = cputime_add(times->stime, cputime); times->stime = cputime_add(times->stime, cputime);
put_cpu_no_resched(); put_cpu_no_resched();
} }
} }
/** /**
* thread_group_cputime_account_exec_runtime - Maintain exec runtime for a * account_group_exec_runtime - Maintain exec runtime for a thread group.
* thread group.
* *
* @tgtimes: Pointer to thread_group_cputime structure. * @tsk: Pointer to task structure.
* @ns: Time value by which to increment the sum_exec_runtime field * @ns: Time value by which to increment the sum_exec_runtime field
* of that structure. * of the thread_group_cputime structure.
* *
* If thread group time is being maintained, get the structure for the * If thread group time is being maintained, get the structure for the
* running CPU and update the sum_exec_runtime field there. * running CPU and update the sum_exec_runtime field there.
*/ */
static inline void thread_group_cputime_account_exec_runtime( static inline void account_group_exec_runtime(struct task_struct *tsk,
struct thread_group_cputime *tgtimes, unsigned long long ns)
unsigned long long ns)
{ {
if (tgtimes->totals) { struct signal_struct *sig;
sig = tsk->signal;
if (unlikely(!sig))
return;
if (sig->cputime.totals) {
struct task_cputime *times; struct task_cputime *times;
times = per_cpu_ptr(tgtimes->totals, get_cpu()); times = per_cpu_ptr(sig->cputime.totals, get_cpu());
times->sum_exec_runtime += ns; times->sum_exec_runtime += ns;
put_cpu_no_resched(); put_cpu_no_resched();
} }
} }
#else /* CONFIG_SMP */
static inline void thread_group_cputime_account_user(
struct thread_group_cputime *tgtimes,
cputime_t cputime)
{
tgtimes->totals->utime = cputime_add(tgtimes->totals->utime, cputime);
}
static inline void thread_group_cputime_account_system(
struct thread_group_cputime *tgtimes,
cputime_t cputime)
{
tgtimes->totals->stime = cputime_add(tgtimes->totals->stime, cputime);
}
static inline void thread_group_cputime_account_exec_runtime(
struct thread_group_cputime *tgtimes,
unsigned long long ns)
{
tgtimes->totals->sum_exec_runtime += ns;
}
#endif /* CONFIG_SMP */
/*
* These are the generic time-accounting routines that use the above
* functions. They are the functions actually called by the scheduler.
*/
static inline void account_group_user_time(struct task_struct *tsk,
cputime_t cputime)
{
struct signal_struct *sig;
sig = tsk->signal;
if (likely(sig))
thread_group_cputime_account_user(&sig->cputime, cputime);
}
static inline void account_group_system_time(struct task_struct *tsk,
cputime_t cputime)
{
struct signal_struct *sig;
sig = tsk->signal;
if (likely(sig))
thread_group_cputime_account_system(&sig->cputime, cputime);
}
static inline void account_group_exec_runtime(struct task_struct *tsk,
unsigned long long ns)
{
struct signal_struct *sig;
sig = tsk->signal;
if (likely(sig))
thread_group_cputime_account_exec_runtime(&sig->cputime, ns);
}