Commit 8b2ed21e authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull scheduler fixes from Ingo Molnar:
 "Misc fixes: two NUMA fixes, two cputime fixes and an RCU/lockdep fix"

* 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  sched/cputime: Fix clock_nanosleep()/clock_gettime() inconsistency
  sched/cputime: Fix cpu_timer_sample_group() double accounting
  sched/numa: Avoid selecting oneself as swap target
  sched/numa: Fix out of bounds read in sched_init_numa()
  sched: Remove lockdep check in sched_move_task()
parents 13f5004c 6e998916
...@@ -77,11 +77,6 @@ static inline unsigned int kstat_cpu_irqs_sum(unsigned int cpu) ...@@ -77,11 +77,6 @@ static inline unsigned int kstat_cpu_irqs_sum(unsigned int cpu)
return kstat_cpu(cpu).irqs_sum; return kstat_cpu(cpu).irqs_sum;
} }
/*
* Lock/unlock the current runqueue - to extract task statistics:
*/
extern unsigned long long task_delta_exec(struct task_struct *);
extern void account_user_time(struct task_struct *, cputime_t, cputime_t); extern void account_user_time(struct task_struct *, cputime_t, cputime_t);
extern void account_system_time(struct task_struct *, int, cputime_t, cputime_t); extern void account_system_time(struct task_struct *, int, cputime_t, cputime_t);
extern void account_steal_time(cputime_t); extern void account_steal_time(cputime_t);
......
...@@ -2474,44 +2474,6 @@ DEFINE_PER_CPU(struct kernel_cpustat, kernel_cpustat); ...@@ -2474,44 +2474,6 @@ DEFINE_PER_CPU(struct kernel_cpustat, kernel_cpustat);
EXPORT_PER_CPU_SYMBOL(kstat); EXPORT_PER_CPU_SYMBOL(kstat);
EXPORT_PER_CPU_SYMBOL(kernel_cpustat); EXPORT_PER_CPU_SYMBOL(kernel_cpustat);
/*
* Return any ns on the sched_clock that have not yet been accounted in
* @p in case that task is currently running.
*
* Called with task_rq_lock() held on @rq.
*/
static u64 do_task_delta_exec(struct task_struct *p, struct rq *rq)
{
u64 ns = 0;
/*
* Must be ->curr _and_ ->on_rq. If dequeued, we would
* project cycles that may never be accounted to this
* thread, breaking clock_gettime().
*/
if (task_current(rq, p) && task_on_rq_queued(p)) {
update_rq_clock(rq);
ns = rq_clock_task(rq) - p->se.exec_start;
if ((s64)ns < 0)
ns = 0;
}
return ns;
}
unsigned long long task_delta_exec(struct task_struct *p)
{
unsigned long flags;
struct rq *rq;
u64 ns = 0;
rq = task_rq_lock(p, &flags);
ns = do_task_delta_exec(p, rq);
task_rq_unlock(rq, p, &flags);
return ns;
}
/* /*
* Return accounted runtime for the task. * Return accounted runtime for the task.
* In case the task is currently running, return the runtime plus current's * In case the task is currently running, return the runtime plus current's
...@@ -2521,7 +2483,7 @@ unsigned long long task_sched_runtime(struct task_struct *p) ...@@ -2521,7 +2483,7 @@ unsigned long long task_sched_runtime(struct task_struct *p)
{ {
unsigned long flags; unsigned long flags;
struct rq *rq; struct rq *rq;
u64 ns = 0; u64 ns;
#if defined(CONFIG_64BIT) && defined(CONFIG_SMP) #if defined(CONFIG_64BIT) && defined(CONFIG_SMP)
/* /*
...@@ -2540,7 +2502,16 @@ unsigned long long task_sched_runtime(struct task_struct *p) ...@@ -2540,7 +2502,16 @@ unsigned long long task_sched_runtime(struct task_struct *p)
#endif #endif
rq = task_rq_lock(p, &flags); rq = task_rq_lock(p, &flags);
ns = p->se.sum_exec_runtime + do_task_delta_exec(p, rq); /*
* Must be ->curr _and_ ->on_rq. If dequeued, we would
* project cycles that may never be accounted to this
* thread, breaking clock_gettime().
*/
if (task_current(rq, p) && task_on_rq_queued(p)) {
update_rq_clock(rq);
p->sched_class->update_curr(rq);
}
ns = p->se.sum_exec_runtime;
task_rq_unlock(rq, p, &flags); task_rq_unlock(rq, p, &flags);
return ns; return ns;
...@@ -6368,6 +6339,10 @@ static void sched_init_numa(void) ...@@ -6368,6 +6339,10 @@ static void sched_init_numa(void)
if (!sched_debug()) if (!sched_debug())
break; break;
} }
if (!level)
return;
/* /*
* 'level' contains the number of unique distances, excluding the * 'level' contains the number of unique distances, excluding the
* identity distance node_distance(i,i). * identity distance node_distance(i,i).
...@@ -7444,8 +7419,12 @@ void sched_move_task(struct task_struct *tsk) ...@@ -7444,8 +7419,12 @@ void sched_move_task(struct task_struct *tsk)
if (unlikely(running)) if (unlikely(running))
put_prev_task(rq, tsk); put_prev_task(rq, tsk);
tg = container_of(task_css_check(tsk, cpu_cgrp_id, /*
lockdep_is_held(&tsk->sighand->siglock)), * All callers are synchronized by task_rq_lock(); we do not use RCU
* which is pointless here. Thus, we pass "true" to task_css_check()
* to prevent lockdep warnings.
*/
tg = container_of(task_css_check(tsk, cpu_cgrp_id, true),
struct task_group, css); struct task_group, css);
tg = autogroup_task_group(tsk, tg); tg = autogroup_task_group(tsk, tg);
tsk->sched_task_group = tg; tsk->sched_task_group = tg;
......
...@@ -1701,4 +1701,6 @@ const struct sched_class dl_sched_class = { ...@@ -1701,4 +1701,6 @@ const struct sched_class dl_sched_class = {
.prio_changed = prio_changed_dl, .prio_changed = prio_changed_dl,
.switched_from = switched_from_dl, .switched_from = switched_from_dl,
.switched_to = switched_to_dl, .switched_to = switched_to_dl,
.update_curr = update_curr_dl,
}; };
...@@ -726,6 +726,11 @@ static void update_curr(struct cfs_rq *cfs_rq) ...@@ -726,6 +726,11 @@ static void update_curr(struct cfs_rq *cfs_rq)
account_cfs_rq_runtime(cfs_rq, delta_exec); account_cfs_rq_runtime(cfs_rq, delta_exec);
} }
static void update_curr_fair(struct rq *rq)
{
update_curr(cfs_rq_of(&rq->curr->se));
}
static inline void static inline void
update_stats_wait_start(struct cfs_rq *cfs_rq, struct sched_entity *se) update_stats_wait_start(struct cfs_rq *cfs_rq, struct sched_entity *se)
{ {
...@@ -1179,6 +1184,13 @@ static void task_numa_compare(struct task_numa_env *env, ...@@ -1179,6 +1184,13 @@ static void task_numa_compare(struct task_numa_env *env,
cur = NULL; cur = NULL;
raw_spin_unlock_irq(&dst_rq->lock); raw_spin_unlock_irq(&dst_rq->lock);
/*
* Because we have preemption enabled we can get migrated around and
* end try selecting ourselves (current == env->p) as a swap candidate.
*/
if (cur == env->p)
goto unlock;
/* /*
* "imp" is the fault differential for the source task between the * "imp" is the fault differential for the source task between the
* source and destination node. Calculate the total differential for * source and destination node. Calculate the total differential for
...@@ -7949,6 +7961,8 @@ const struct sched_class fair_sched_class = { ...@@ -7949,6 +7961,8 @@ const struct sched_class fair_sched_class = {
.get_rr_interval = get_rr_interval_fair, .get_rr_interval = get_rr_interval_fair,
.update_curr = update_curr_fair,
#ifdef CONFIG_FAIR_GROUP_SCHED #ifdef CONFIG_FAIR_GROUP_SCHED
.task_move_group = task_move_group_fair, .task_move_group = task_move_group_fair,
#endif #endif
......
...@@ -2128,6 +2128,8 @@ const struct sched_class rt_sched_class = { ...@@ -2128,6 +2128,8 @@ const struct sched_class rt_sched_class = {
.prio_changed = prio_changed_rt, .prio_changed = prio_changed_rt,
.switched_to = switched_to_rt, .switched_to = switched_to_rt,
.update_curr = update_curr_rt,
}; };
#ifdef CONFIG_SCHED_DEBUG #ifdef CONFIG_SCHED_DEBUG
......
...@@ -1135,6 +1135,8 @@ struct sched_class { ...@@ -1135,6 +1135,8 @@ struct sched_class {
unsigned int (*get_rr_interval) (struct rq *rq, unsigned int (*get_rr_interval) (struct rq *rq,
struct task_struct *task); struct task_struct *task);
void (*update_curr) (struct rq *rq);
#ifdef CONFIG_FAIR_GROUP_SCHED #ifdef CONFIG_FAIR_GROUP_SCHED
void (*task_move_group) (struct task_struct *p, int on_rq); void (*task_move_group) (struct task_struct *p, int on_rq);
#endif #endif
......
...@@ -553,7 +553,7 @@ static int cpu_timer_sample_group(const clockid_t which_clock, ...@@ -553,7 +553,7 @@ static int cpu_timer_sample_group(const clockid_t which_clock,
*sample = cputime_to_expires(cputime.utime); *sample = cputime_to_expires(cputime.utime);
break; break;
case CPUCLOCK_SCHED: case CPUCLOCK_SCHED:
*sample = cputime.sum_exec_runtime + task_delta_exec(p); *sample = cputime.sum_exec_runtime;
break; break;
} }
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment