sched/deadline: always enqueue on previous rq when dl_task_timer fires
PATCH 1/1 sched/deadline: always enqueue on previous rq when dl_task_timer fires
dl_task_timer() may fire on a different rq from where a task was removed after throttling. Since the call path is:
dl_task_timer() ->
enqueue_task_dl() ->
enqueue_dl_entity() ->
replenish_dl_entity()and replenish_dl_entity() uses dl_se's rq, we can't use current's rq in dl_task_timer(), but we need to lock the task's previous one.
--- kernel/sched/deadline.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/sched/deadline.c +2 -2
@@ -514,7 +514,7 @@ static enum hrtimer_restart dl_task_timer(struct hrtimer *timer)unsigned long flags;struct rq *rq; - rq =task_rq_lock (current, &flags); + rq =task_rq_lock (p, &flags);/* * We need to take care of several possible races here:
@@ -569,7 +569,7 @@ static enum hrtimer_restart dl_task_timer(struct hrtimer *timer)push_dl_task (rq);#endif unlock: -task_rq_unlock (rq, current, &flags); +task_rq_unlock (rq, p, &flags);return HRTIMER_NORESTART ; }
Signature · 1 line
2.2.2
PATCH 1/1 sched/core: check for available -dl bandwidth in cpuset_cpu_inactive
Hotplug operations are destructive w.r.t. cpusets. In case such an operation is performed on a CPU belonging to an exlusive cpuset, the -dl bandwidth information associated with the corresponding root domain is gone even if the operation fails (in sched_cpu_inactive()).
For this reason we need to move the check we currently have in sched_cpu_inactive() to cpuset_cpu_inactive() to prevent useless cpusets reconfiguration in the CPU_DOWN_FAILED path.
--- kernel/sched/core.c | 56 ++++++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 28 deletions(-)
kernel/sched/core.c +28 -28
@@ -5320,36 +5320,13 @@ static int sched_cpu_active(struct notifier_block *nfb,static int sched_cpu_inactive (struct notifier_block *nfb,unsigned long action,void *hcpu) { -unsigned long flags; -long cpu = (long )hcpu; -struct dl_bw *dl_b; -switch (action & ~CPU_TASKS_FROZEN ) {case CPU_DOWN_PREPARE : -set_cpu_active (cpu, false); - -/* explicitly allow suspend */ -if (!(action &CPU_TASKS_FROZEN )) { -bool overflow; -int cpus; - -rcu_read_lock_sched (); - dl_b =dl_bw_of (cpu); - -raw_spin_lock_irqsave (&dl_b->lock, flags); - cpus =dl_bw_cpus (cpu); - overflow =__dl_overflow (dl_b, cpus,0 ,0 ); -raw_spin_unlock_irqrestore (&dl_b->lock, flags); - -rcu_read_unlock_sched (); - -if (overflow) -return notifier_from_errno (-EBUSY ); - } +set_cpu_active ((long )hcpu, false);return NOTIFY_OK ; +default : +return NOTIFY_DONE ; } - -return NOTIFY_DONE ; }static int __init migration_init (void )
@@ -7000,7 +6977,6 @@ static int cpuset_cpu_active(struct notifier_block *nfb, unsigned long action,*/ case CPU_ONLINE : -case CPU_DOWN_FAILED :cpuset_update_active_cpus (true);break ;default :
@@ -7012,8 +6988,32 @@ static int cpuset_cpu_active(struct notifier_block *nfb, unsigned long action,static int cpuset_cpu_inactive (struct notifier_block *nfb,unsigned long action,void *hcpu) { -switch (action) { +unsigned long flags; +long cpu = (long )hcpu; +struct dl_bw *dl_b; + +switch (action & ~CPU_TASKS_FROZEN ) {case CPU_DOWN_PREPARE : +/* explicitly allow suspend */ +if (!(action &CPU_TASKS_FROZEN )) { +bool overflow; +int cpus; + +rcu_read_lock_sched (); + dl_b =dl_bw_of (cpu); + +raw_spin_lock_irqsave (&dl_b->lock, flags); + cpus =dl_bw_cpus (cpu); + overflow =__dl_overflow (dl_b, cpus,0 ,0 ); +raw_spin_unlock_irqrestore (&dl_b->lock, flags); + +rcu_read_unlock_sched (); + +if (overflow) { +trace_printk ("hotplug failed for cpu %lu" , cpu); +return notifier_from_errno (-EBUSY ); + } + }cpuset_update_active_cpus (false);break ;case CPU_DOWN_PREPARE_FROZEN :
Signature · 1 line
2.2.2
tip-bot for Juri Lelli
merge bot[tip:sched/core] sched/core: Check for available DL bandwidth in cpuset_cpu_inactive()
sched/core: Check for available DL bandwidth in cpuset_cpu_inactive()
Commit-ID: 3c18d447b3b36a8d3c90dc37dfbd363cdb685d0a Gitweb: http://git.kernel.org/tip/3c18d447b3b36a8d3c90dc37dfbd363cdb685d0a Author: Juri Lelli <[email protected]> AuthorDate: Tue, 31 Mar 2015 09:53:37 +0100 Committer: Ingo Molnar <[email protected]> CommitDate: Thu, 2 Apr 2015 17:42:56 +0200
sched/core: Check for available DL bandwidth in cpuset_cpu_inactive()
Hotplug operations are destructive w.r.t. cpusets. In case such an operation is performed on a CPU belonging to an exlusive cpuset, the DL bandwidth information associated with the corresponding root domain is gone even if the operation fails (in sched_cpu_inactive()).
For this reason we need to move the check we currently have in sched_cpu_inactive() to cpuset_cpu_inactive() to prevent useless cpusets reconfiguration in the CPU_DOWN_FAILED path.
--- kernel/sched/core.c | 56 ++++++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 28 deletions(-)
kernel/sched/core.c +28 -28
@@ -5337,36 +5337,13 @@ static int sched_cpu_active(struct notifier_block *nfb,static int sched_cpu_inactive (struct notifier_block *nfb,unsigned long action,void *hcpu) { -unsigned long flags; -long cpu = (long )hcpu; -struct dl_bw *dl_b; -switch (action & ~CPU_TASKS_FROZEN ) {case CPU_DOWN_PREPARE : -set_cpu_active (cpu, false); - -/* explicitly allow suspend */ -if (!(action &CPU_TASKS_FROZEN )) { -bool overflow; -int cpus; - -rcu_read_lock_sched (); - dl_b =dl_bw_of (cpu); - -raw_spin_lock_irqsave (&dl_b->lock, flags); - cpus =dl_bw_cpus (cpu); - overflow =__dl_overflow (dl_b, cpus,0 ,0 ); -raw_spin_unlock_irqrestore (&dl_b->lock, flags); - -rcu_read_unlock_sched (); - -if (overflow) -return notifier_from_errno (-EBUSY ); - } +set_cpu_active ((long )hcpu, false);return NOTIFY_OK ; +default : +return NOTIFY_DONE ; } - -return NOTIFY_DONE ; }static int __init migration_init (void )
@@ -7006,7 +6983,6 @@ static int cpuset_cpu_active(struct notifier_block *nfb, unsigned long action,*/ case CPU_ONLINE : -case CPU_DOWN_FAILED :cpuset_update_active_cpus (true);break ;default :
@@ -7018,8 +6994,32 @@ static int cpuset_cpu_active(struct notifier_block *nfb, unsigned long action,static int cpuset_cpu_inactive (struct notifier_block *nfb,unsigned long action,void *hcpu) { -switch (action) { +unsigned long flags; +long cpu = (long )hcpu; +struct dl_bw *dl_b; + +switch (action & ~CPU_TASKS_FROZEN ) {case CPU_DOWN_PREPARE : +/* explicitly allow suspend */ +if (!(action &CPU_TASKS_FROZEN )) { +bool overflow; +int cpus; + +rcu_read_lock_sched (); + dl_b =dl_bw_of (cpu); + +raw_spin_lock_irqsave (&dl_b->lock, flags); + cpus =dl_bw_cpus (cpu); + overflow =__dl_overflow (dl_b, cpus,0 ,0 ); +raw_spin_unlock_irqrestore (&dl_b->lock, flags); + +rcu_read_unlock_sched (); + +if (overflow) { +trace_printk ("hotplug failed for cpu %lu" , cpu); +return notifier_from_errno (-EBUSY ); + } + }cpuset_update_active_cpus (false);break ;case CPU_DOWN_PREPARE_FROZEN :
Re: [tip:sched/core] sched/core: Check for available DL bandwidth in cpuset_cpu_inactive()
Quoted 97 lines · tip-bot for Juri Lelli
Commit-ID: 3c18d447b3b36a8d3c90dc37dfbd363cdb685d0a Gitweb: http://git.kernel.org/tip/3c18d447b3b36a8d3c90dc37dfbd363cdb685d0a Author: Juri Lelli <[email protected]> AuthorDate: Tue, 31 Mar 2015 09:53:37 +0100 Committer: Ingo Molnar <[email protected]> CommitDate: Thu, 2 Apr 2015 17:42:56 +0200sched/core: Check for available DL bandwidth in
cpuset_cpu_inactive()Hotplug operations are destructive w.r.t. cpusets. In case such an operation is performed on a CPU belonging to an exlusive cpuset, the DL bandwidth information associated with the corresponding root domain is gone even if the operation fails (in
sched_cpu_inactive()).For this reason we need to move the check we currently have in
sched_cpu_inactive()tocpuset_cpu_inactive()to prevent useless cpusets reconfiguration in theCPU_DOWN_FAILEDpath.Signed-off-by Juri Lelli <[email protected]>Signed-off-by Peter Zijlstra (Intel) <[email protected]>Cc Juri Lelli <[email protected]>Signed-off-by Ingo Molnar <[email protected]>--- kernel/sched/core.c | 56 ++++++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 28 deletions(-)kernel/sched/core.c +15
-28@@ -5337,36 +5337,13 @@ static int sched_cpu_active(struct notifier_block *nfb,static int sched_cpu_inactive (struct notifier_block *nfb,unsigned long action,void *hcpu) { -unsigned long flags; -long cpu = (long )hcpu; -struct dl_bw *dl_b; -switch (action & ~CPU_TASKS_FROZEN ) {case CPU_DOWN_PREPARE : -set_cpu_active (cpu, false); - -/* explicitly allow suspend */ -if (!(action &CPU_TASKS_FROZEN )) { -bool overflow; -int cpus; - -rcu_read_lock_sched (); - dl_b =dl_bw_of (cpu); - -raw_spin_lock_irqsave (&dl_b->lock, flags); - cpus =dl_bw_cpus (cpu); - overflow =__dl_overflow (dl_b, cpus,0 ,0 ); -raw_spin_unlock_irqrestore (&dl_b->lock, flags); - -rcu_read_unlock_sched (); - -if (overflow) -return notifier_from_errno (-EBUSY ); - } +set_cpu_active ((long )hcpu, false);return NOTIFY_OK ; +default : +return NOTIFY_DONE ; } - -return NOTIFY_DONE ; }static int __init migration_init (void )@@ -7006,7 +6983,6 @@ static int cpuset_cpu_active(struct notifier_block *nfb, unsigned long action,*/ case CPU_ONLINE : -case CPU_DOWN_FAILED :cpuset_update_active_cpus (true);break ;default :@@ -7018,8 +6994,32 @@ static int cpuset_cpu_active(struct notifier_block *nfb, unsigned long action,static int cpuset_cpu_inactive (struct notifier_block *nfb,unsigned long action,void *hcpu) { -switch (action) { +unsigned long flags; +long cpu = (long )hcpu; +struct dl_bw *dl_b; + +switch (action & ~CPU_TASKS_FROZEN ) {case CPU_DOWN_PREPARE : +/* explicitly allow suspend */ +if (!(action &CPU_TASKS_FROZEN )) { +bool overflow; +int cpus; + +rcu_read_lock_sched (); + dl_b =dl_bw_of (cpu);
kernel/sched/core.c static int cpuset_cpu_active(struct notifier_block *nfb, unsigned long action, · line 7019
Quoted 10 lines
kernel/sched/core.c +10
-0+ +raw_spin_lock_irqsave (&dl_b->lock, flags); + cpus =dl_bw_cpus (cpu); + overflow =__dl_overflow (dl_b, cpus,0 ,0 ); +raw_spin_unlock_irqrestore (&dl_b->lock, flags); + +rcu_read_unlock_sched (); + +if (overflow) { +trace_printk ("hotplug failed for cpu %lu" , cpu);
Look ma,
someone forgot debugging code:
...
[ 0.000000] RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=2. [ 0.000000] RCU: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=2 [ 0.000000] [ 0.000000] ********************************************************** [ 0.000000] ** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE ** [ 0.000000] ** ** [ 0.000000] ** trace_printk() being used. Allocating extra memory. ** [ 0.000000] ** ** [ 0.000000] ** This means that this is a DEBUG kernel and it is ** [ 0.000000] ** unsafe for production use. ** [ 0.000000] ** ** [ 0.000000] ** If you see this message and you are not debugging ** [ 0.000000] ** the kernel, report this immediately to your vendor! ** [ 0.000000] ** ** [ 0.000000] ** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE ** [ 0.000000] **********************************************************
Fix coming up.
Signature · 5 lines
Regards/Gruss,
Boris.
ECO tip #101: Trim your mails when you reply.
--Peter Zijlstra
maintainerRe: [tip:sched/core] sched/core: Check for available DL bandwidth in cpuset_cpu_inactive()
Quoted 7 lines · Borislav Petkov
kernel/sched/core.c static int cpuset_cpu_active(struct notifier_block *nfb, unsigned long action, · line 7019
Quoted 2 lines
kernel/sched/core.c +2
-0+if (overflow) { +trace_printk ("hotplug failed for cpu %lu" , cpu);Look ma,
someone forgot debugging code:
*groan*, I actually saw that when Juri send the patch and though: I should not forget to take that out... :/
Re: [tip:sched/core] sched/core: Check for available DL bandwidth in cpuset_cpu_inactive()
Quoted 2 lines · Peter Zijlstra
*groan*, I actually saw that when Juri send the patch and though: I should not forget to take that out... :/
Look at the bright side - we tested rostedt's banner. It works. :-)
Signature · 5 lines
Regards/Gruss,
Boris.
ECO tip #101: Trim your mails when you reply.
--tip-bot for Juri Lelli
merge bot[tip:sched/core] sched/deadline: Always enqueue on previous rq when dl_task_timer() fires
In reply to Juri Lellisched/deadline: Always enqueue on previous rq when dl_task_timer() fires
Commit-ID: 4cd57f97135840f637431c92380c8da3edbe44ed Gitweb: http://git.kernel.org/tip/4cd57f97135840f637431c92380c8da3edbe44ed Author: Juri Lelli <[email protected]> AuthorDate: Tue, 31 Mar 2015 09:53:36 +0100 Committer: Ingo Molnar <[email protected]> CommitDate: Thu, 2 Apr 2015 17:42:56 +0200
sched/deadline: Always enqueue on previous rq when dl_task_timer() fires
dl_task_timer() may fire on a different rq from where a task was removed after throttling. Since the call path is:
dl_task_timer() ->
enqueue_task_dl() ->
enqueue_dl_entity() ->
replenish_dl_entity()and replenish_dl_entity() uses dl_se's rq, we can't use current's rq in dl_task_timer(), but we need to lock the task's previous one.
--- kernel/sched/deadline.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/sched/deadline.c +2 -2
@@ -514,7 +514,7 @@ static enum hrtimer_restart dl_task_timer(struct hrtimer *timer)unsigned long flags;struct rq *rq; - rq =task_rq_lock (current, &flags); + rq =task_rq_lock (p, &flags);/* * We need to take care of several possible races here:
@@ -569,7 +569,7 @@ static enum hrtimer_restart dl_task_timer(struct hrtimer *timer)push_dl_task (rq);#endif unlock: -task_rq_unlock (rq, current, &flags); +task_rq_unlock (rq, p, &flags);return HRTIMER_NORESTART ; }