Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'sched-urgent-2020-07-25' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip into master

Pull scheduler fixes from Ingo Molnar:
"Fix a race introduced by the recent loadavg race fix, plus add a debug
check for a hard to debug case of bogus wakeup function flags"

* tag 'sched-urgent-2020-07-25' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
sched: Warn if garbage is passed to default_wake_function()
sched: Fix race against ptrace_freeze_trace()

+15 -10
+15 -10
kernel/sched/core.c
··· 4119 4119 local_irq_disable(); 4120 4120 rcu_note_context_switch(preempt); 4121 4121 4122 - /* See deactivate_task() below. */ 4123 - prev_state = prev->state; 4124 - 4125 4122 /* 4126 4123 * Make sure that signal_pending_state()->signal_pending() below 4127 4124 * can't be reordered with __set_current_state(TASK_INTERRUPTIBLE) ··· 4142 4145 update_rq_clock(rq); 4143 4146 4144 4147 switch_count = &prev->nivcsw; 4148 + 4145 4149 /* 4146 - * We must re-load prev->state in case ttwu_remote() changed it 4147 - * before we acquired rq->lock. 4150 + * We must load prev->state once (task_struct::state is volatile), such 4151 + * that: 4152 + * 4153 + * - we form a control dependency vs deactivate_task() below. 4154 + * - ptrace_{,un}freeze_traced() can change ->state underneath us. 4148 4155 */ 4149 - if (!preempt && prev_state && prev_state == prev->state) { 4156 + prev_state = prev->state; 4157 + if (!preempt && prev_state) { 4150 4158 if (signal_pending_state(prev_state, prev)) { 4151 4159 prev->state = TASK_RUNNING; 4152 4160 } else { ··· 4165 4163 4166 4164 /* 4167 4165 * __schedule() ttwu() 4168 - * prev_state = prev->state; if (READ_ONCE(p->on_rq) && ...) 4169 - * LOCK rq->lock goto out; 4170 - * smp_mb__after_spinlock(); smp_acquire__after_ctrl_dep(); 4171 - * p->on_rq = 0; p->state = TASK_WAKING; 4166 + * prev_state = prev->state; if (p->on_rq && ...) 4167 + * if (prev_state) goto out; 4168 + * p->on_rq = 0; smp_acquire__after_ctrl_dep(); 4169 + * p->state = TASK_WAKING 4170 + * 4171 + * Where __schedule() and ttwu() have matching control dependencies. 4172 4172 * 4173 4173 * After this, schedule() must not care about p->state any more. 4174 4174 */ ··· 4485 4481 int default_wake_function(wait_queue_entry_t *curr, unsigned mode, int wake_flags, 4486 4482 void *key) 4487 4483 { 4484 + WARN_ON_ONCE(IS_ENABLED(CONFIG_SCHED_DEBUG) && wake_flags & ~WF_SYNC); 4488 4485 return try_to_wake_up(curr->private, mode, wake_flags); 4489 4486 } 4490 4487 EXPORT_SYMBOL(default_wake_function);