sched_rt.c: resch needed in rt_rq_enqueue() for the root rt_rq
PATCH 1/1 sched_rt.c: resch needed in rt_rq_enqueue() for the root rt_rq
Hi all,
While working on the new version of the code for SCHED_SPORADIC I noticed something strange in the present throttling mechanism. More specifically in the throttling timer handler in sched_rt.c (do_sched_rt_period_timer()) and in rt_rq_enqueue().
The problem is that, when unthrottling a runqueue, rt_rq_enqueue() only asks for rescheduling if the runqueue has a sched_entity associated to it (i.e., rt_rq->rt_se != NULL).
Now, if the runqueue is the root rq (which has a rt_se = NULL) rescheduling does not take place, and it is delayed to some undefined instant in the future.
This imply some random bandwidth usage by the RT tasks under throttling. For instance, setting rt_runtime_us/rt_period_us = 950ms/1000ms an RT task will get less than 95%. In our tests we got something varying between 70% to 95%.
Using smaller time values, e.g., 95ms/100ms, things are even worse, and I can see values also going down to 20-25%!!
The tests we performed are simply running 'yes' as a SCHED_FIFO task, and checking the CPU usage with top, but we can investigate thoroughly if you think it is needed.
Things go much better, for us, with the attached patch... Don't know if it is the best approach, but it solved the issue for us.
Best Regards,
Dario Faggioli
---
---
kernel/sched_rt.c +4 -4
@@ -102,12 +102,12 @@ static void dequeue_rt_entity(struct sched_rt_entity *rt_se);static void sched_rt_rq_enqueue (struct rt_rq *rt_rq) { +struct task_struct *curr =rq_of_rt_rq (rt_rq)->curr;struct sched_rt_entity *rt_se = rt_rq->rt_se; -if (rt_se && !on_rt_rq (rt_se) && rt_rq->rt_nr_running) { -struct task_struct *curr =rq_of_rt_rq (rt_rq)->curr; - -enqueue_rt_entity (rt_se); +if (rt_rq->rt_nr_running) { +if (rt_se && !on_rt_rq (rt_se)) +enqueue_rt_entity (rt_se);if (rt_rq->highest_prio < curr->prio)resched_task (curr); }
Signature · 12 lines
<<This happens because I choose it to happen!>> (Raistlin Majere, DragonLance Chronicles -Dragons of Spring Drawning-) ---------------------------------------------------------------------- Dario Faggioli GNU/Linux Registered User: #340657 Web: http://www.linux.it/~raistlin Blog: http://blog.linux.it/raistlin SIP Account: [email protected] or [email protected] Jabber Account: [email protected]/WengoPhone GnuPG Key ID: 4DC83AC4 GnuPG Key Fingerprint: 2A78 AD5D B9CF A082 0836 08AD 9385 DA04 4DC8 3AC4
Quoted 21 lines · Dario Faggioli
Hi all,
While working on the new version of the code for
SCHED_SPORADICI noticed something strange in the present throttling mechanism. More specifically in the throttling timer handler insched_rt.c(do_sched_rt_period_timer()) and inrt_rq_enqueue().The problem is that, when unthrottling a runqueue,
rt_rq_enqueue()only asks for rescheduling if the runqueue has asched_entityassociated to it (i.e.,rt_rq->rt_se!= NULL).
Now, if the runqueue is the root rq (which has art_se= NULL) rescheduling does not take place, and it is delayed to some undefined instant in the future.This imply some random bandwidth usage by the RT tasks under throttling. For instance, setting rt_runtime_us/rt_period_us = 950ms/1000ms an RT task will get less than 95%. In our tests we got something varying between 70% to 95%.
Using smaller time values, e.g., 95ms/100ms, things are even worse, and I can see values also going down to 20-25%!!
Quoted 6 lines
The tests we performed are simply running 'yes' as a
SCHED_FIFOtask, and checking the CPU usage with top, but we can investigate thoroughly if you think it is needed.Things go much better, for us, with the attached patch... Don't know if it is the best approach, but it solved the issue for us.
Its consistent with John Blackwood's change to the !group case (f3ade837), and looks good.
Ingo, please pickup (might be 27.1 material as well).
Thanks Dario!
Quoted 27 lines
---
Signed-off-by Dario Faggioli <[email protected]>Signed-off-by Michael Trimarchi <[email protected]>---
kernel/sched_rt.c +4
-4@@ -102,12 +102,12 @@ static void dequeue_rt_entity(struct sched_rt_entity *rt_se);static void sched_rt_rq_enqueue (struct rt_rq *rt_rq) { +struct task_struct *curr =rq_of_rt_rq (rt_rq)->curr;struct sched_rt_entity *rt_se = rt_rq->rt_se; -if (rt_se && !on_rt_rq (rt_se) && rt_rq->rt_nr_running) { -struct task_struct *curr =rq_of_rt_rq (rt_rq)->curr; - -enqueue_rt_entity (rt_se); +if (rt_rq->rt_nr_running) { +if (rt_se && !on_rt_rq (rt_se)) +enqueue_rt_entity (rt_se);if (rt_rq->highest_prio < curr->prio)resched_task (curr); }
Ingo Molnar
AppliedQuoted 29 lines · Peter Zijlstra
Quoted 21 lines · Dario Faggioli
Hi all,
While working on the new version of the code for
SCHED_SPORADICI noticed something strange in the present throttling mechanism. More specifically in the throttling timer handler insched_rt.c(do_sched_rt_period_timer()) and inrt_rq_enqueue().The problem is that, when unthrottling a runqueue,
rt_rq_enqueue()only asks for rescheduling if the runqueue has asched_entityassociated to it (i.e.,rt_rq->rt_se!= NULL).
Now, if the runqueue is the root rq (which has art_se= NULL) rescheduling does not take place, and it is delayed to some undefined instant in the future.This imply some random bandwidth usage by the RT tasks under throttling. For instance, setting rt_runtime_us/rt_period_us = 950ms/1000ms an RT task will get less than 95%. In our tests we got something varying between 70% to 95%.
Using smaller time values, e.g., 95ms/100ms, things are even worse, and I can see values also going down to 20-25%!!Quoted 6 lines
The tests we performed are simply running 'yes' as a
SCHED_FIFOtask, and checking the CPU usage with top, but we can investigate thoroughly if you think it is needed.Things go much better, for us, with the attached patch... Don't know if it is the best approach, but it solved the issue for us.
Quoted 6 lines
Its consistent with John Blackwood's change to the !group case (
f3ade837), and looks good.Acked-by Peter Zijlstra <[email protected]>Ingo, please pickup (might be 27.1 material as well).
applied to tip/sched/devel, thanks! I've also added a Cc:
[email protected] tag to the commit.
Ingo