diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/sched/core.c | 36 | ||||
-rw-r--r-- | kernel/sched/deadline.c | 3 | ||||
-rw-r--r-- | kernel/sched/fair.c | 2 | ||||
-rw-r--r-- | kernel/smpboot.c | 2 | ||||
-rw-r--r-- | kernel/time/hrtimer.c | 2 |
5 files changed, 37 insertions, 8 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index e628cb11b560..5eab11d4b747 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
@@ -1814,6 +1814,10 @@ void __dl_clear_params(struct task_struct *p) | |||
1814 | dl_se->dl_period = 0; | 1814 | dl_se->dl_period = 0; |
1815 | dl_se->flags = 0; | 1815 | dl_se->flags = 0; |
1816 | dl_se->dl_bw = 0; | 1816 | dl_se->dl_bw = 0; |
1817 | |||
1818 | dl_se->dl_throttled = 0; | ||
1819 | dl_se->dl_new = 1; | ||
1820 | dl_se->dl_yielded = 0; | ||
1817 | } | 1821 | } |
1818 | 1822 | ||
1819 | /* | 1823 | /* |
@@ -1839,7 +1843,7 @@ static void __sched_fork(unsigned long clone_flags, struct task_struct *p) | |||
1839 | #endif | 1843 | #endif |
1840 | 1844 | ||
1841 | RB_CLEAR_NODE(&p->dl.rb_node); | 1845 | RB_CLEAR_NODE(&p->dl.rb_node); |
1842 | hrtimer_init(&p->dl.dl_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | 1846 | init_dl_task_timer(&p->dl); |
1843 | __dl_clear_params(p); | 1847 | __dl_clear_params(p); |
1844 | 1848 | ||
1845 | INIT_LIST_HEAD(&p->rt.run_list); | 1849 | INIT_LIST_HEAD(&p->rt.run_list); |
@@ -2049,6 +2053,9 @@ static inline int dl_bw_cpus(int i) | |||
2049 | * allocated bandwidth to reflect the new situation. | 2053 | * allocated bandwidth to reflect the new situation. |
2050 | * | 2054 | * |
2051 | * This function is called while holding p's rq->lock. | 2055 | * This function is called while holding p's rq->lock. |
2056 | * | ||
2057 | * XXX we should delay bw change until the task's 0-lag point, see | ||
2058 | * __setparam_dl(). | ||
2052 | */ | 2059 | */ |
2053 | static int dl_overflow(struct task_struct *p, int policy, | 2060 | static int dl_overflow(struct task_struct *p, int policy, |
2054 | const struct sched_attr *attr) | 2061 | const struct sched_attr *attr) |
@@ -3251,15 +3258,31 @@ __setparam_dl(struct task_struct *p, const struct sched_attr *attr) | |||
3251 | { | 3258 | { |
3252 | struct sched_dl_entity *dl_se = &p->dl; | 3259 | struct sched_dl_entity *dl_se = &p->dl; |
3253 | 3260 | ||
3254 | init_dl_task_timer(dl_se); | ||
3255 | dl_se->dl_runtime = attr->sched_runtime; | 3261 | dl_se->dl_runtime = attr->sched_runtime; |
3256 | dl_se->dl_deadline = attr->sched_deadline; | 3262 | dl_se->dl_deadline = attr->sched_deadline; |
3257 | dl_se->dl_period = attr->sched_period ?: dl_se->dl_deadline; | 3263 | dl_se->dl_period = attr->sched_period ?: dl_se->dl_deadline; |
3258 | dl_se->flags = attr->sched_flags; | 3264 | dl_se->flags = attr->sched_flags; |
3259 | dl_se->dl_bw = to_ratio(dl_se->dl_period, dl_se->dl_runtime); | 3265 | dl_se->dl_bw = to_ratio(dl_se->dl_period, dl_se->dl_runtime); |
3260 | dl_se->dl_throttled = 0; | 3266 | |
3261 | dl_se->dl_new = 1; | 3267 | /* |
3262 | dl_se->dl_yielded = 0; | 3268 | * Changing the parameters of a task is 'tricky' and we're not doing |
3269 | * the correct thing -- also see task_dead_dl() and switched_from_dl(). | ||
3270 | * | ||
3271 | * What we SHOULD do is delay the bandwidth release until the 0-lag | ||
3272 | * point. This would include retaining the task_struct until that time | ||
3273 | * and change dl_overflow() to not immediately decrement the current | ||
3274 | * amount. | ||
3275 | * | ||
3276 | * Instead we retain the current runtime/deadline and let the new | ||
3277 | * parameters take effect after the current reservation period lapses. | ||
3278 | * This is safe (albeit pessimistic) because the 0-lag point is always | ||
3279 | * before the current scheduling deadline. | ||
3280 | * | ||
3281 | * We can still have temporary overloads because we do not delay the | ||
3282 | * change in bandwidth until that time; so admission control is | ||
3283 | * not on the safe side. It does however guarantee tasks will never | ||
3284 | * consume more than promised. | ||
3285 | */ | ||
3263 | } | 3286 | } |
3264 | 3287 | ||
3265 | /* | 3288 | /* |
@@ -4642,6 +4665,9 @@ int cpuset_cpumask_can_shrink(const struct cpumask *cur, | |||
4642 | struct dl_bw *cur_dl_b; | 4665 | struct dl_bw *cur_dl_b; |
4643 | unsigned long flags; | 4666 | unsigned long flags; |
4644 | 4667 | ||
4668 | if (!cpumask_weight(cur)) | ||
4669 | return ret; | ||
4670 | |||
4645 | rcu_read_lock_sched(); | 4671 | rcu_read_lock_sched(); |
4646 | cur_dl_b = dl_bw_of(cpumask_any(cur)); | 4672 | cur_dl_b = dl_bw_of(cpumask_any(cur)); |
4647 | trial_cpus = cpumask_weight(trial); | 4673 | trial_cpus = cpumask_weight(trial); |
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c index b52092f2636d..726470d47f87 100644 --- a/kernel/sched/deadline.c +++ b/kernel/sched/deadline.c | |||
@@ -1094,6 +1094,7 @@ static void task_dead_dl(struct task_struct *p) | |||
1094 | * Since we are TASK_DEAD we won't slip out of the domain! | 1094 | * Since we are TASK_DEAD we won't slip out of the domain! |
1095 | */ | 1095 | */ |
1096 | raw_spin_lock_irq(&dl_b->lock); | 1096 | raw_spin_lock_irq(&dl_b->lock); |
1097 | /* XXX we should retain the bw until 0-lag */ | ||
1097 | dl_b->total_bw -= p->dl.dl_bw; | 1098 | dl_b->total_bw -= p->dl.dl_bw; |
1098 | raw_spin_unlock_irq(&dl_b->lock); | 1099 | raw_spin_unlock_irq(&dl_b->lock); |
1099 | 1100 | ||
@@ -1614,8 +1615,8 @@ static void cancel_dl_timer(struct rq *rq, struct task_struct *p) | |||
1614 | 1615 | ||
1615 | static void switched_from_dl(struct rq *rq, struct task_struct *p) | 1616 | static void switched_from_dl(struct rq *rq, struct task_struct *p) |
1616 | { | 1617 | { |
1618 | /* XXX we should retain the bw until 0-lag */ | ||
1617 | cancel_dl_timer(rq, p); | 1619 | cancel_dl_timer(rq, p); |
1618 | |||
1619 | __dl_clear_params(p); | 1620 | __dl_clear_params(p); |
1620 | 1621 | ||
1621 | /* | 1622 | /* |
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 40667cbf371b..fe331fc391f5 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c | |||
@@ -1730,7 +1730,7 @@ static int preferred_group_nid(struct task_struct *p, int nid) | |||
1730 | nodes = node_online_map; | 1730 | nodes = node_online_map; |
1731 | for (dist = sched_max_numa_distance; dist > LOCAL_DISTANCE; dist--) { | 1731 | for (dist = sched_max_numa_distance; dist > LOCAL_DISTANCE; dist--) { |
1732 | unsigned long max_faults = 0; | 1732 | unsigned long max_faults = 0; |
1733 | nodemask_t max_group; | 1733 | nodemask_t max_group = NODE_MASK_NONE; |
1734 | int a, b; | 1734 | int a, b; |
1735 | 1735 | ||
1736 | /* Are there nodes at this distance from each other? */ | 1736 | /* Are there nodes at this distance from each other? */ |
diff --git a/kernel/smpboot.c b/kernel/smpboot.c index f032fb5284e3..40190f28db35 100644 --- a/kernel/smpboot.c +++ b/kernel/smpboot.c | |||
@@ -280,6 +280,7 @@ int smpboot_register_percpu_thread(struct smp_hotplug_thread *plug_thread) | |||
280 | unsigned int cpu; | 280 | unsigned int cpu; |
281 | int ret = 0; | 281 | int ret = 0; |
282 | 282 | ||
283 | get_online_cpus(); | ||
283 | mutex_lock(&smpboot_threads_lock); | 284 | mutex_lock(&smpboot_threads_lock); |
284 | for_each_online_cpu(cpu) { | 285 | for_each_online_cpu(cpu) { |
285 | ret = __smpboot_create_thread(plug_thread, cpu); | 286 | ret = __smpboot_create_thread(plug_thread, cpu); |
@@ -292,6 +293,7 @@ int smpboot_register_percpu_thread(struct smp_hotplug_thread *plug_thread) | |||
292 | list_add(&plug_thread->list, &hotplug_threads); | 293 | list_add(&plug_thread->list, &hotplug_threads); |
293 | out: | 294 | out: |
294 | mutex_unlock(&smpboot_threads_lock); | 295 | mutex_unlock(&smpboot_threads_lock); |
296 | put_online_cpus(); | ||
295 | return ret; | 297 | return ret; |
296 | } | 298 | } |
297 | EXPORT_SYMBOL_GPL(smpboot_register_percpu_thread); | 299 | EXPORT_SYMBOL_GPL(smpboot_register_percpu_thread); |
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c index 37e50aadd471..d8c724cda37b 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c | |||
@@ -122,7 +122,7 @@ static void hrtimer_get_softirq_time(struct hrtimer_cpu_base *base) | |||
122 | mono = ktime_get_update_offsets_tick(&off_real, &off_boot, &off_tai); | 122 | mono = ktime_get_update_offsets_tick(&off_real, &off_boot, &off_tai); |
123 | boot = ktime_add(mono, off_boot); | 123 | boot = ktime_add(mono, off_boot); |
124 | xtim = ktime_add(mono, off_real); | 124 | xtim = ktime_add(mono, off_real); |
125 | tai = ktime_add(xtim, off_tai); | 125 | tai = ktime_add(mono, off_tai); |
126 | 126 | ||
127 | base->clock_base[HRTIMER_BASE_REALTIME].softirq_time = xtim; | 127 | base->clock_base[HRTIMER_BASE_REALTIME].softirq_time = xtim; |
128 | base->clock_base[HRTIMER_BASE_MONOTONIC].softirq_time = mono; | 128 | base->clock_base[HRTIMER_BASE_MONOTONIC].softirq_time = mono; |