mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 06:01:57 +00:00
sched: Prepare generic code for delayed dequeue
While most of the delayed dequeue code can be done inside the sched_class itself, there is one location where we do not have an appropriate hook, namely ttwu_runnable(). Add an ENQUEUE_DELAYED call to the on_rq path to deal with waking delayed dequeue tasks. Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Valentin Schneider <vschneid@redhat.com> Tested-by: Valentin Schneider <vschneid@redhat.com> Link: https://lkml.kernel.org/r/20240727105029.200000445@infradead.org
This commit is contained in:
parent
e8901061ca
commit
abc158c82a
@ -544,6 +544,7 @@ struct sched_entity {
|
||||
|
||||
struct list_head group_node;
|
||||
unsigned int on_rq;
|
||||
unsigned int sched_delayed;
|
||||
|
||||
u64 exec_start;
|
||||
u64 sum_exec_runtime;
|
||||
|
@ -2036,6 +2036,8 @@ void activate_task(struct rq *rq, struct task_struct *p, int flags)
|
||||
|
||||
void deactivate_task(struct rq *rq, struct task_struct *p, int flags)
|
||||
{
|
||||
SCHED_WARN_ON(flags & DEQUEUE_SLEEP);
|
||||
|
||||
WRITE_ONCE(p->on_rq, TASK_ON_RQ_MIGRATING);
|
||||
ASSERT_EXCLUSIVE_WRITER(p->on_rq);
|
||||
|
||||
@ -3689,12 +3691,14 @@ static int ttwu_runnable(struct task_struct *p, int wake_flags)
|
||||
|
||||
rq = __task_rq_lock(p, &rf);
|
||||
if (task_on_rq_queued(p)) {
|
||||
update_rq_clock(rq);
|
||||
if (p->se.sched_delayed)
|
||||
enqueue_task(rq, p, ENQUEUE_NOCLOCK | ENQUEUE_DELAYED);
|
||||
if (!task_on_cpu(rq, p)) {
|
||||
/*
|
||||
* When on_rq && !on_cpu the task is preempted, see if
|
||||
* it should preempt the task that is current now.
|
||||
*/
|
||||
update_rq_clock(rq);
|
||||
wakeup_preempt(rq, p, wake_flags);
|
||||
}
|
||||
ttwu_do_wakeup(p);
|
||||
@ -4074,11 +4078,16 @@ int try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags)
|
||||
* case the whole 'p->on_rq && ttwu_runnable()' case below
|
||||
* without taking any locks.
|
||||
*
|
||||
* Specifically, given current runs ttwu() we must be before
|
||||
* schedule()'s block_task(), as such this must not observe
|
||||
* sched_delayed.
|
||||
*
|
||||
* In particular:
|
||||
* - we rely on Program-Order guarantees for all the ordering,
|
||||
* - we're serialized against set_special_state() by virtue of
|
||||
* it disabling IRQs (this allows not taking ->pi_lock).
|
||||
*/
|
||||
SCHED_WARN_ON(p->se.sched_delayed);
|
||||
if (!ttwu_state_match(p, state, &success))
|
||||
goto out;
|
||||
|
||||
@ -4370,6 +4379,9 @@ static void __sched_fork(unsigned long clone_flags, struct task_struct *p)
|
||||
p->se.slice = sysctl_sched_base_slice;
|
||||
INIT_LIST_HEAD(&p->se.group_node);
|
||||
|
||||
/* A delayed task cannot be in clone(). */
|
||||
SCHED_WARN_ON(p->se.sched_delayed);
|
||||
|
||||
#ifdef CONFIG_FAIR_GROUP_SCHED
|
||||
p->se.cfs_rq = NULL;
|
||||
#endif
|
||||
|
@ -2253,6 +2253,7 @@ extern const u32 sched_prio_to_wmult[40];
|
||||
#define DEQUEUE_MOVE 0x04 /* Matches ENQUEUE_MOVE */
|
||||
#define DEQUEUE_NOCLOCK 0x08 /* Matches ENQUEUE_NOCLOCK */
|
||||
#define DEQUEUE_MIGRATING 0x100 /* Matches ENQUEUE_MIGRATING */
|
||||
#define DEQUEUE_DELAYED 0x200 /* Matches ENQUEUE_DELAYED */
|
||||
|
||||
#define ENQUEUE_WAKEUP 0x01
|
||||
#define ENQUEUE_RESTORE 0x02
|
||||
@ -2268,6 +2269,7 @@ extern const u32 sched_prio_to_wmult[40];
|
||||
#endif
|
||||
#define ENQUEUE_INITIAL 0x80
|
||||
#define ENQUEUE_MIGRATING 0x100
|
||||
#define ENQUEUE_DELAYED 0x200
|
||||
|
||||
#define RETRY_TASK ((void *)-1UL)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user