You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'sched-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull scheduler updates from Ingo Molnar:
"The main changes in this cycle were:
- Optimized support for Intel "Cluster-on-Die" (CoD) topologies (Dave
Hansen)
- Various sched/idle refinements for better idle handling (Nicolas
Pitre, Daniel Lezcano, Chuansheng Liu, Vincent Guittot)
- sched/numa updates and optimizations (Rik van Riel)
- sysbench speedup (Vincent Guittot)
- capacity calculation cleanups/refactoring (Vincent Guittot)
- Various cleanups to thread group iteration (Oleg Nesterov)
- Double-rq-lock removal optimization and various refactorings
(Kirill Tkhai)
- various sched/deadline fixes
... and lots of other changes"
* 'sched-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (72 commits)
sched/dl: Use dl_bw_of() under rcu_read_lock_sched()
sched/fair: Delete resched_cpu() from idle_balance()
sched, time: Fix build error with 64 bit cputime_t on 32 bit systems
sched: Improve sysbench performance by fixing spurious active migration
sched/x86: Fix up typo in topology detection
x86, sched: Add new topology for multi-NUMA-node CPUs
sched/rt: Use resched_curr() in task_tick_rt()
sched: Use rq->rd in sched_setaffinity() under RCU read lock
sched: cleanup: Rename 'out_unlock' to 'out_free_new_mask'
sched: Use dl_bw_of() under RCU read lock
sched/fair: Remove duplicate code from can_migrate_task()
sched, mips, ia64: Remove __ARCH_WANT_UNLOCKED_CTXSW
sched: print_rq(): Don't use tasklist_lock
sched: normalize_rt_tasks(): Don't use _irqsave for tasklist_lock, use task_rq_lock()
sched: Fix the task-group check in tg_has_rt_tasks()
sched/fair: Leverage the idle state info when choosing the "idlest" cpu
sched: Let the scheduler see CPU idle states
sched/deadline: Fix inter- exclusive cpusets migrations
sched/deadline: Clear dl_entity params when setscheduling to different class
sched/numa: Kill the wrong/dead TASK_DEAD check in task_numa_fault()
...
This commit is contained in:
+25
-22
@@ -115,32 +115,33 @@ static void __exit_signal(struct task_struct *tsk)
|
||||
|
||||
if (tsk == sig->curr_target)
|
||||
sig->curr_target = next_thread(tsk);
|
||||
/*
|
||||
* Accumulate here the counters for all threads but the
|
||||
* group leader as they die, so they can be added into
|
||||
* the process-wide totals when those are taken.
|
||||
* The group leader stays around as a zombie as long
|
||||
* as there are other threads. When it gets reaped,
|
||||
* the exit.c code will add its counts into these totals.
|
||||
* We won't ever get here for the group leader, since it
|
||||
* will have been the last reference on the signal_struct.
|
||||
*/
|
||||
task_cputime(tsk, &utime, &stime);
|
||||
sig->utime += utime;
|
||||
sig->stime += stime;
|
||||
sig->gtime += task_gtime(tsk);
|
||||
sig->min_flt += tsk->min_flt;
|
||||
sig->maj_flt += tsk->maj_flt;
|
||||
sig->nvcsw += tsk->nvcsw;
|
||||
sig->nivcsw += tsk->nivcsw;
|
||||
sig->inblock += task_io_get_inblock(tsk);
|
||||
sig->oublock += task_io_get_oublock(tsk);
|
||||
task_io_accounting_add(&sig->ioac, &tsk->ioac);
|
||||
sig->sum_sched_runtime += tsk->se.sum_exec_runtime;
|
||||
}
|
||||
|
||||
/*
|
||||
* Accumulate here the counters for all threads but the group leader
|
||||
* as they die, so they can be added into the process-wide totals
|
||||
* when those are taken. The group leader stays around as a zombie as
|
||||
* long as there are other threads. When it gets reaped, the exit.c
|
||||
* code will add its counts into these totals. We won't ever get here
|
||||
* for the group leader, since it will have been the last reference on
|
||||
* the signal_struct.
|
||||
*/
|
||||
task_cputime(tsk, &utime, &stime);
|
||||
write_seqlock(&sig->stats_lock);
|
||||
sig->utime += utime;
|
||||
sig->stime += stime;
|
||||
sig->gtime += task_gtime(tsk);
|
||||
sig->min_flt += tsk->min_flt;
|
||||
sig->maj_flt += tsk->maj_flt;
|
||||
sig->nvcsw += tsk->nvcsw;
|
||||
sig->nivcsw += tsk->nivcsw;
|
||||
sig->inblock += task_io_get_inblock(tsk);
|
||||
sig->oublock += task_io_get_oublock(tsk);
|
||||
task_io_accounting_add(&sig->ioac, &tsk->ioac);
|
||||
sig->sum_sched_runtime += tsk->se.sum_exec_runtime;
|
||||
sig->nr_threads--;
|
||||
__unhash_process(tsk, group_dead);
|
||||
write_sequnlock(&sig->stats_lock);
|
||||
|
||||
/*
|
||||
* Do this under ->siglock, we can race with another thread
|
||||
@@ -1046,6 +1047,7 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
|
||||
spin_lock_irq(&p->real_parent->sighand->siglock);
|
||||
psig = p->real_parent->signal;
|
||||
sig = p->signal;
|
||||
write_seqlock(&psig->stats_lock);
|
||||
psig->cutime += tgutime + sig->cutime;
|
||||
psig->cstime += tgstime + sig->cstime;
|
||||
psig->cgtime += task_gtime(p) + sig->gtime + sig->cgtime;
|
||||
@@ -1068,6 +1070,7 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
|
||||
psig->cmaxrss = maxrss;
|
||||
task_io_accounting_add(&psig->ioac, &p->ioac);
|
||||
task_io_accounting_add(&psig->ioac, &sig->ioac);
|
||||
write_sequnlock(&psig->stats_lock);
|
||||
spin_unlock_irq(&p->real_parent->sighand->siglock);
|
||||
}
|
||||
|
||||
|
||||
+10
-3
@@ -294,11 +294,18 @@ int __weak arch_dup_task_struct(struct task_struct *dst,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void set_task_stack_end_magic(struct task_struct *tsk)
|
||||
{
|
||||
unsigned long *stackend;
|
||||
|
||||
stackend = end_of_stack(tsk);
|
||||
*stackend = STACK_END_MAGIC; /* for overflow detection */
|
||||
}
|
||||
|
||||
static struct task_struct *dup_task_struct(struct task_struct *orig)
|
||||
{
|
||||
struct task_struct *tsk;
|
||||
struct thread_info *ti;
|
||||
unsigned long *stackend;
|
||||
int node = tsk_fork_get_node(orig);
|
||||
int err;
|
||||
|
||||
@@ -328,8 +335,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
|
||||
setup_thread_stack(tsk, orig);
|
||||
clear_user_return_notifier(tsk);
|
||||
clear_tsk_need_resched(tsk);
|
||||
stackend = end_of_stack(tsk);
|
||||
*stackend = STACK_END_MAGIC; /* for overflow detection */
|
||||
set_task_stack_end_magic(tsk);
|
||||
|
||||
#ifdef CONFIG_CC_STACKPROTECTOR
|
||||
tsk->stack_canary = get_random_int();
|
||||
@@ -1067,6 +1073,7 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
|
||||
sig->curr_target = tsk;
|
||||
init_sigpending(&sig->shared_pending);
|
||||
INIT_LIST_HEAD(&sig->posix_timers);
|
||||
seqlock_init(&sig->stats_lock);
|
||||
|
||||
hrtimer_init(&sig->real_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
||||
sig->real_timer.function = it_real_fn;
|
||||
|
||||
@@ -148,11 +148,8 @@ autogroup_move_group(struct task_struct *p, struct autogroup *ag)
|
||||
if (!ACCESS_ONCE(sysctl_sched_autogroup_enabled))
|
||||
goto out;
|
||||
|
||||
t = p;
|
||||
do {
|
||||
for_each_thread(p, t)
|
||||
sched_move_task(t);
|
||||
} while_each_thread(p, t);
|
||||
|
||||
out:
|
||||
unlock_task_sighand(p, &flags);
|
||||
autogroup_kref_put(prev);
|
||||
|
||||
+189
-106
File diff suppressed because it is too large
Load Diff
@@ -107,9 +107,7 @@ int cpudl_find(struct cpudl *cp, struct task_struct *p,
|
||||
int best_cpu = -1;
|
||||
const struct sched_dl_entity *dl_se = &p->dl;
|
||||
|
||||
if (later_mask && cpumask_and(later_mask, cp->free_cpus,
|
||||
&p->cpus_allowed) && cpumask_and(later_mask,
|
||||
later_mask, cpu_active_mask)) {
|
||||
if (later_mask && cpumask_and(later_mask, later_mask, cp->free_cpus)) {
|
||||
best_cpu = cpumask_any(later_mask);
|
||||
goto out;
|
||||
} else if (cpumask_test_cpu(cpudl_maximum(cp), &p->cpus_allowed) &&
|
||||
|
||||
+39
-25
@@ -288,24 +288,29 @@ void thread_group_cputime(struct task_struct *tsk, struct task_cputime *times)
|
||||
struct signal_struct *sig = tsk->signal;
|
||||
cputime_t utime, stime;
|
||||
struct task_struct *t;
|
||||
|
||||
times->utime = sig->utime;
|
||||
times->stime = sig->stime;
|
||||
times->sum_exec_runtime = sig->sum_sched_runtime;
|
||||
unsigned int seq, nextseq;
|
||||
unsigned long flags;
|
||||
|
||||
rcu_read_lock();
|
||||
/* make sure we can trust tsk->thread_group list */
|
||||
if (!likely(pid_alive(tsk)))
|
||||
goto out;
|
||||
|
||||
t = tsk;
|
||||
/* Attempt a lockless read on the first round. */
|
||||
nextseq = 0;
|
||||
do {
|
||||
task_cputime(t, &utime, &stime);
|
||||
times->utime += utime;
|
||||
times->stime += stime;
|
||||
times->sum_exec_runtime += task_sched_runtime(t);
|
||||
} while_each_thread(tsk, t);
|
||||
out:
|
||||
seq = nextseq;
|
||||
flags = read_seqbegin_or_lock_irqsave(&sig->stats_lock, &seq);
|
||||
times->utime = sig->utime;
|
||||
times->stime = sig->stime;
|
||||
times->sum_exec_runtime = sig->sum_sched_runtime;
|
||||
|
||||
for_each_thread(tsk, t) {
|
||||
task_cputime(t, &utime, &stime);
|
||||
times->utime += utime;
|
||||
times->stime += stime;
|
||||
times->sum_exec_runtime += task_sched_runtime(t);
|
||||
}
|
||||
/* If lockless access failed, take the lock. */
|
||||
nextseq = 1;
|
||||
} while (need_seqretry(&sig->stats_lock, seq));
|
||||
done_seqretry_irqrestore(&sig->stats_lock, seq, flags);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
@@ -549,6 +554,23 @@ drop_precision:
|
||||
return (__force cputime_t) scaled;
|
||||
}
|
||||
|
||||
/*
|
||||
* Atomically advance counter to the new value. Interrupts, vcpu
|
||||
* scheduling, and scaling inaccuracies can cause cputime_advance
|
||||
* to be occasionally called with a new value smaller than counter.
|
||||
* Let's enforce atomicity.
|
||||
*
|
||||
* Normally a caller will only go through this loop once, or not
|
||||
* at all in case a previous caller updated counter the same jiffy.
|
||||
*/
|
||||
static void cputime_advance(cputime_t *counter, cputime_t new)
|
||||
{
|
||||
cputime_t old;
|
||||
|
||||
while (new > (old = ACCESS_ONCE(*counter)))
|
||||
cmpxchg_cputime(counter, old, new);
|
||||
}
|
||||
|
||||
/*
|
||||
* Adjust tick based cputime random precision against scheduler
|
||||
* runtime accounting.
|
||||
@@ -594,13 +616,8 @@ static void cputime_adjust(struct task_cputime *curr,
|
||||
utime = rtime - stime;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the tick based count grows faster than the scheduler one,
|
||||
* the result of the scaling may go backward.
|
||||
* Let's enforce monotonicity.
|
||||
*/
|
||||
prev->stime = max(prev->stime, stime);
|
||||
prev->utime = max(prev->utime, utime);
|
||||
cputime_advance(&prev->stime, stime);
|
||||
cputime_advance(&prev->utime, utime);
|
||||
|
||||
out:
|
||||
*ut = prev->utime;
|
||||
@@ -617,9 +634,6 @@ void task_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime_t *st)
|
||||
cputime_adjust(&cputime, &p->prev_cputime, ut, st);
|
||||
}
|
||||
|
||||
/*
|
||||
* Must be called with siglock held.
|
||||
*/
|
||||
void thread_group_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime_t *st)
|
||||
{
|
||||
struct task_cputime cputime;
|
||||
|
||||
+19
-14
@@ -530,7 +530,7 @@ again:
|
||||
update_rq_clock(rq);
|
||||
dl_se->dl_throttled = 0;
|
||||
dl_se->dl_yielded = 0;
|
||||
if (p->on_rq) {
|
||||
if (task_on_rq_queued(p)) {
|
||||
enqueue_task_dl(rq, p, ENQUEUE_REPLENISH);
|
||||
if (task_has_dl_policy(rq->curr))
|
||||
check_preempt_curr_dl(rq, p, 0);
|
||||
@@ -997,10 +997,7 @@ static void check_preempt_curr_dl(struct rq *rq, struct task_struct *p,
|
||||
#ifdef CONFIG_SCHED_HRTICK
|
||||
static void start_hrtick_dl(struct rq *rq, struct task_struct *p)
|
||||
{
|
||||
s64 delta = p->dl.dl_runtime - p->dl.runtime;
|
||||
|
||||
if (delta > 10000)
|
||||
hrtick_start(rq, p->dl.runtime);
|
||||
hrtick_start(rq, p->dl.runtime);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1030,7 +1027,7 @@ struct task_struct *pick_next_task_dl(struct rq *rq, struct task_struct *prev)
|
||||
* means a stop task can slip in, in which case we need to
|
||||
* re-start task selection.
|
||||
*/
|
||||
if (rq->stop && rq->stop->on_rq)
|
||||
if (rq->stop && task_on_rq_queued(rq->stop))
|
||||
return RETRY_TASK;
|
||||
}
|
||||
|
||||
@@ -1124,10 +1121,8 @@ static void set_curr_task_dl(struct rq *rq)
|
||||
static int pick_dl_task(struct rq *rq, struct task_struct *p, int cpu)
|
||||
{
|
||||
if (!task_running(rq, p) &&
|
||||
(cpu < 0 || cpumask_test_cpu(cpu, &p->cpus_allowed)) &&
|
||||
(p->nr_cpus_allowed > 1))
|
||||
cpumask_test_cpu(cpu, tsk_cpus_allowed(p)))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1169,6 +1164,13 @@ static int find_later_rq(struct task_struct *task)
|
||||
if (task->nr_cpus_allowed == 1)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* We have to consider system topology and task affinity
|
||||
* first, then we can look for a suitable cpu.
|
||||
*/
|
||||
cpumask_copy(later_mask, task_rq(task)->rd->span);
|
||||
cpumask_and(later_mask, later_mask, cpu_active_mask);
|
||||
cpumask_and(later_mask, later_mask, &task->cpus_allowed);
|
||||
best_cpu = cpudl_find(&task_rq(task)->rd->cpudl,
|
||||
task, later_mask);
|
||||
if (best_cpu == -1)
|
||||
@@ -1257,7 +1259,8 @@ static struct rq *find_lock_later_rq(struct task_struct *task, struct rq *rq)
|
||||
if (unlikely(task_rq(task) != rq ||
|
||||
!cpumask_test_cpu(later_rq->cpu,
|
||||
&task->cpus_allowed) ||
|
||||
task_running(rq, task) || !task->on_rq)) {
|
||||
task_running(rq, task) ||
|
||||
!task_on_rq_queued(task))) {
|
||||
double_unlock_balance(rq, later_rq);
|
||||
later_rq = NULL;
|
||||
break;
|
||||
@@ -1296,7 +1299,7 @@ static struct task_struct *pick_next_pushable_dl_task(struct rq *rq)
|
||||
BUG_ON(task_current(rq, p));
|
||||
BUG_ON(p->nr_cpus_allowed <= 1);
|
||||
|
||||
BUG_ON(!p->on_rq);
|
||||
BUG_ON(!task_on_rq_queued(p));
|
||||
BUG_ON(!dl_task(p));
|
||||
|
||||
return p;
|
||||
@@ -1443,7 +1446,7 @@ static int pull_dl_task(struct rq *this_rq)
|
||||
dl_time_before(p->dl.deadline,
|
||||
this_rq->dl.earliest_dl.curr))) {
|
||||
WARN_ON(p == src_rq->curr);
|
||||
WARN_ON(!p->on_rq);
|
||||
WARN_ON(!task_on_rq_queued(p));
|
||||
|
||||
/*
|
||||
* Then we pull iff p has actually an earlier
|
||||
@@ -1569,6 +1572,8 @@ static void switched_from_dl(struct rq *rq, struct task_struct *p)
|
||||
if (hrtimer_active(&p->dl.dl_timer) && !dl_policy(p->policy))
|
||||
hrtimer_try_to_cancel(&p->dl.dl_timer);
|
||||
|
||||
__dl_clear_params(p);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/*
|
||||
* Since this might be the only -deadline task on the rq,
|
||||
@@ -1596,7 +1601,7 @@ static void switched_to_dl(struct rq *rq, struct task_struct *p)
|
||||
if (unlikely(p->dl.dl_throttled))
|
||||
return;
|
||||
|
||||
if (p->on_rq && rq->curr != p) {
|
||||
if (task_on_rq_queued(p) && rq->curr != p) {
|
||||
#ifdef CONFIG_SMP
|
||||
if (rq->dl.overloaded && push_dl_task(rq) && rq != task_rq(p))
|
||||
/* Only reschedule if pushing failed */
|
||||
@@ -1614,7 +1619,7 @@ static void switched_to_dl(struct rq *rq, struct task_struct *p)
|
||||
static void prio_changed_dl(struct rq *rq, struct task_struct *p,
|
||||
int oldprio)
|
||||
{
|
||||
if (p->on_rq || rq->curr == p) {
|
||||
if (task_on_rq_queued(p) || rq->curr == p) {
|
||||
#ifdef CONFIG_SMP
|
||||
/*
|
||||
* This might be too much, but unfortunately
|
||||
|
||||
@@ -150,7 +150,6 @@ print_task(struct seq_file *m, struct rq *rq, struct task_struct *p)
|
||||
static void print_rq(struct seq_file *m, struct rq *rq, int rq_cpu)
|
||||
{
|
||||
struct task_struct *g, *p;
|
||||
unsigned long flags;
|
||||
|
||||
SEQ_printf(m,
|
||||
"\nrunnable tasks:\n"
|
||||
@@ -159,16 +158,14 @@ static void print_rq(struct seq_file *m, struct rq *rq, int rq_cpu)
|
||||
"------------------------------------------------------"
|
||||
"----------------------------------------------------\n");
|
||||
|
||||
read_lock_irqsave(&tasklist_lock, flags);
|
||||
|
||||
do_each_thread(g, p) {
|
||||
rcu_read_lock();
|
||||
for_each_process_thread(g, p) {
|
||||
if (task_cpu(p) != rq_cpu)
|
||||
continue;
|
||||
|
||||
print_task(m, rq, p);
|
||||
} while_each_thread(g, p);
|
||||
|
||||
read_unlock_irqrestore(&tasklist_lock, flags);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)
|
||||
@@ -333,9 +330,7 @@ do { \
|
||||
print_cfs_stats(m, cpu);
|
||||
print_rt_stats(m, cpu);
|
||||
|
||||
rcu_read_lock();
|
||||
print_rq(m, rq, cpu);
|
||||
rcu_read_unlock();
|
||||
spin_unlock_irqrestore(&sched_debug_lock, flags);
|
||||
SEQ_printf(m, "\n");
|
||||
}
|
||||
|
||||
+293
-190
File diff suppressed because it is too large
Load Diff
@@ -147,6 +147,9 @@ use_default:
|
||||
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu))
|
||||
goto use_default;
|
||||
|
||||
/* Take note of the planned idle state. */
|
||||
idle_set_state(this_rq(), &drv->states[next_state]);
|
||||
|
||||
/*
|
||||
* Enter the idle state previously returned by the governor decision.
|
||||
* This function will block until an interrupt occurs and will take
|
||||
@@ -154,6 +157,9 @@ use_default:
|
||||
*/
|
||||
entered_state = cpuidle_enter(drv, dev, next_state);
|
||||
|
||||
/* The cpu is no longer idle or about to enter idle. */
|
||||
idle_set_state(this_rq(), NULL);
|
||||
|
||||
if (broadcast)
|
||||
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
|
||||
|
||||
|
||||
+10
-11
@@ -1448,7 +1448,7 @@ pick_next_task_rt(struct rq *rq, struct task_struct *prev)
|
||||
* means a dl or stop task can slip in, in which case we need
|
||||
* to re-start task selection.
|
||||
*/
|
||||
if (unlikely((rq->stop && rq->stop->on_rq) ||
|
||||
if (unlikely((rq->stop && task_on_rq_queued(rq->stop)) ||
|
||||
rq->dl.dl_nr_running))
|
||||
return RETRY_TASK;
|
||||
}
|
||||
@@ -1468,8 +1468,7 @@ pick_next_task_rt(struct rq *rq, struct task_struct *prev)
|
||||
p = _pick_next_task_rt(rq);
|
||||
|
||||
/* The running task is never eligible for pushing */
|
||||
if (p)
|
||||
dequeue_pushable_task(rq, p);
|
||||
dequeue_pushable_task(rq, p);
|
||||
|
||||
set_post_schedule(rq);
|
||||
|
||||
@@ -1624,7 +1623,7 @@ static struct rq *find_lock_lowest_rq(struct task_struct *task, struct rq *rq)
|
||||
!cpumask_test_cpu(lowest_rq->cpu,
|
||||
tsk_cpus_allowed(task)) ||
|
||||
task_running(rq, task) ||
|
||||
!task->on_rq)) {
|
||||
!task_on_rq_queued(task))) {
|
||||
|
||||
double_unlock_balance(rq, lowest_rq);
|
||||
lowest_rq = NULL;
|
||||
@@ -1658,7 +1657,7 @@ static struct task_struct *pick_next_pushable_task(struct rq *rq)
|
||||
BUG_ON(task_current(rq, p));
|
||||
BUG_ON(p->nr_cpus_allowed <= 1);
|
||||
|
||||
BUG_ON(!p->on_rq);
|
||||
BUG_ON(!task_on_rq_queued(p));
|
||||
BUG_ON(!rt_task(p));
|
||||
|
||||
return p;
|
||||
@@ -1809,7 +1808,7 @@ static int pull_rt_task(struct rq *this_rq)
|
||||
*/
|
||||
if (p && (p->prio < this_rq->rt.highest_prio.curr)) {
|
||||
WARN_ON(p == src_rq->curr);
|
||||
WARN_ON(!p->on_rq);
|
||||
WARN_ON(!task_on_rq_queued(p));
|
||||
|
||||
/*
|
||||
* There's a chance that p is higher in priority
|
||||
@@ -1870,7 +1869,7 @@ static void set_cpus_allowed_rt(struct task_struct *p,
|
||||
|
||||
BUG_ON(!rt_task(p));
|
||||
|
||||
if (!p->on_rq)
|
||||
if (!task_on_rq_queued(p))
|
||||
return;
|
||||
|
||||
weight = cpumask_weight(new_mask);
|
||||
@@ -1936,7 +1935,7 @@ static void switched_from_rt(struct rq *rq, struct task_struct *p)
|
||||
* we may need to handle the pulling of RT tasks
|
||||
* now.
|
||||
*/
|
||||
if (!p->on_rq || rq->rt.rt_nr_running)
|
||||
if (!task_on_rq_queued(p) || rq->rt.rt_nr_running)
|
||||
return;
|
||||
|
||||
if (pull_rt_task(rq))
|
||||
@@ -1970,7 +1969,7 @@ static void switched_to_rt(struct rq *rq, struct task_struct *p)
|
||||
* If that current running task is also an RT task
|
||||
* then see if we can move to another run queue.
|
||||
*/
|
||||
if (p->on_rq && rq->curr != p) {
|
||||
if (task_on_rq_queued(p) && rq->curr != p) {
|
||||
#ifdef CONFIG_SMP
|
||||
if (p->nr_cpus_allowed > 1 && rq->rt.overloaded &&
|
||||
/* Don't resched if we changed runqueues */
|
||||
@@ -1989,7 +1988,7 @@ static void switched_to_rt(struct rq *rq, struct task_struct *p)
|
||||
static void
|
||||
prio_changed_rt(struct rq *rq, struct task_struct *p, int oldprio)
|
||||
{
|
||||
if (!p->on_rq)
|
||||
if (!task_on_rq_queued(p))
|
||||
return;
|
||||
|
||||
if (rq->curr == p) {
|
||||
@@ -2073,7 +2072,7 @@ static void task_tick_rt(struct rq *rq, struct task_struct *p, int queued)
|
||||
for_each_sched_rt_entity(rt_se) {
|
||||
if (rt_se->run_list.prev != rt_se->run_list.next) {
|
||||
requeue_task_rt(rq, p, 0);
|
||||
set_tsk_need_resched(p);
|
||||
resched_curr(rq);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
+48
-32
@@ -14,6 +14,11 @@
|
||||
#include "cpuacct.h"
|
||||
|
||||
struct rq;
|
||||
struct cpuidle_state;
|
||||
|
||||
/* task_struct::on_rq states: */
|
||||
#define TASK_ON_RQ_QUEUED 1
|
||||
#define TASK_ON_RQ_MIGRATING 2
|
||||
|
||||
extern __read_mostly int scheduler_running;
|
||||
|
||||
@@ -126,6 +131,9 @@ struct rt_bandwidth {
|
||||
u64 rt_runtime;
|
||||
struct hrtimer rt_period_timer;
|
||||
};
|
||||
|
||||
void __dl_clear_params(struct task_struct *p);
|
||||
|
||||
/*
|
||||
* To keep the bandwidth of -deadline tasks and groups under control
|
||||
* we need some place where:
|
||||
@@ -184,7 +192,7 @@ struct cfs_bandwidth {
|
||||
raw_spinlock_t lock;
|
||||
ktime_t period;
|
||||
u64 quota, runtime;
|
||||
s64 hierarchal_quota;
|
||||
s64 hierarchical_quota;
|
||||
u64 runtime_expires;
|
||||
|
||||
int idle, timer_active;
|
||||
@@ -636,6 +644,11 @@ struct rq {
|
||||
#ifdef CONFIG_SMP
|
||||
struct llist_head wake_list;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CPU_IDLE
|
||||
/* Must be inspected within a rcu lock section */
|
||||
struct cpuidle_state *idle_state;
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline int cpu_of(struct rq *rq)
|
||||
@@ -647,7 +660,7 @@ static inline int cpu_of(struct rq *rq)
|
||||
#endif
|
||||
}
|
||||
|
||||
DECLARE_PER_CPU(struct rq, runqueues);
|
||||
DECLARE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues);
|
||||
|
||||
#define cpu_rq(cpu) (&per_cpu(runqueues, (cpu)))
|
||||
#define this_rq() (&__get_cpu_var(runqueues))
|
||||
@@ -942,6 +955,15 @@ static inline int task_running(struct rq *rq, struct task_struct *p)
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int task_on_rq_queued(struct task_struct *p)
|
||||
{
|
||||
return p->on_rq == TASK_ON_RQ_QUEUED;
|
||||
}
|
||||
|
||||
static inline int task_on_rq_migrating(struct task_struct *p)
|
||||
{
|
||||
return p->on_rq == TASK_ON_RQ_MIGRATING;
|
||||
}
|
||||
|
||||
#ifndef prepare_arch_switch
|
||||
# define prepare_arch_switch(next) do { } while (0)
|
||||
@@ -953,7 +975,6 @@ static inline int task_running(struct rq *rq, struct task_struct *p)
|
||||
# define finish_arch_post_lock_switch() do { } while (0)
|
||||
#endif
|
||||
|
||||
#ifndef __ARCH_WANT_UNLOCKED_CTXSW
|
||||
static inline void prepare_lock_switch(struct rq *rq, struct task_struct *next)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
@@ -991,35 +1012,6 @@ static inline void finish_lock_switch(struct rq *rq, struct task_struct *prev)
|
||||
raw_spin_unlock_irq(&rq->lock);
|
||||
}
|
||||
|
||||
#else /* __ARCH_WANT_UNLOCKED_CTXSW */
|
||||
static inline void prepare_lock_switch(struct rq *rq, struct task_struct *next)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
/*
|
||||
* We can optimise this out completely for !SMP, because the
|
||||
* SMP rebalancing from interrupt is the only thing that cares
|
||||
* here.
|
||||
*/
|
||||
next->on_cpu = 1;
|
||||
#endif
|
||||
raw_spin_unlock(&rq->lock);
|
||||
}
|
||||
|
||||
static inline void finish_lock_switch(struct rq *rq, struct task_struct *prev)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
/*
|
||||
* After ->on_cpu is cleared, the task can be moved to a different CPU.
|
||||
* We must ensure this doesn't happen until the switch is completely
|
||||
* finished.
|
||||
*/
|
||||
smp_wmb();
|
||||
prev->on_cpu = 0;
|
||||
#endif
|
||||
local_irq_enable();
|
||||
}
|
||||
#endif /* __ARCH_WANT_UNLOCKED_CTXSW */
|
||||
|
||||
/*
|
||||
* wake flags
|
||||
*/
|
||||
@@ -1180,6 +1172,30 @@ static inline void idle_exit_fair(struct rq *rq) { }
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CPU_IDLE
|
||||
static inline void idle_set_state(struct rq *rq,
|
||||
struct cpuidle_state *idle_state)
|
||||
{
|
||||
rq->idle_state = idle_state;
|
||||
}
|
||||
|
||||
static inline struct cpuidle_state *idle_get_state(struct rq *rq)
|
||||
{
|
||||
WARN_ON(!rcu_read_lock_held());
|
||||
return rq->idle_state;
|
||||
}
|
||||
#else
|
||||
static inline void idle_set_state(struct rq *rq,
|
||||
struct cpuidle_state *idle_state)
|
||||
{
|
||||
}
|
||||
|
||||
static inline struct cpuidle_state *idle_get_state(struct rq *rq)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
extern void sysrq_sched_debug_show(void);
|
||||
extern void sched_init_granularity(void);
|
||||
extern void update_max_interval(void);
|
||||
|
||||
@@ -28,7 +28,7 @@ pick_next_task_stop(struct rq *rq, struct task_struct *prev)
|
||||
{
|
||||
struct task_struct *stop = rq->stop;
|
||||
|
||||
if (!stop || !stop->on_rq)
|
||||
if (!stop || !task_on_rq_queued(stop))
|
||||
return NULL;
|
||||
|
||||
put_prev_task(rq, prev);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
#include "smpboot.h"
|
||||
|
||||
@@ -699,3 +700,24 @@ void kick_all_cpus_sync(void)
|
||||
smp_call_function(do_nothing, NULL, 1);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kick_all_cpus_sync);
|
||||
|
||||
/**
|
||||
* wake_up_all_idle_cpus - break all cpus out of idle
|
||||
* wake_up_all_idle_cpus try to break all cpus which is in idle state even
|
||||
* including idle polling cpus, for non-idle cpus, we will do nothing
|
||||
* for them.
|
||||
*/
|
||||
void wake_up_all_idle_cpus(void)
|
||||
{
|
||||
int cpu;
|
||||
|
||||
preempt_disable();
|
||||
for_each_online_cpu(cpu) {
|
||||
if (cpu == smp_processor_id())
|
||||
continue;
|
||||
|
||||
wake_up_if_idle(cpu);
|
||||
}
|
||||
preempt_enable();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(wake_up_all_idle_cpus);
|
||||
|
||||
@@ -869,11 +869,9 @@ void do_sys_times(struct tms *tms)
|
||||
{
|
||||
cputime_t tgutime, tgstime, cutime, cstime;
|
||||
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
thread_group_cputime_adjusted(current, &tgutime, &tgstime);
|
||||
cutime = current->signal->cutime;
|
||||
cstime = current->signal->cstime;
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
tms->tms_utime = cputime_to_clock_t(tgutime);
|
||||
tms->tms_stime = cputime_to_clock_t(tgstime);
|
||||
tms->tms_cutime = cputime_to_clock_t(cutime);
|
||||
|
||||
@@ -1776,7 +1776,6 @@ schedule_hrtimeout_range_clock(ktime_t *expires, unsigned long delta,
|
||||
*/
|
||||
if (!expires) {
|
||||
schedule();
|
||||
__set_current_state(TASK_RUNNING);
|
||||
return -EINTR;
|
||||
}
|
||||
|
||||
|
||||
@@ -272,22 +272,8 @@ static int posix_cpu_clock_get_task(struct task_struct *tsk,
|
||||
if (same_thread_group(tsk, current))
|
||||
err = cpu_clock_sample(which_clock, tsk, &rtn);
|
||||
} else {
|
||||
unsigned long flags;
|
||||
struct sighand_struct *sighand;
|
||||
|
||||
/*
|
||||
* while_each_thread() is not yet entirely RCU safe,
|
||||
* keep locking the group while sampling process
|
||||
* clock for now.
|
||||
*/
|
||||
sighand = lock_task_sighand(tsk, &flags);
|
||||
if (!sighand)
|
||||
return err;
|
||||
|
||||
if (tsk == current || thread_group_leader(tsk))
|
||||
err = cpu_clock_sample_group(which_clock, tsk, &rtn);
|
||||
|
||||
unlock_task_sighand(tsk, &flags);
|
||||
}
|
||||
|
||||
if (!err)
|
||||
|
||||
@@ -205,7 +205,6 @@ static void ring_buffer_consumer(void)
|
||||
break;
|
||||
|
||||
schedule();
|
||||
__set_current_state(TASK_RUNNING);
|
||||
}
|
||||
reader_finish = 0;
|
||||
complete(&read_done);
|
||||
@@ -379,7 +378,6 @@ static int ring_buffer_consumer_thread(void *arg)
|
||||
break;
|
||||
|
||||
schedule();
|
||||
__set_current_state(TASK_RUNNING);
|
||||
}
|
||||
__set_current_state(TASK_RUNNING);
|
||||
|
||||
@@ -407,7 +405,6 @@ static int ring_buffer_producer_thread(void *arg)
|
||||
trace_printk("Sleeping for 10 secs\n");
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
schedule_timeout(HZ * SLEEP_TIME);
|
||||
__set_current_state(TASK_RUNNING);
|
||||
}
|
||||
|
||||
if (kill_test)
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <linux/sysctl.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/magic.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
|
||||
@@ -171,8 +170,7 @@ check_stack(unsigned long ip, unsigned long *stack)
|
||||
i++;
|
||||
}
|
||||
|
||||
if ((current != &init_task &&
|
||||
*(end_of_stack(current)) != STACK_END_MAGIC)) {
|
||||
if (task_stack_end_corrupted(current)) {
|
||||
print_max_stack();
|
||||
BUG();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user