diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-09-15 14:00:37 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-09-15 14:00:37 -0400 |
| commit | 4314daa55b4ddc2dc1c28a3835b484de33ffbfdd (patch) | |
| tree | 584e5077160abcbf4d13eb03ff42ed58d87c1a90 | |
| parent | c0be92b5b14bc6928363527602dabff57875473a (diff) | |
| parent | 882a78a9f39f5535b209b4aa0a1741e35b8c67fb (diff) | |
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: various scheduler metrics corner case fixes, a
sched_features deadlock fix, and a topology fix for certain NUMA
systems"
* 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
sched/fair: Fix kernel-doc notation warning
sched/fair: Fix load_balance redo for !imbalance
sched/fair: Fix scale_rt_capacity() for SMT
sched/fair: Fix vruntime_normalized() for remote non-migration wakeup
sched/pelt: Fix update_blocked_averages() for RT and DL classes
sched/topology: Set correct NUMA topology type
sched/debug: Fix potential deadlock when writing to sched_features
| -rw-r--r-- | kernel/sched/debug.c | 6 | ||||
| -rw-r--r-- | kernel/sched/fair.c | 26 | ||||
| -rw-r--r-- | kernel/sched/topology.c | 5 |
3 files changed, 22 insertions, 15 deletions
diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c index 60caf1fb94e0..6383aa6a60ca 100644 --- a/kernel/sched/debug.c +++ b/kernel/sched/debug.c | |||
| @@ -89,12 +89,12 @@ struct static_key sched_feat_keys[__SCHED_FEAT_NR] = { | |||
| 89 | 89 | ||
| 90 | static void sched_feat_disable(int i) | 90 | static void sched_feat_disable(int i) |
| 91 | { | 91 | { |
| 92 | static_key_disable(&sched_feat_keys[i]); | 92 | static_key_disable_cpuslocked(&sched_feat_keys[i]); |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | static void sched_feat_enable(int i) | 95 | static void sched_feat_enable(int i) |
| 96 | { | 96 | { |
| 97 | static_key_enable(&sched_feat_keys[i]); | 97 | static_key_enable_cpuslocked(&sched_feat_keys[i]); |
| 98 | } | 98 | } |
| 99 | #else | 99 | #else |
| 100 | static void sched_feat_disable(int i) { }; | 100 | static void sched_feat_disable(int i) { }; |
| @@ -146,9 +146,11 @@ sched_feat_write(struct file *filp, const char __user *ubuf, | |||
| 146 | 146 | ||
| 147 | /* Ensure the static_key remains in a consistent state */ | 147 | /* Ensure the static_key remains in a consistent state */ |
| 148 | inode = file_inode(filp); | 148 | inode = file_inode(filp); |
| 149 | cpus_read_lock(); | ||
| 149 | inode_lock(inode); | 150 | inode_lock(inode); |
| 150 | ret = sched_feat_set(cmp); | 151 | ret = sched_feat_set(cmp); |
| 151 | inode_unlock(inode); | 152 | inode_unlock(inode); |
| 153 | cpus_read_unlock(); | ||
| 152 | if (ret < 0) | 154 | if (ret < 0) |
| 153 | return ret; | 155 | return ret; |
| 154 | 156 | ||
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index b39fb596f6c1..f808ddf2a868 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c | |||
| @@ -3362,6 +3362,7 @@ update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq) | |||
| 3362 | * attach_entity_load_avg - attach this entity to its cfs_rq load avg | 3362 | * attach_entity_load_avg - attach this entity to its cfs_rq load avg |
| 3363 | * @cfs_rq: cfs_rq to attach to | 3363 | * @cfs_rq: cfs_rq to attach to |
| 3364 | * @se: sched_entity to attach | 3364 | * @se: sched_entity to attach |
| 3365 | * @flags: migration hints | ||
| 3365 | * | 3366 | * |
| 3366 | * Must call update_cfs_rq_load_avg() before this, since we rely on | 3367 | * Must call update_cfs_rq_load_avg() before this, since we rely on |
| 3367 | * cfs_rq->avg.last_update_time being current. | 3368 | * cfs_rq->avg.last_update_time being current. |
| @@ -7263,6 +7264,7 @@ static void update_blocked_averages(int cpu) | |||
| 7263 | { | 7264 | { |
| 7264 | struct rq *rq = cpu_rq(cpu); | 7265 | struct rq *rq = cpu_rq(cpu); |
| 7265 | struct cfs_rq *cfs_rq, *pos; | 7266 | struct cfs_rq *cfs_rq, *pos; |
| 7267 | const struct sched_class *curr_class; | ||
| 7266 | struct rq_flags rf; | 7268 | struct rq_flags rf; |
| 7267 | bool done = true; | 7269 | bool done = true; |
| 7268 | 7270 | ||
| @@ -7299,8 +7301,10 @@ static void update_blocked_averages(int cpu) | |||
| 7299 | if (cfs_rq_has_blocked(cfs_rq)) | 7301 | if (cfs_rq_has_blocked(cfs_rq)) |
| 7300 | done = false; | 7302 | done = false; |
| 7301 | } | 7303 | } |
| 7302 | update_rt_rq_load_avg(rq_clock_task(rq), rq, 0); | 7304 | |
| 7303 | update_dl_rq_load_avg(rq_clock_task(rq), rq, 0); | 7305 | curr_class = rq->curr->sched_class; |
| 7306 | update_rt_rq_load_avg(rq_clock_task(rq), rq, curr_class == &rt_sched_class); | ||
| 7307 | update_dl_rq_load_avg(rq_clock_task(rq), rq, curr_class == &dl_sched_class); | ||
| 7304 | update_irq_load_avg(rq, 0); | 7308 | update_irq_load_avg(rq, 0); |
| 7305 | /* Don't need periodic decay once load/util_avg are null */ | 7309 | /* Don't need periodic decay once load/util_avg are null */ |
| 7306 | if (others_have_blocked(rq)) | 7310 | if (others_have_blocked(rq)) |
| @@ -7365,13 +7369,16 @@ static inline void update_blocked_averages(int cpu) | |||
| 7365 | { | 7369 | { |
| 7366 | struct rq *rq = cpu_rq(cpu); | 7370 | struct rq *rq = cpu_rq(cpu); |
| 7367 | struct cfs_rq *cfs_rq = &rq->cfs; | 7371 | struct cfs_rq *cfs_rq = &rq->cfs; |
| 7372 | const struct sched_class *curr_class; | ||
| 7368 | struct rq_flags rf; | 7373 | struct rq_flags rf; |
| 7369 | 7374 | ||
| 7370 | rq_lock_irqsave(rq, &rf); | 7375 | rq_lock_irqsave(rq, &rf); |
| 7371 | update_rq_clock(rq); | 7376 | update_rq_clock(rq); |
| 7372 | update_cfs_rq_load_avg(cfs_rq_clock_task(cfs_rq), cfs_rq); | 7377 | update_cfs_rq_load_avg(cfs_rq_clock_task(cfs_rq), cfs_rq); |
| 7373 | update_rt_rq_load_avg(rq_clock_task(rq), rq, 0); | 7378 | |
| 7374 | update_dl_rq_load_avg(rq_clock_task(rq), rq, 0); | 7379 | curr_class = rq->curr->sched_class; |
| 7380 | update_rt_rq_load_avg(rq_clock_task(rq), rq, curr_class == &rt_sched_class); | ||
| 7381 | update_dl_rq_load_avg(rq_clock_task(rq), rq, curr_class == &dl_sched_class); | ||
| 7375 | update_irq_load_avg(rq, 0); | 7382 | update_irq_load_avg(rq, 0); |
| 7376 | #ifdef CONFIG_NO_HZ_COMMON | 7383 | #ifdef CONFIG_NO_HZ_COMMON |
| 7377 | rq->last_blocked_load_update_tick = jiffies; | 7384 | rq->last_blocked_load_update_tick = jiffies; |
| @@ -7482,10 +7489,10 @@ static inline int get_sd_load_idx(struct sched_domain *sd, | |||
| 7482 | return load_idx; | 7489 | return load_idx; |
| 7483 | } | 7490 | } |
| 7484 | 7491 | ||
| 7485 | static unsigned long scale_rt_capacity(int cpu) | 7492 | static unsigned long scale_rt_capacity(struct sched_domain *sd, int cpu) |
| 7486 | { | 7493 | { |
| 7487 | struct rq *rq = cpu_rq(cpu); | 7494 | struct rq *rq = cpu_rq(cpu); |
| 7488 | unsigned long max = arch_scale_cpu_capacity(NULL, cpu); | 7495 | unsigned long max = arch_scale_cpu_capacity(sd, cpu); |
| 7489 | unsigned long used, free; | 7496 | unsigned long used, free; |
| 7490 | unsigned long irq; | 7497 | unsigned long irq; |
| 7491 | 7498 | ||
| @@ -7507,7 +7514,7 @@ static unsigned long scale_rt_capacity(int cpu) | |||
| 7507 | 7514 | ||
| 7508 | static void update_cpu_capacity(struct sched_domain *sd, int cpu) | 7515 | static void update_cpu_capacity(struct sched_domain *sd, int cpu) |
| 7509 | { | 7516 | { |
| 7510 | unsigned long capacity = scale_rt_capacity(cpu); | 7517 | unsigned long capacity = scale_rt_capacity(sd, cpu); |
| 7511 | struct sched_group *sdg = sd->groups; | 7518 | struct sched_group *sdg = sd->groups; |
| 7512 | 7519 | ||
| 7513 | cpu_rq(cpu)->cpu_capacity_orig = arch_scale_cpu_capacity(sd, cpu); | 7520 | cpu_rq(cpu)->cpu_capacity_orig = arch_scale_cpu_capacity(sd, cpu); |
| @@ -8269,7 +8276,7 @@ static struct sched_group *find_busiest_group(struct lb_env *env) | |||
| 8269 | force_balance: | 8276 | force_balance: |
| 8270 | /* Looks like there is an imbalance. Compute it */ | 8277 | /* Looks like there is an imbalance. Compute it */ |
| 8271 | calculate_imbalance(env, &sds); | 8278 | calculate_imbalance(env, &sds); |
| 8272 | return sds.busiest; | 8279 | return env->imbalance ? sds.busiest : NULL; |
| 8273 | 8280 | ||
| 8274 | out_balanced: | 8281 | out_balanced: |
| 8275 | env->imbalance = 0; | 8282 | env->imbalance = 0; |
| @@ -9638,7 +9645,8 @@ static inline bool vruntime_normalized(struct task_struct *p) | |||
| 9638 | * - A task which has been woken up by try_to_wake_up() and | 9645 | * - A task which has been woken up by try_to_wake_up() and |
| 9639 | * waiting for actually being woken up by sched_ttwu_pending(). | 9646 | * waiting for actually being woken up by sched_ttwu_pending(). |
| 9640 | */ | 9647 | */ |
| 9641 | if (!se->sum_exec_runtime || p->state == TASK_WAKING) | 9648 | if (!se->sum_exec_runtime || |
| 9649 | (p->state == TASK_WAKING && p->sched_remote_wakeup)) | ||
| 9642 | return true; | 9650 | return true; |
| 9643 | 9651 | ||
| 9644 | return false; | 9652 | return false; |
diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c index 56a0fed30c0a..505a41c42b96 100644 --- a/kernel/sched/topology.c +++ b/kernel/sched/topology.c | |||
| @@ -1295,7 +1295,7 @@ static void init_numa_topology_type(void) | |||
| 1295 | 1295 | ||
| 1296 | n = sched_max_numa_distance; | 1296 | n = sched_max_numa_distance; |
| 1297 | 1297 | ||
| 1298 | if (sched_domains_numa_levels <= 1) { | 1298 | if (sched_domains_numa_levels <= 2) { |
| 1299 | sched_numa_topology_type = NUMA_DIRECT; | 1299 | sched_numa_topology_type = NUMA_DIRECT; |
| 1300 | return; | 1300 | return; |
| 1301 | } | 1301 | } |
| @@ -1380,9 +1380,6 @@ void sched_init_numa(void) | |||
| 1380 | break; | 1380 | break; |
| 1381 | } | 1381 | } |
| 1382 | 1382 | ||
| 1383 | if (!level) | ||
| 1384 | return; | ||
| 1385 | |||
| 1386 | /* | 1383 | /* |
| 1387 | * 'level' contains the number of unique distances | 1384 | * 'level' contains the number of unique distances |
| 1388 | * | 1385 | * |
