diff options
Diffstat (limited to 'kernel/sched/core.c')
-rw-r--r-- | kernel/sched/core.c | 130 |
1 files changed, 42 insertions, 88 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index ead464a0f2e5..102dfcf0a29a 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
@@ -792,10 +792,14 @@ void activate_task(struct rq *rq, struct task_struct *p, int flags) | |||
792 | rq->nr_uninterruptible--; | 792 | rq->nr_uninterruptible--; |
793 | 793 | ||
794 | enqueue_task(rq, p, flags); | 794 | enqueue_task(rq, p, flags); |
795 | |||
796 | p->on_rq = TASK_ON_RQ_QUEUED; | ||
795 | } | 797 | } |
796 | 798 | ||
797 | void deactivate_task(struct rq *rq, struct task_struct *p, int flags) | 799 | void deactivate_task(struct rq *rq, struct task_struct *p, int flags) |
798 | { | 800 | { |
801 | p->on_rq = (flags & DEQUEUE_SLEEP) ? 0 : TASK_ON_RQ_MIGRATING; | ||
802 | |||
799 | if (task_contributes_to_load(p)) | 803 | if (task_contributes_to_load(p)) |
800 | rq->nr_uninterruptible++; | 804 | rq->nr_uninterruptible++; |
801 | 805 | ||
@@ -920,7 +924,7 @@ static inline bool is_per_cpu_kthread(struct task_struct *p) | |||
920 | } | 924 | } |
921 | 925 | ||
922 | /* | 926 | /* |
923 | * Per-CPU kthreads are allowed to run on !actie && online CPUs, see | 927 | * Per-CPU kthreads are allowed to run on !active && online CPUs, see |
924 | * __set_cpus_allowed_ptr() and select_fallback_rq(). | 928 | * __set_cpus_allowed_ptr() and select_fallback_rq(). |
925 | */ | 929 | */ |
926 | static inline bool is_cpu_allowed(struct task_struct *p, int cpu) | 930 | static inline bool is_cpu_allowed(struct task_struct *p, int cpu) |
@@ -1151,7 +1155,6 @@ static int __set_cpus_allowed_ptr(struct task_struct *p, | |||
1151 | /* Need help from migration thread: drop lock and wait. */ | 1155 | /* Need help from migration thread: drop lock and wait. */ |
1152 | task_rq_unlock(rq, p, &rf); | 1156 | task_rq_unlock(rq, p, &rf); |
1153 | stop_one_cpu(cpu_of(rq), migration_cpu_stop, &arg); | 1157 | stop_one_cpu(cpu_of(rq), migration_cpu_stop, &arg); |
1154 | tlb_migrate_finish(p->mm); | ||
1155 | return 0; | 1158 | return 0; |
1156 | } else if (task_on_rq_queued(p)) { | 1159 | } else if (task_on_rq_queued(p)) { |
1157 | /* | 1160 | /* |
@@ -1237,11 +1240,9 @@ static void __migrate_swap_task(struct task_struct *p, int cpu) | |||
1237 | rq_pin_lock(src_rq, &srf); | 1240 | rq_pin_lock(src_rq, &srf); |
1238 | rq_pin_lock(dst_rq, &drf); | 1241 | rq_pin_lock(dst_rq, &drf); |
1239 | 1242 | ||
1240 | p->on_rq = TASK_ON_RQ_MIGRATING; | ||
1241 | deactivate_task(src_rq, p, 0); | 1243 | deactivate_task(src_rq, p, 0); |
1242 | set_task_cpu(p, cpu); | 1244 | set_task_cpu(p, cpu); |
1243 | activate_task(dst_rq, p, 0); | 1245 | activate_task(dst_rq, p, 0); |
1244 | p->on_rq = TASK_ON_RQ_QUEUED; | ||
1245 | check_preempt_curr(dst_rq, p, 0); | 1246 | check_preempt_curr(dst_rq, p, 0); |
1246 | 1247 | ||
1247 | rq_unpin_lock(dst_rq, &drf); | 1248 | rq_unpin_lock(dst_rq, &drf); |
@@ -1681,16 +1682,6 @@ ttwu_stat(struct task_struct *p, int cpu, int wake_flags) | |||
1681 | __schedstat_inc(p->se.statistics.nr_wakeups_sync); | 1682 | __schedstat_inc(p->se.statistics.nr_wakeups_sync); |
1682 | } | 1683 | } |
1683 | 1684 | ||
1684 | static inline void ttwu_activate(struct rq *rq, struct task_struct *p, int en_flags) | ||
1685 | { | ||
1686 | activate_task(rq, p, en_flags); | ||
1687 | p->on_rq = TASK_ON_RQ_QUEUED; | ||
1688 | |||
1689 | /* If a worker is waking up, notify the workqueue: */ | ||
1690 | if (p->flags & PF_WQ_WORKER) | ||
1691 | wq_worker_waking_up(p, cpu_of(rq)); | ||
1692 | } | ||
1693 | |||
1694 | /* | 1685 | /* |
1695 | * Mark the task runnable and perform wakeup-preemption. | 1686 | * Mark the task runnable and perform wakeup-preemption. |
1696 | */ | 1687 | */ |
@@ -1742,7 +1733,7 @@ ttwu_do_activate(struct rq *rq, struct task_struct *p, int wake_flags, | |||
1742 | en_flags |= ENQUEUE_MIGRATED; | 1733 | en_flags |= ENQUEUE_MIGRATED; |
1743 | #endif | 1734 | #endif |
1744 | 1735 | ||
1745 | ttwu_activate(rq, p, en_flags); | 1736 | activate_task(rq, p, en_flags); |
1746 | ttwu_do_wakeup(rq, p, wake_flags, rf); | 1737 | ttwu_do_wakeup(rq, p, wake_flags, rf); |
1747 | } | 1738 | } |
1748 | 1739 | ||
@@ -2107,56 +2098,6 @@ out: | |||
2107 | } | 2098 | } |
2108 | 2099 | ||
2109 | /** | 2100 | /** |
2110 | * try_to_wake_up_local - try to wake up a local task with rq lock held | ||
2111 | * @p: the thread to be awakened | ||
2112 | * @rf: request-queue flags for pinning | ||
2113 | * | ||
2114 | * Put @p on the run-queue if it's not already there. The caller must | ||
2115 | * ensure that this_rq() is locked, @p is bound to this_rq() and not | ||
2116 | * the current task. | ||
2117 | */ | ||
2118 | static void try_to_wake_up_local(struct task_struct *p, struct rq_flags *rf) | ||
2119 | { | ||
2120 | struct rq *rq = task_rq(p); | ||
2121 | |||
2122 | if (WARN_ON_ONCE(rq != this_rq()) || | ||
2123 | WARN_ON_ONCE(p == current)) | ||
2124 | return; | ||
2125 | |||
2126 | lockdep_assert_held(&rq->lock); | ||
2127 | |||
2128 | if (!raw_spin_trylock(&p->pi_lock)) { | ||
2129 | /* | ||
2130 | * This is OK, because current is on_cpu, which avoids it being | ||
2131 | * picked for load-balance and preemption/IRQs are still | ||
2132 | * disabled avoiding further scheduler activity on it and we've | ||
2133 | * not yet picked a replacement task. | ||
2134 | */ | ||
2135 | rq_unlock(rq, rf); | ||
2136 | raw_spin_lock(&p->pi_lock); | ||
2137 | rq_relock(rq, rf); | ||
2138 | } | ||
2139 | |||
2140 | if (!(p->state & TASK_NORMAL)) | ||
2141 | goto out; | ||
2142 | |||
2143 | trace_sched_waking(p); | ||
2144 | |||
2145 | if (!task_on_rq_queued(p)) { | ||
2146 | if (p->in_iowait) { | ||
2147 | delayacct_blkio_end(p); | ||
2148 | atomic_dec(&rq->nr_iowait); | ||
2149 | } | ||
2150 | ttwu_activate(rq, p, ENQUEUE_WAKEUP | ENQUEUE_NOCLOCK); | ||
2151 | } | ||
2152 | |||
2153 | ttwu_do_wakeup(rq, p, 0, rf); | ||
2154 | ttwu_stat(p, smp_processor_id(), 0); | ||
2155 | out: | ||
2156 | raw_spin_unlock(&p->pi_lock); | ||
2157 | } | ||
2158 | |||
2159 | /** | ||
2160 | * wake_up_process - Wake up a specific process | 2101 | * wake_up_process - Wake up a specific process |
2161 | * @p: The process to be woken up. | 2102 | * @p: The process to be woken up. |
2162 | * | 2103 | * |
@@ -2467,7 +2408,6 @@ void wake_up_new_task(struct task_struct *p) | |||
2467 | post_init_entity_util_avg(p); | 2408 | post_init_entity_util_avg(p); |
2468 | 2409 | ||
2469 | activate_task(rq, p, ENQUEUE_NOCLOCK); | 2410 | activate_task(rq, p, ENQUEUE_NOCLOCK); |
2470 | p->on_rq = TASK_ON_RQ_QUEUED; | ||
2471 | trace_sched_wakeup_new(p); | 2411 | trace_sched_wakeup_new(p); |
2472 | check_preempt_curr(rq, p, WF_FORK); | 2412 | check_preempt_curr(rq, p, WF_FORK); |
2473 | #ifdef CONFIG_SMP | 2413 | #ifdef CONFIG_SMP |
@@ -3466,25 +3406,11 @@ static void __sched notrace __schedule(bool preempt) | |||
3466 | prev->state = TASK_RUNNING; | 3406 | prev->state = TASK_RUNNING; |
3467 | } else { | 3407 | } else { |
3468 | deactivate_task(rq, prev, DEQUEUE_SLEEP | DEQUEUE_NOCLOCK); | 3408 | deactivate_task(rq, prev, DEQUEUE_SLEEP | DEQUEUE_NOCLOCK); |
3469 | prev->on_rq = 0; | ||
3470 | 3409 | ||
3471 | if (prev->in_iowait) { | 3410 | if (prev->in_iowait) { |
3472 | atomic_inc(&rq->nr_iowait); | 3411 | atomic_inc(&rq->nr_iowait); |
3473 | delayacct_blkio_start(); | 3412 | delayacct_blkio_start(); |
3474 | } | 3413 | } |
3475 | |||
3476 | /* | ||
3477 | * If a worker went to sleep, notify and ask workqueue | ||
3478 | * whether it wants to wake up a task to maintain | ||
3479 | * concurrency. | ||
3480 | */ | ||
3481 | if (prev->flags & PF_WQ_WORKER) { | ||
3482 | struct task_struct *to_wakeup; | ||
3483 | |||
3484 | to_wakeup = wq_worker_sleeping(prev); | ||
3485 | if (to_wakeup) | ||
3486 | try_to_wake_up_local(to_wakeup, &rf); | ||
3487 | } | ||
3488 | } | 3414 | } |
3489 | switch_count = &prev->nvcsw; | 3415 | switch_count = &prev->nvcsw; |
3490 | } | 3416 | } |
@@ -3544,6 +3470,20 @@ static inline void sched_submit_work(struct task_struct *tsk) | |||
3544 | { | 3470 | { |
3545 | if (!tsk->state || tsk_is_pi_blocked(tsk)) | 3471 | if (!tsk->state || tsk_is_pi_blocked(tsk)) |
3546 | return; | 3472 | return; |
3473 | |||
3474 | /* | ||
3475 | * If a worker went to sleep, notify and ask workqueue whether | ||
3476 | * it wants to wake up a task to maintain concurrency. | ||
3477 | * As this function is called inside the schedule() context, | ||
3478 | * we disable preemption to avoid it calling schedule() again | ||
3479 | * in the possible wakeup of a kworker. | ||
3480 | */ | ||
3481 | if (tsk->flags & PF_WQ_WORKER) { | ||
3482 | preempt_disable(); | ||
3483 | wq_worker_sleeping(tsk); | ||
3484 | preempt_enable_no_resched(); | ||
3485 | } | ||
3486 | |||
3547 | /* | 3487 | /* |
3548 | * If we are going to sleep and we have plugged IO queued, | 3488 | * If we are going to sleep and we have plugged IO queued, |
3549 | * make sure to submit it to avoid deadlocks. | 3489 | * make sure to submit it to avoid deadlocks. |
@@ -3552,6 +3492,12 @@ static inline void sched_submit_work(struct task_struct *tsk) | |||
3552 | blk_schedule_flush_plug(tsk); | 3492 | blk_schedule_flush_plug(tsk); |
3553 | } | 3493 | } |
3554 | 3494 | ||
3495 | static void sched_update_worker(struct task_struct *tsk) | ||
3496 | { | ||
3497 | if (tsk->flags & PF_WQ_WORKER) | ||
3498 | wq_worker_running(tsk); | ||
3499 | } | ||
3500 | |||
3555 | asmlinkage __visible void __sched schedule(void) | 3501 | asmlinkage __visible void __sched schedule(void) |
3556 | { | 3502 | { |
3557 | struct task_struct *tsk = current; | 3503 | struct task_struct *tsk = current; |
@@ -3562,6 +3508,7 @@ asmlinkage __visible void __sched schedule(void) | |||
3562 | __schedule(false); | 3508 | __schedule(false); |
3563 | sched_preempt_enable_no_resched(); | 3509 | sched_preempt_enable_no_resched(); |
3564 | } while (need_resched()); | 3510 | } while (need_resched()); |
3511 | sched_update_worker(tsk); | ||
3565 | } | 3512 | } |
3566 | EXPORT_SYMBOL(schedule); | 3513 | EXPORT_SYMBOL(schedule); |
3567 | 3514 | ||
@@ -5918,7 +5865,7 @@ void __init sched_init_smp(void) | |||
5918 | 5865 | ||
5919 | static int __init migration_init(void) | 5866 | static int __init migration_init(void) |
5920 | { | 5867 | { |
5921 | sched_rq_cpu_starting(smp_processor_id()); | 5868 | sched_cpu_starting(smp_processor_id()); |
5922 | return 0; | 5869 | return 0; |
5923 | } | 5870 | } |
5924 | early_initcall(migration_init); | 5871 | early_initcall(migration_init); |
@@ -6559,6 +6506,8 @@ static void cpu_cgroup_attach(struct cgroup_taskset *tset) | |||
6559 | static int cpu_shares_write_u64(struct cgroup_subsys_state *css, | 6506 | static int cpu_shares_write_u64(struct cgroup_subsys_state *css, |
6560 | struct cftype *cftype, u64 shareval) | 6507 | struct cftype *cftype, u64 shareval) |
6561 | { | 6508 | { |
6509 | if (shareval > scale_load_down(ULONG_MAX)) | ||
6510 | shareval = MAX_SHARES; | ||
6562 | return sched_group_set_shares(css_tg(css), scale_load(shareval)); | 6511 | return sched_group_set_shares(css_tg(css), scale_load(shareval)); |
6563 | } | 6512 | } |
6564 | 6513 | ||
@@ -6574,7 +6523,7 @@ static u64 cpu_shares_read_u64(struct cgroup_subsys_state *css, | |||
6574 | static DEFINE_MUTEX(cfs_constraints_mutex); | 6523 | static DEFINE_MUTEX(cfs_constraints_mutex); |
6575 | 6524 | ||
6576 | const u64 max_cfs_quota_period = 1 * NSEC_PER_SEC; /* 1s */ | 6525 | const u64 max_cfs_quota_period = 1 * NSEC_PER_SEC; /* 1s */ |
6577 | const u64 min_cfs_quota_period = 1 * NSEC_PER_MSEC; /* 1ms */ | 6526 | static const u64 min_cfs_quota_period = 1 * NSEC_PER_MSEC; /* 1ms */ |
6578 | 6527 | ||
6579 | static int __cfs_schedulable(struct task_group *tg, u64 period, u64 runtime); | 6528 | static int __cfs_schedulable(struct task_group *tg, u64 period, u64 runtime); |
6580 | 6529 | ||
@@ -6654,20 +6603,22 @@ out_unlock: | |||
6654 | return ret; | 6603 | return ret; |
6655 | } | 6604 | } |
6656 | 6605 | ||
6657 | int tg_set_cfs_quota(struct task_group *tg, long cfs_quota_us) | 6606 | static int tg_set_cfs_quota(struct task_group *tg, long cfs_quota_us) |
6658 | { | 6607 | { |
6659 | u64 quota, period; | 6608 | u64 quota, period; |
6660 | 6609 | ||
6661 | period = ktime_to_ns(tg->cfs_bandwidth.period); | 6610 | period = ktime_to_ns(tg->cfs_bandwidth.period); |
6662 | if (cfs_quota_us < 0) | 6611 | if (cfs_quota_us < 0) |
6663 | quota = RUNTIME_INF; | 6612 | quota = RUNTIME_INF; |
6664 | else | 6613 | else if ((u64)cfs_quota_us <= U64_MAX / NSEC_PER_USEC) |
6665 | quota = (u64)cfs_quota_us * NSEC_PER_USEC; | 6614 | quota = (u64)cfs_quota_us * NSEC_PER_USEC; |
6615 | else | ||
6616 | return -EINVAL; | ||
6666 | 6617 | ||
6667 | return tg_set_cfs_bandwidth(tg, period, quota); | 6618 | return tg_set_cfs_bandwidth(tg, period, quota); |
6668 | } | 6619 | } |
6669 | 6620 | ||
6670 | long tg_get_cfs_quota(struct task_group *tg) | 6621 | static long tg_get_cfs_quota(struct task_group *tg) |
6671 | { | 6622 | { |
6672 | u64 quota_us; | 6623 | u64 quota_us; |
6673 | 6624 | ||
@@ -6680,17 +6631,20 @@ long tg_get_cfs_quota(struct task_group *tg) | |||
6680 | return quota_us; | 6631 | return quota_us; |
6681 | } | 6632 | } |
6682 | 6633 | ||
6683 | int tg_set_cfs_period(struct task_group *tg, long cfs_period_us) | 6634 | static int tg_set_cfs_period(struct task_group *tg, long cfs_period_us) |
6684 | { | 6635 | { |
6685 | u64 quota, period; | 6636 | u64 quota, period; |
6686 | 6637 | ||
6638 | if ((u64)cfs_period_us > U64_MAX / NSEC_PER_USEC) | ||
6639 | return -EINVAL; | ||
6640 | |||
6687 | period = (u64)cfs_period_us * NSEC_PER_USEC; | 6641 | period = (u64)cfs_period_us * NSEC_PER_USEC; |
6688 | quota = tg->cfs_bandwidth.quota; | 6642 | quota = tg->cfs_bandwidth.quota; |
6689 | 6643 | ||
6690 | return tg_set_cfs_bandwidth(tg, period, quota); | 6644 | return tg_set_cfs_bandwidth(tg, period, quota); |
6691 | } | 6645 | } |
6692 | 6646 | ||
6693 | long tg_get_cfs_period(struct task_group *tg) | 6647 | static long tg_get_cfs_period(struct task_group *tg) |
6694 | { | 6648 | { |
6695 | u64 cfs_period_us; | 6649 | u64 cfs_period_us; |
6696 | 6650 | ||
@@ -6998,7 +6952,7 @@ static int __maybe_unused cpu_period_quota_parse(char *buf, | |||
6998 | { | 6952 | { |
6999 | char tok[21]; /* U64_MAX */ | 6953 | char tok[21]; /* U64_MAX */ |
7000 | 6954 | ||
7001 | if (!sscanf(buf, "%s %llu", tok, periodp)) | 6955 | if (sscanf(buf, "%20s %llu", tok, periodp) < 1) |
7002 | return -EINVAL; | 6956 | return -EINVAL; |
7003 | 6957 | ||
7004 | *periodp *= NSEC_PER_USEC; | 6958 | *periodp *= NSEC_PER_USEC; |