aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sched.c')
-rw-r--r--kernel/sched.c53
1 files changed, 51 insertions, 2 deletions
diff --git a/kernel/sched.c b/kernel/sched.c
index 96eafd5f345f..edd5a54b95da 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -77,6 +77,7 @@
77#include <asm/irq_regs.h> 77#include <asm/irq_regs.h>
78 78
79#include "sched_cpupri.h" 79#include "sched_cpupri.h"
80#include "workqueue_sched.h"
80 81
81#define CREATE_TRACE_POINTS 82#define CREATE_TRACE_POINTS
82#include <trace/events/sched.h> 83#include <trace/events/sched.h>
@@ -2306,6 +2307,9 @@ static inline void ttwu_post_activation(struct task_struct *p, struct rq *rq,
2306 rq->idle_stamp = 0; 2307 rq->idle_stamp = 0;
2307 } 2308 }
2308#endif 2309#endif
2310 /* if a worker is waking up, notify workqueue */
2311 if ((p->flags & PF_WQ_WORKER) && success)
2312 wq_worker_waking_up(p, cpu_of(rq));
2309} 2313}
2310 2314
2311/** 2315/**
@@ -2414,6 +2418,37 @@ out:
2414} 2418}
2415 2419
2416/** 2420/**
2421 * try_to_wake_up_local - try to wake up a local task with rq lock held
2422 * @p: the thread to be awakened
2423 *
2424 * Put @p on the run-queue if it's not alredy there. The caller must
2425 * ensure that this_rq() is locked, @p is bound to this_rq() and not
2426 * the current task. this_rq() stays locked over invocation.
2427 */
2428static void try_to_wake_up_local(struct task_struct *p)
2429{
2430 struct rq *rq = task_rq(p);
2431 bool success = false;
2432
2433 BUG_ON(rq != this_rq());
2434 BUG_ON(p == current);
2435 lockdep_assert_held(&rq->lock);
2436
2437 if (!(p->state & TASK_NORMAL))
2438 return;
2439
2440 if (!p->se.on_rq) {
2441 if (likely(!task_running(rq, p))) {
2442 schedstat_inc(rq, ttwu_count);
2443 schedstat_inc(rq, ttwu_local);
2444 }
2445 ttwu_activate(p, rq, false, false, true, ENQUEUE_WAKEUP);
2446 success = true;
2447 }
2448 ttwu_post_activation(p, rq, 0, success);
2449}
2450
2451/**
2417 * wake_up_process - Wake up a specific process 2452 * wake_up_process - Wake up a specific process
2418 * @p: The process to be woken up. 2453 * @p: The process to be woken up.
2419 * 2454 *
@@ -3618,10 +3653,24 @@ need_resched_nonpreemptible:
3618 clear_tsk_need_resched(prev); 3653 clear_tsk_need_resched(prev);
3619 3654
3620 if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) { 3655 if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
3621 if (unlikely(signal_pending_state(prev->state, prev))) 3656 if (unlikely(signal_pending_state(prev->state, prev))) {
3622 prev->state = TASK_RUNNING; 3657 prev->state = TASK_RUNNING;
3623 else 3658 } else {
3659 /*
3660 * If a worker is going to sleep, notify and
3661 * ask workqueue whether it wants to wake up a
3662 * task to maintain concurrency. If so, wake
3663 * up the task.
3664 */
3665 if (prev->flags & PF_WQ_WORKER) {
3666 struct task_struct *to_wakeup;
3667
3668 to_wakeup = wq_worker_sleeping(prev, cpu);
3669 if (to_wakeup)
3670 try_to_wake_up_local(to_wakeup);
3671 }
3624 deactivate_task(rq, prev, DEQUEUE_SLEEP); 3672 deactivate_task(rq, prev, DEQUEUE_SLEEP);
3673 }
3625 switch_count = &prev->nvcsw; 3674 switch_count = &prev->nvcsw;
3626 } 3675 }
3627 3676