-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Demotion reloaded #2
Changes from 1 commit
3269633
7260848
7618896
c6ab52f
04e4ecc
f4b82ff
7d9cc86
dabbb3e
332859b
e2bd3c6
67397e2
c8fb86d
20ef682
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1094,7 +1094,7 @@ static inline void check_class_changed(struct rq *rq, struct task_struct *p, | |
const struct sched_class *prev_class, | ||
int oldprio) | ||
{ | ||
if (prev_class != p->sched_class) { | ||
if (prev_class != p->sched_class || rt_throttled(p)) { | ||
if (prev_class->switched_from) | ||
prev_class->switched_from(rq, p); | ||
|
||
|
@@ -3632,6 +3632,94 @@ int default_wake_function(wait_queue_t *curr, unsigned mode, int wake_flags, | |
} | ||
EXPORT_SYMBOL(default_wake_function); | ||
|
||
void __setprio_other(struct rq *rq, struct task_struct *p) | ||
{ | ||
int oldprio, queued, running; | ||
const struct sched_class *prev_class; | ||
|
||
lockdep_assert_held(&rq->lock); | ||
|
||
oldprio = p->prio; | ||
prev_class = p->sched_class; | ||
queued = task_on_rq_queued(p); | ||
running = task_current(rq, p); | ||
BUG_ON(!rt_throttled(p)); | ||
|
||
if (queued) | ||
dequeue_task(rq, p, DEQUEUE_SAVE | DEQUEUE_MOVE); | ||
/* | ||
if (running) | ||
put_prev_task(rq, p); | ||
*/ | ||
p->sched_class = &fair_sched_class; | ||
p->prio = DEFAULT_PRIO; | ||
|
||
/* | ||
* As in attach_task_cfs_rq, since the real-depth could have been | ||
* changed (only FAIR class maintain depth value), reset depth | ||
* properly. | ||
*/ | ||
p->se.depth = p->se.parent ? p->se.parent->depth + 1 : 0; | ||
|
||
if (running) | ||
p->sched_class->set_curr_task(rq); | ||
if (queued) | ||
enqueue_task(rq, p, ENQUEUE_RESTORE | ENQUEUE_MOVE); | ||
|
||
check_class_changed(rq, p, prev_class, oldprio); | ||
} | ||
|
||
void __setprio_fifo(struct rq *rq, struct task_struct *p) | ||
{ | ||
int oldprio, queued, running, cpu; | ||
const struct sched_class *prev_class; | ||
unsigned int count = 0; | ||
|
||
lockdep_assert_held(&rq->lock); | ||
|
||
/* | ||
* p might have migrated while hanging out in OTHER. We will need its | ||
* current rq lock for dequeue_task/put_prev_task. | ||
*/ | ||
again: | ||
cpu = task_cpu(p); | ||
if (cpu != cpu_of(rq)) { | ||
double_lock_balance(rq, cpu_rq(cpu)); | ||
if (cpu != task_cpu(p)) { | ||
double_unlock_balance(rq, cpu_rq(cpu)); | ||
count++; | ||
BUG_ON(count > 10); | ||
goto again; | ||
} | ||
} | ||
|
||
BUG_ON(p->sched_class == &rt_sched_class); | ||
|
||
oldprio = p->prio; | ||
prev_class = p->sched_class; | ||
queued = task_on_rq_queued(p); | ||
running = task_current(cpu_rq(cpu), p); | ||
BUG_ON(rt_throttled(p)); | ||
|
||
if (queued) | ||
dequeue_task(cpu_rq(cpu), p, DEQUEUE_SAVE | DEQUEUE_MOVE); | ||
if (running) | ||
put_prev_task(cpu_rq(cpu), p); | ||
|
||
p->sched_class = &rt_sched_class; | ||
p->prio = (MAX_RT_PRIO - 1) - p->rt_priority; | ||
|
||
if (running) | ||
p->sched_class->set_curr_task(cpu_rq(cpu)); | ||
if (queued) | ||
enqueue_task(cpu_rq(cpu), p, ENQUEUE_REPLENISH | ENQUEUE_MOVE | ENQUEUE_RESTORE); | ||
|
||
check_class_changed(cpu_rq(cpu), p, prev_class, oldprio); | ||
out: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This label doesn't seem to be used. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Uhmm... Right. I suspect is a leftover from some previous change; I am going to check There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, I checked:
near the beginning of __setprio_fifo().
but I forgot to remove the "out:" label. |
||
if (cpu != cpu_of(rq)) | ||
double_unlock_balance(rq, cpu_rq(cpu)); | ||
} | ||
|
||
#ifdef CONFIG_RT_MUTEXES | ||
|
||
/* | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this commented out?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I replied to the email, but I do not see replies here... So, here it is again:
this function is invoked by cfs_throttle_rt_tasks(), that is invoked by update_curr_rt().
Invoking put_prev_task() would result in another invocation of update_curr_rt(), potentially causing some issues.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. Also, considering that put_prev_task_rt() would only enqueue the task in the pushable list (and we don't want that). It seems save to remove it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that I remember: I removed it due to some crash I was seeing, that I decided to be caused by infinite recursion (update_curr_rt -> cfs_throttle_rt_tasks -> __setprio_fifo -> put_prev_task_rt -> update_curr_rt -> cfs_throttle_rt_tasks -> ...)