Re: [RFC][PATCH 4/7] sched: Replace sd_busy/nr_busy_cpus with sched_domain_shared
From: Matt Fleming
Date: Wed May 11 2016 - 07:56:04 EST
On Mon, 09 May, at 12:48:11PM, Peter Zijlstra wrote:
> Move the nr_busy_cpus thing from its hacky sd->parent->groups->sgc
> location into the much more natural sched_domain_shared location.
>
> Signed-off-by: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx>
> ---
> include/linux/sched.h | 1 +
> kernel/sched/core.c | 10 +++++-----
> kernel/sched/fair.c | 22 ++++++++++++----------
> kernel/sched/sched.h | 6 +-----
> kernel/time/tick-sched.c | 10 +++++-----
> 5 files changed, 24 insertions(+), 25 deletions(-)
>
> --- a/include/linux/sched.h
> +++ b/include/linux/sched.h
> @@ -1059,6 +1059,7 @@ struct sched_group;
>
> struct sched_domain_shared {
> atomic_t ref;
> + atomic_t nr_busy_cpus;
> };
>
> struct sched_domain {
[...]
> --- a/kernel/sched/fair.c
> +++ b/kernel/sched/fair.c
> @@ -7842,13 +7842,13 @@ static inline void set_cpu_sd_state_busy
> int cpu = smp_processor_id();
>
> rcu_read_lock();
> - sd = rcu_dereference(per_cpu(sd_busy, cpu));
> + sd = rcu_dereference(per_cpu(sd_llc, cpu));
>
> if (!sd || !sd->nohz_idle)
> goto unlock;
> sd->nohz_idle = 0;
>
> - atomic_inc(&sd->groups->sgc->nr_busy_cpus);
> + atomic_inc(&sd->shared->nr_busy_cpus);
> unlock:
> rcu_read_unlock();
> }
This breaks my POWER7 box which presumably doesn't have SD_SHARE_PKG_RESOURCES,
NIP [c00000000012de68] .set_cpu_sd_state_idle+0x58/0x80
LR [c00000000017ded4] .tick_nohz_idle_enter+0x24/0x90
Call Trace:
[c0000007774b7cf0] [c0000007774b4080] 0xc0000007774b4080 (unreliable)
[c0000007774b7d60] [c00000000017ded4] .tick_nohz_idle_enter+0x24/0x90
[c0000007774b7dd0] [c000000000137200] .cpu_startup_entry+0xe0/0x440
[c0000007774b7ee0] [c00000000004739c] .start_secondary+0x35c/0x3a0
[c0000007774b7f90] [c000000000008bfc] start_secondary_prolog+0x10/0x14
The following fixes it,
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 978b3ef2d87e..d27153adee4d 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -7920,7 +7920,8 @@ static inline void set_cpu_sd_state_busy(void)
goto unlock;
sd->nohz_idle = 0;
- atomic_inc(&sd->shared->nr_busy_cpus);
+ if (sd->shared)
+ atomic_inc(&sd->shared->nr_busy_cpus);
unlock:
rcu_read_unlock();
}
@@ -7937,7 +7938,8 @@ void set_cpu_sd_state_idle(void)
goto unlock;
sd->nohz_idle = 1;
- atomic_dec(&sd->shared->nr_busy_cpus);
+ if (sd->shared)
+ atomic_dec(&sd->shared->nr_busy_cpus);
unlock:
rcu_read_unlock();
}