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:
parent
31d9284569
commit
7086efe1c1
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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(
|
|
||||||
struct thread_group_cputime *tgtimes,
|
|
||||||
cputime_t cputime)
|
|
||||||
{
|
|
||||||
if (tgtimes->totals) {
|
|
||||||
struct task_cputime *times;
|
|
||||||
|
|
||||||
times = per_cpu_ptr(tgtimes->totals, get_cpu());
|
|
||||||
times->utime = cputime_add(times->utime, cputime);
|
|
||||||
put_cpu_no_resched();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* thread_group_cputime_account_system - Maintain stime for a thread group.
|
|
||||||
*
|
|
||||||
* @tgtimes: Pointer to thread_group_cputime structure.
|
|
||||||
* @cputime: Time value by which to increment the stime field of that
|
|
||||||
* structure.
|
|
||||||
*
|
|
||||||
* If thread group time is being maintained, get the structure for the
|
|
||||||
* running CPU and update the stime field there.
|
|
||||||
*/
|
|
||||||
static inline void thread_group_cputime_account_system(
|
|
||||||
struct thread_group_cputime *tgtimes,
|
|
||||||
cputime_t cputime)
|
|
||||||
{
|
|
||||||
if (tgtimes->totals) {
|
|
||||||
struct task_cputime *times;
|
|
||||||
|
|
||||||
times = per_cpu_ptr(tgtimes->totals, get_cpu());
|
|
||||||
times->stime = cputime_add(times->stime, cputime);
|
|
||||||
put_cpu_no_resched();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* thread_group_cputime_account_exec_runtime - Maintain exec runtime for a
|
|
||||||
* thread group.
|
|
||||||
*
|
|
||||||
* @tgtimes: Pointer to thread_group_cputime structure.
|
|
||||||
* @ns: Time value by which to increment the sum_exec_runtime field
|
|
||||||
* of that structure.
|
|
||||||
*
|
|
||||||
* If thread group time is being maintained, get the structure for the
|
|
||||||
* running CPU and update the sum_exec_runtime field there.
|
|
||||||
*/
|
|
||||||
static inline void thread_group_cputime_account_exec_runtime(
|
|
||||||
struct thread_group_cputime *tgtimes,
|
|
||||||
unsigned long long ns)
|
|
||||||
{
|
|
||||||
if (tgtimes->totals) {
|
|
||||||
struct task_cputime *times;
|
|
||||||
|
|
||||||
times = per_cpu_ptr(tgtimes->totals, get_cpu());
|
|
||||||
times->sum_exec_runtime += ns;
|
|
||||||
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,
|
static inline void account_group_user_time(struct task_struct *tsk,
|
||||||
cputime_t cputime)
|
cputime_t cputime)
|
||||||
{
|
{
|
||||||
struct signal_struct *sig;
|
struct signal_struct *sig;
|
||||||
|
|
||||||
sig = tsk->signal;
|
sig = tsk->signal;
|
||||||
if (likely(sig))
|
if (unlikely(!sig))
|
||||||
thread_group_cputime_account_user(&sig->cputime, cputime);
|
return;
|
||||||
|
if (sig->cputime.totals) {
|
||||||
|
struct task_cputime *times;
|
||||||
|
|
||||||
|
times = per_cpu_ptr(sig->cputime.totals, get_cpu());
|
||||||
|
times->utime = cputime_add(times->utime, cputime);
|
||||||
|
put_cpu_no_resched();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* account_group_system_time - Maintain stime for a thread group.
|
||||||
|
*
|
||||||
|
* @tsk: Pointer to task structure.
|
||||||
|
* @cputime: Time value by which to increment the stime field of the
|
||||||
|
* thread_group_cputime structure.
|
||||||
|
*
|
||||||
|
* If thread group time is being maintained, get the structure for the
|
||||||
|
* running CPU and update the stime field there.
|
||||||
|
*/
|
||||||
static inline void account_group_system_time(struct task_struct *tsk,
|
static inline void account_group_system_time(struct task_struct *tsk,
|
||||||
cputime_t cputime)
|
cputime_t cputime)
|
||||||
{
|
{
|
||||||
struct signal_struct *sig;
|
struct signal_struct *sig;
|
||||||
|
|
||||||
sig = tsk->signal;
|
sig = tsk->signal;
|
||||||
if (likely(sig))
|
if (unlikely(!sig))
|
||||||
thread_group_cputime_account_system(&sig->cputime, cputime);
|
return;
|
||||||
|
if (sig->cputime.totals) {
|
||||||
|
struct task_cputime *times;
|
||||||
|
|
||||||
|
times = per_cpu_ptr(sig->cputime.totals, get_cpu());
|
||||||
|
times->stime = cputime_add(times->stime, cputime);
|
||||||
|
put_cpu_no_resched();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* account_group_exec_runtime - Maintain exec runtime for a thread group.
|
||||||
|
*
|
||||||
|
* @tsk: Pointer to task structure.
|
||||||
|
* @ns: Time value by which to increment the sum_exec_runtime field
|
||||||
|
* of the thread_group_cputime structure.
|
||||||
|
*
|
||||||
|
* If thread group time is being maintained, get the structure for the
|
||||||
|
* running CPU and update the sum_exec_runtime field there.
|
||||||
|
*/
|
||||||
static inline void account_group_exec_runtime(struct task_struct *tsk,
|
static inline void account_group_exec_runtime(struct task_struct *tsk,
|
||||||
unsigned long long ns)
|
unsigned long long ns)
|
||||||
{
|
{
|
||||||
struct signal_struct *sig;
|
struct signal_struct *sig;
|
||||||
|
|
||||||
sig = tsk->signal;
|
sig = tsk->signal;
|
||||||
if (likely(sig))
|
if (unlikely(!sig))
|
||||||
thread_group_cputime_account_exec_runtime(&sig->cputime, ns);
|
return;
|
||||||
|
if (sig->cputime.totals) {
|
||||||
|
struct task_cputime *times;
|
||||||
|
|
||||||
|
times = per_cpu_ptr(sig->cputime.totals, get_cpu());
|
||||||
|
times->sum_exec_runtime += ns;
|
||||||
|
put_cpu_no_resched();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue