aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sched')
-rw-r--r--kernel/sched/core.c10
-rw-r--r--kernel/sched/deadline.c11
-rw-r--r--kernel/sched/fair.c16
-rw-r--r--kernel/sched/rt.c7
-rw-r--r--kernel/sched/sched.h9
5 files changed, 37 insertions, 16 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 268a45ea238c..d9d8ece46a15 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -2192,7 +2192,7 @@ static inline void post_schedule(struct rq *rq)
2192 * schedule_tail - first thing a freshly forked thread must call. 2192 * schedule_tail - first thing a freshly forked thread must call.
2193 * @prev: the thread we just switched away from. 2193 * @prev: the thread we just switched away from.
2194 */ 2194 */
2195asmlinkage void schedule_tail(struct task_struct *prev) 2195asmlinkage __visible void schedule_tail(struct task_struct *prev)
2196 __releases(rq->lock) 2196 __releases(rq->lock)
2197{ 2197{
2198 struct rq *rq = this_rq(); 2198 struct rq *rq = this_rq();
@@ -2741,7 +2741,7 @@ static inline void sched_submit_work(struct task_struct *tsk)
2741 blk_schedule_flush_plug(tsk); 2741 blk_schedule_flush_plug(tsk);
2742} 2742}
2743 2743
2744asmlinkage void __sched schedule(void) 2744asmlinkage __visible void __sched schedule(void)
2745{ 2745{
2746 struct task_struct *tsk = current; 2746 struct task_struct *tsk = current;
2747 2747
@@ -2751,7 +2751,7 @@ asmlinkage void __sched schedule(void)
2751EXPORT_SYMBOL(schedule); 2751EXPORT_SYMBOL(schedule);
2752 2752
2753#ifdef CONFIG_CONTEXT_TRACKING 2753#ifdef CONFIG_CONTEXT_TRACKING
2754asmlinkage void __sched schedule_user(void) 2754asmlinkage __visible void __sched schedule_user(void)
2755{ 2755{
2756 /* 2756 /*
2757 * If we come here after a random call to set_need_resched(), 2757 * If we come here after a random call to set_need_resched(),
@@ -2783,7 +2783,7 @@ void __sched schedule_preempt_disabled(void)
2783 * off of preempt_enable. Kernel preemptions off return from interrupt 2783 * off of preempt_enable. Kernel preemptions off return from interrupt
2784 * occur there and call schedule directly. 2784 * occur there and call schedule directly.
2785 */ 2785 */
2786asmlinkage void __sched notrace preempt_schedule(void) 2786asmlinkage __visible void __sched notrace preempt_schedule(void)
2787{ 2787{
2788 /* 2788 /*
2789 * If there is a non-zero preempt_count or interrupts are disabled, 2789 * If there is a non-zero preempt_count or interrupts are disabled,
@@ -2813,7 +2813,7 @@ EXPORT_SYMBOL(preempt_schedule);
2813 * Note, that this is called and return with irqs disabled. This will 2813 * Note, that this is called and return with irqs disabled. This will
2814 * protect us against recursive calling from irq. 2814 * protect us against recursive calling from irq.
2815 */ 2815 */
2816asmlinkage void __sched preempt_schedule_irq(void) 2816asmlinkage __visible void __sched preempt_schedule_irq(void)
2817{ 2817{
2818 enum ctx_state prev_state; 2818 enum ctx_state prev_state;
2819 2819
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
index 27ef40925525..b08095786cb8 100644
--- a/kernel/sched/deadline.c
+++ b/kernel/sched/deadline.c
@@ -1021,8 +1021,17 @@ struct task_struct *pick_next_task_dl(struct rq *rq, struct task_struct *prev)
1021 1021
1022 dl_rq = &rq->dl; 1022 dl_rq = &rq->dl;
1023 1023
1024 if (need_pull_dl_task(rq, prev)) 1024 if (need_pull_dl_task(rq, prev)) {
1025 pull_dl_task(rq); 1025 pull_dl_task(rq);
1026 /*
1027 * pull_rt_task() can drop (and re-acquire) rq->lock; this
1028 * means a stop task can slip in, in which case we need to
1029 * re-start task selection.
1030 */
1031 if (rq->stop && rq->stop->on_rq)
1032 return RETRY_TASK;
1033 }
1034
1026 /* 1035 /*
1027 * When prev is DL, we may throttle it in put_prev_task(). 1036 * When prev is DL, we may throttle it in put_prev_task().
1028 * So, we update time before we check for dl_nr_running. 1037 * So, we update time before we check for dl_nr_running.
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 7e9bd0b1fa9e..7570dd969c28 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -1497,7 +1497,7 @@ static void task_numa_placement(struct task_struct *p)
1497 /* If the task is part of a group prevent parallel updates to group stats */ 1497 /* If the task is part of a group prevent parallel updates to group stats */
1498 if (p->numa_group) { 1498 if (p->numa_group) {
1499 group_lock = &p->numa_group->lock; 1499 group_lock = &p->numa_group->lock;
1500 spin_lock(group_lock); 1500 spin_lock_irq(group_lock);
1501 } 1501 }
1502 1502
1503 /* Find the node with the highest number of faults */ 1503 /* Find the node with the highest number of faults */
@@ -1572,7 +1572,7 @@ static void task_numa_placement(struct task_struct *p)
1572 } 1572 }
1573 } 1573 }
1574 1574
1575 spin_unlock(group_lock); 1575 spin_unlock_irq(group_lock);
1576 } 1576 }
1577 1577
1578 /* Preferred node as the node with the most faults */ 1578 /* Preferred node as the node with the most faults */
@@ -1677,7 +1677,8 @@ static void task_numa_group(struct task_struct *p, int cpupid, int flags,
1677 if (!join) 1677 if (!join)
1678 return; 1678 return;
1679 1679
1680 double_lock(&my_grp->lock, &grp->lock); 1680 BUG_ON(irqs_disabled());
1681 double_lock_irq(&my_grp->lock, &grp->lock);
1681 1682
1682 for (i = 0; i < NR_NUMA_HINT_FAULT_STATS * nr_node_ids; i++) { 1683 for (i = 0; i < NR_NUMA_HINT_FAULT_STATS * nr_node_ids; i++) {
1683 my_grp->faults[i] -= p->numa_faults_memory[i]; 1684 my_grp->faults[i] -= p->numa_faults_memory[i];
@@ -1691,7 +1692,7 @@ static void task_numa_group(struct task_struct *p, int cpupid, int flags,
1691 grp->nr_tasks++; 1692 grp->nr_tasks++;
1692 1693
1693 spin_unlock(&my_grp->lock); 1694 spin_unlock(&my_grp->lock);
1694 spin_unlock(&grp->lock); 1695 spin_unlock_irq(&grp->lock);
1695 1696
1696 rcu_assign_pointer(p->numa_group, grp); 1697 rcu_assign_pointer(p->numa_group, grp);
1697 1698
@@ -1710,14 +1711,14 @@ void task_numa_free(struct task_struct *p)
1710 void *numa_faults = p->numa_faults_memory; 1711 void *numa_faults = p->numa_faults_memory;
1711 1712
1712 if (grp) { 1713 if (grp) {
1713 spin_lock(&grp->lock); 1714 spin_lock_irq(&grp->lock);
1714 for (i = 0; i < NR_NUMA_HINT_FAULT_STATS * nr_node_ids; i++) 1715 for (i = 0; i < NR_NUMA_HINT_FAULT_STATS * nr_node_ids; i++)
1715 grp->faults[i] -= p->numa_faults_memory[i]; 1716 grp->faults[i] -= p->numa_faults_memory[i];
1716 grp->total_faults -= p->total_numa_faults; 1717 grp->total_faults -= p->total_numa_faults;
1717 1718
1718 list_del(&p->numa_entry); 1719 list_del(&p->numa_entry);
1719 grp->nr_tasks--; 1720 grp->nr_tasks--;
1720 spin_unlock(&grp->lock); 1721 spin_unlock_irq(&grp->lock);
1721 rcu_assign_pointer(p->numa_group, NULL); 1722 rcu_assign_pointer(p->numa_group, NULL);
1722 put_numa_group(grp); 1723 put_numa_group(grp);
1723 } 1724 }
@@ -6727,7 +6728,8 @@ static int idle_balance(struct rq *this_rq)
6727out: 6728out:
6728 /* Is there a task of a high priority class? */ 6729 /* Is there a task of a high priority class? */
6729 if (this_rq->nr_running != this_rq->cfs.h_nr_running && 6730 if (this_rq->nr_running != this_rq->cfs.h_nr_running &&
6730 (this_rq->dl.dl_nr_running || 6731 ((this_rq->stop && this_rq->stop->on_rq) ||
6732 this_rq->dl.dl_nr_running ||
6731 (this_rq->rt.rt_nr_running && !rt_rq_throttled(&this_rq->rt)))) 6733 (this_rq->rt.rt_nr_running && !rt_rq_throttled(&this_rq->rt))))
6732 pulled_task = -1; 6734 pulled_task = -1;
6733 6735
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index d8cdf1618551..bd2267ad404f 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -1362,10 +1362,11 @@ pick_next_task_rt(struct rq *rq, struct task_struct *prev)
1362 pull_rt_task(rq); 1362 pull_rt_task(rq);
1363 /* 1363 /*
1364 * pull_rt_task() can drop (and re-acquire) rq->lock; this 1364 * pull_rt_task() can drop (and re-acquire) rq->lock; this
1365 * means a dl task can slip in, in which case we need to 1365 * means a dl or stop task can slip in, in which case we need
1366 * re-start task selection. 1366 * to re-start task selection.
1367 */ 1367 */
1368 if (unlikely(rq->dl.dl_nr_running)) 1368 if (unlikely((rq->stop && rq->stop->on_rq) ||
1369 rq->dl.dl_nr_running))
1369 return RETRY_TASK; 1370 return RETRY_TASK;
1370 } 1371 }
1371 1372
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index c9007f28d3a2..456e492a3dca 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -1385,6 +1385,15 @@ static inline void double_lock(spinlock_t *l1, spinlock_t *l2)
1385 spin_lock_nested(l2, SINGLE_DEPTH_NESTING); 1385 spin_lock_nested(l2, SINGLE_DEPTH_NESTING);
1386} 1386}
1387 1387
1388static inline void double_lock_irq(spinlock_t *l1, spinlock_t *l2)
1389{
1390 if (l1 > l2)
1391 swap(l1, l2);
1392
1393 spin_lock_irq(l1);
1394 spin_lock_nested(l2, SINGLE_DEPTH_NESTING);
1395}
1396
1388static inline void double_raw_lock(raw_spinlock_t *l1, raw_spinlock_t *l2) 1397static inline void double_raw_lock(raw_spinlock_t *l1, raw_spinlock_t *l2)
1389{ 1398{
1390 if (l1 > l2) 1399 if (l1 > l2)