Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1277716 > unrolled thread
| Started by | Waiman Long <Waiman.Long@hpe.com> |
|---|---|
| First post | 2015-11-25 20:20 +0100 |
| Last post | 2015-11-30 23:40 +0100 |
| Articles | 13 — 4 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
[RFC PATCH 3/3] sched/fair: Use different cachelines for readers and writers of load_avg Waiman Long <Waiman.Long@hpe.com> - 2015-11-25 20:20 +0100
Re: [RFC PATCH 3/3] sched/fair: Use different cachelines for readers and writers of load_avg Peter Zijlstra <peterz@infradead.org> - 2015-11-30 11:30 +0100
Re: [RFC PATCH 3/3] sched/fair: Use different cachelines for readers and writers of load_avg Waiman Long <waiman.long@hpe.com> - 2015-11-30 20:20 +0100
Re: [RFC PATCH 3/3] sched/fair: Use different cachelines for readers and writers of load_avg Peter Zijlstra <peterz@infradead.org> - 2015-11-30 23:20 +0100
Re: [RFC PATCH 3/3] sched/fair: Use different cachelines for readers and writers of load_avg Waiman Long <waiman.long@hpe.com> - 2015-12-01 05:00 +0100
Re: [RFC PATCH 3/3] sched/fair: Use different cachelines for readers and writers of load_avg Peter Zijlstra <peterz@infradead.org> - 2015-12-01 09:50 +0100
Re: [RFC PATCH 3/3] sched/fair: Use different cachelines for readers and writers of load_avg Mike Galbraith <umgwanakikbuti@gmail.com> - 2015-12-01 11:50 +0100
Re: [RFC PATCH 3/3] sched/fair: Use different cachelines for readers and writers of load_avg Waiman Long <waiman.long@hpe.com> - 2015-12-02 19:50 +0100
Re: [RFC PATCH 3/3] sched/fair: Use different cachelines for readers and writers of load_avg Peter Zijlstra <peterz@infradead.org> - 2015-11-30 23:30 +0100
Re: [RFC PATCH 3/3] sched/fair: Use different cachelines for readers and writers of load_avg Waiman Long <waiman.long@hpe.com> - 2015-12-01 05:10 +0100
Re: [RFC PATCH 3/3] sched/fair: Use different cachelines for readers and writers of load_avg Peter Zijlstra <peterz@infradead.org> - 2015-12-01 09:50 +0100
Re: [RFC PATCH 3/3] sched/fair: Use different cachelines for readers and writers of load_avg Waiman Long <waiman.long@hpe.com> - 2015-12-02 19:50 +0100
Re: [RFC PATCH 3/3] sched/fair: Use different cachelines for readers and writers of load_avg Peter Zijlstra <peterz@infradead.org> - 2015-11-30 23:40 +0100
| From | Waiman Long <Waiman.Long@hpe.com> |
|---|---|
| Date | 2015-11-25 20:20 +0100 |
| Subject | [RFC PATCH 3/3] sched/fair: Use different cachelines for readers and writers of load_avg |
| Message-ID | <qyNLI-1Zv-19@gated-at.bofh.it> |
The load_avg statistical counter is only changed if the load on a CPU
deviates significantly from the previous tick. So there are usually
more readers than writers of load_avg. Still, on a large system,
the cacheline contention can cause significant slowdown and impact
performance.
This patch attempts to separate those load_avg readers
(update_cfs_shares) and writers (task_tick_fair) to use different
cachelines instead. Writers of load_avg will now accumulates the
load delta into load_avg_delta which sits in a different cacheline.
If load_avg_delta is sufficiently large (> load_avg/64), it will then
be added back to load_avg.
Running a java benchmark on a 16-socket IvyBridge-EX system (240 cores,
480 threads), the perf profile before the patch was:
9.44% 0.00% java [kernel.vmlinux] [k] smp_apic_timer_interrupt
8.74% 0.01% java [kernel.vmlinux] [k] hrtimer_interrupt
7.83% 0.03% java [kernel.vmlinux] [k] tick_sched_timer
7.74% 0.00% java [kernel.vmlinux] [k] update_process_times
7.27% 0.03% java [kernel.vmlinux] [k] scheduler_tick
5.94% 1.74% java [kernel.vmlinux] [k] task_tick_fair
4.15% 3.92% java [kernel.vmlinux] [k] update_cfs_shares
After the patch, it became:
2.94% 0.00% java [kernel.vmlinux] [k] smp_apic_timer_interrupt
2.52% 0.01% java [kernel.vmlinux] [k] hrtimer_interrupt
2.25% 0.02% java [kernel.vmlinux] [k] tick_sched_timer
2.21% 0.00% java [kernel.vmlinux] [k] update_process_times
1.70% 0.03% java [kernel.vmlinux] [k] scheduler_tick
0.96% 0.34% java [kernel.vmlinux] [k] task_tick_fair
0.61% 0.48% java [kernel.vmlinux] [k] update_cfs_shares
The benchmark results before and after the patch were as follows:
Before patch - Max-jOPs: 916011 Critical-jOps: 142366
AFter patch - Max-jOPs: 939130 Critical-jOps: 211937
There was significant improvement in Critical-jOps which was latency
sensitive.
This patch does introduce additional delay in getting the real load
average reflected in load_avg. It may also incur additional overhead
if the number of CPUs in a task group is small. As a result, this
change is only activated when running on a 4-socket or larger systems
which can get the most benefit from it.
Signed-off-by: Waiman Long <Waiman.Long@hpe.com>
---
kernel/sched/core.c | 9 +++++++++
kernel/sched/fair.c | 30 ++++++++++++++++++++++++++++--
kernel/sched/sched.h | 8 ++++++++
3 files changed, 45 insertions(+), 2 deletions(-)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 4d568ac..f3075da 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -7356,6 +7356,12 @@ void __init sched_init(void)
root_task_group.cfs_rq = (struct cfs_rq **)ptr;
ptr += nr_cpu_ids * sizeof(void **);
+#ifdef CONFIG_SMP
+ /*
+ * Use load_avg_delta if not 2P or less
+ */
+ root_task_group.use_la_delta = (num_possible_nodes() > 2);
+#endif /* CONFIG_SMP */
#endif /* CONFIG_FAIR_GROUP_SCHED */
#ifdef CONFIG_RT_GROUP_SCHED
root_task_group.rt_se = (struct sched_rt_entity **)ptr;
@@ -7691,6 +7697,9 @@ struct task_group *sched_create_group(struct task_group *parent)
if (!alloc_rt_sched_group(tg, parent))
goto err;
+#if defined(CONFIG_FAIR_GROUP_SCHED) && defined(CONFIG_SMP)
+ tg->use_la_delta = root_task_group.use_la_delta;
+#endif
return tg;
err:
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 8f1eccc..44732cc 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -2663,15 +2663,41 @@ __update_load_avg(u64 now, int cpu, struct sched_avg *sa,
#ifdef CONFIG_FAIR_GROUP_SCHED
/*
- * Updating tg's load_avg is necessary before update_cfs_share (which is done)
+ * Updating tg's load_avg is necessary before update_cfs_shares (which is done)
* and effective_load (which is not done because it is too costly).
+ *
+ * The tg's use_la_delta flag, if set, will cause the load_avg delta to be
+ * accumulated into the load_avg_delta variable instead to reduce cacheline
+ * contention on load_avg at the expense of more delay in reflecting the real
+ * load_avg. The tg's load_avg and load_avg_delta variables are in separate
+ * cachelines. With that flag set, load_avg will be read mostly whereas
+ * load_avg_delta will be write mostly.
*/
static inline void update_tg_load_avg(struct cfs_rq *cfs_rq, int force)
{
long delta = cfs_rq->avg.load_avg - cfs_rq->tg_load_avg_contrib;
if (force || abs(delta) > cfs_rq->tg_load_avg_contrib / 64) {
- atomic_long_add(delta, &cfs_rq->tg->load_avg);
+ struct task_group *tg = cfs_rq->tg;
+ long load_avg, tot_delta;
+
+ if (!tg->use_la_delta) {
+ /*
+ * If the use_la_delta isn't set, just add the
+ * delta directly into load_avg.
+ */
+ atomic_long_add(delta, &tg->load_avg);
+ goto set_contrib;
+ }
+
+ tot_delta = atomic_long_add_return(delta, &tg->load_avg_delta);
+ load_avg = atomic_long_read(&tg->load_avg);
+ if (abs(tot_delta) > load_avg / 64) {
+ tot_delta = atomic_long_xchg(&tg->load_avg_delta, 0);
+ if (tot_delta)
+ atomic_long_add(tot_delta, &tg->load_avg);
+ }
+set_contrib:
cfs_rq->tg_load_avg_contrib = cfs_rq->avg.load_avg;
}
}
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index e679895..aef4e4e 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -252,8 +252,16 @@ struct task_group {
* load_avg can be heavily contended at clock tick time, so put
* it in its own cacheline separated from the fields above which
* will also be accessed at each tick.
+ *
+ * The use_la_delta flag, if set, will enable the use of load_avg_delta
+ * to accumulate the delta and only change load_avg when the delta
+ * is big enough. This reduces the cacheline contention on load_avg.
+ * This flag will be set at allocation time depending on the system
+ * configuration.
*/
+ int use_la_delta;
atomic_long_t load_avg ____cacheline_aligned;
+ atomic_long_t load_avg_delta ____cacheline_aligned;
#endif
#endif
--
1.7.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [next] | [standalone]
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Date | 2015-11-30 11:30 +0100 |
| Subject | Re: [RFC PATCH 3/3] sched/fair: Use different cachelines for readers and writers of load_avg |
| Message-ID | <qAtSx-2jv-9@gated-at.bofh.it> |
| In reply to | #1277716 |
Please always Cc the people who wrote the code.
+CC pjt, ben, morten, yuyang
On Wed, Nov 25, 2015 at 02:09:40PM -0500, Waiman Long wrote:
> The load_avg statistical counter is only changed if the load on a CPU
> deviates significantly from the previous tick. So there are usually
> more readers than writers of load_avg. Still, on a large system,
> the cacheline contention can cause significant slowdown and impact
> performance.
>
> This patch attempts to separate those load_avg readers
> (update_cfs_shares) and writers (task_tick_fair) to use different
> cachelines instead. Writers of load_avg will now accumulates the
> load delta into load_avg_delta which sits in a different cacheline.
> If load_avg_delta is sufficiently large (> load_avg/64), it will then
> be added back to load_avg.
>
> Running a java benchmark on a 16-socket IvyBridge-EX system (240 cores,
> 480 threads), the perf profile before the patch was:
>
> 9.44% 0.00% java [kernel.vmlinux] [k] smp_apic_timer_interrupt
> 8.74% 0.01% java [kernel.vmlinux] [k] hrtimer_interrupt
> 7.83% 0.03% java [kernel.vmlinux] [k] tick_sched_timer
> 7.74% 0.00% java [kernel.vmlinux] [k] update_process_times
> 7.27% 0.03% java [kernel.vmlinux] [k] scheduler_tick
> 5.94% 1.74% java [kernel.vmlinux] [k] task_tick_fair
> 4.15% 3.92% java [kernel.vmlinux] [k] update_cfs_shares
>
> After the patch, it became:
>
> 2.94% 0.00% java [kernel.vmlinux] [k] smp_apic_timer_interrupt
> 2.52% 0.01% java [kernel.vmlinux] [k] hrtimer_interrupt
> 2.25% 0.02% java [kernel.vmlinux] [k] tick_sched_timer
> 2.21% 0.00% java [kernel.vmlinux] [k] update_process_times
> 1.70% 0.03% java [kernel.vmlinux] [k] scheduler_tick
> 0.96% 0.34% java [kernel.vmlinux] [k] task_tick_fair
> 0.61% 0.48% java [kernel.vmlinux] [k] update_cfs_shares
This begs the question tough; why are you running a global load in a
cgroup; and do we really need to update this for the root cgroup? It
seems to me we don't need calc_tg_weight() for the root cgroup, it
doesn't need to normalize its weight numbers.
That is; isn't this simply a problem we should avoid?
> The benchmark results before and after the patch were as follows:
>
> Before patch - Max-jOPs: 916011 Critical-jOps: 142366
> AFter patch - Max-jOPs: 939130 Critical-jOps: 211937
>
> There was significant improvement in Critical-jOps which was latency
> sensitive.
>
> This patch does introduce additional delay in getting the real load
> average reflected in load_avg. It may also incur additional overhead
> if the number of CPUs in a task group is small. As a result, this
> change is only activated when running on a 4-socket or larger systems
> which can get the most benefit from it.
So I'm not particularly charmed by this; it rather makes a mess of
things. Also this really wants a run of the cgroup fairness test thingy
pjt/ben have somewhere.
> Signed-off-by: Waiman Long <Waiman.Long@hpe.com>
> ---
> kernel/sched/core.c | 9 +++++++++
> kernel/sched/fair.c | 30 ++++++++++++++++++++++++++++--
> kernel/sched/sched.h | 8 ++++++++
> 3 files changed, 45 insertions(+), 2 deletions(-)
>
> diff --git a/kernel/sched/core.c b/kernel/sched/core.c
> index 4d568ac..f3075da 100644
> --- a/kernel/sched/core.c
> +++ b/kernel/sched/core.c
> @@ -7356,6 +7356,12 @@ void __init sched_init(void)
> root_task_group.cfs_rq = (struct cfs_rq **)ptr;
> ptr += nr_cpu_ids * sizeof(void **);
>
> +#ifdef CONFIG_SMP
> + /*
> + * Use load_avg_delta if not 2P or less
> + */
> + root_task_group.use_la_delta = (num_possible_nodes() > 2);
> +#endif /* CONFIG_SMP */
> #endif /* CONFIG_FAIR_GROUP_SCHED */
> #ifdef CONFIG_RT_GROUP_SCHED
> root_task_group.rt_se = (struct sched_rt_entity **)ptr;
> @@ -7691,6 +7697,9 @@ struct task_group *sched_create_group(struct task_group *parent)
> if (!alloc_rt_sched_group(tg, parent))
> goto err;
>
> +#if defined(CONFIG_FAIR_GROUP_SCHED) && defined(CONFIG_SMP)
> + tg->use_la_delta = root_task_group.use_la_delta;
> +#endif
> return tg;
>
> err:
> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> index 8f1eccc..44732cc 100644
> --- a/kernel/sched/fair.c
> +++ b/kernel/sched/fair.c
> @@ -2663,15 +2663,41 @@ __update_load_avg(u64 now, int cpu, struct sched_avg *sa,
>
> #ifdef CONFIG_FAIR_GROUP_SCHED
> /*
> - * Updating tg's load_avg is necessary before update_cfs_share (which is done)
> + * Updating tg's load_avg is necessary before update_cfs_shares (which is done)
> * and effective_load (which is not done because it is too costly).
> + *
> + * The tg's use_la_delta flag, if set, will cause the load_avg delta to be
> + * accumulated into the load_avg_delta variable instead to reduce cacheline
> + * contention on load_avg at the expense of more delay in reflecting the real
> + * load_avg. The tg's load_avg and load_avg_delta variables are in separate
> + * cachelines. With that flag set, load_avg will be read mostly whereas
> + * load_avg_delta will be write mostly.
> */
> static inline void update_tg_load_avg(struct cfs_rq *cfs_rq, int force)
> {
> long delta = cfs_rq->avg.load_avg - cfs_rq->tg_load_avg_contrib;
>
> if (force || abs(delta) > cfs_rq->tg_load_avg_contrib / 64) {
> - atomic_long_add(delta, &cfs_rq->tg->load_avg);
> + struct task_group *tg = cfs_rq->tg;
> + long load_avg, tot_delta;
> +
> + if (!tg->use_la_delta) {
> + /*
> + * If the use_la_delta isn't set, just add the
> + * delta directly into load_avg.
> + */
> + atomic_long_add(delta, &tg->load_avg);
> + goto set_contrib;
> + }
> +
> + tot_delta = atomic_long_add_return(delta, &tg->load_avg_delta);
> + load_avg = atomic_long_read(&tg->load_avg);
> + if (abs(tot_delta) > load_avg / 64) {
> + tot_delta = atomic_long_xchg(&tg->load_avg_delta, 0);
> + if (tot_delta)
> + atomic_long_add(tot_delta, &tg->load_avg);
> + }
> +set_contrib:
> cfs_rq->tg_load_avg_contrib = cfs_rq->avg.load_avg;
> }
> }
I'm thinking that its now far too big to retain the inline qualifier.
> diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
> index e679895..aef4e4e 100644
> --- a/kernel/sched/sched.h
> +++ b/kernel/sched/sched.h
> @@ -252,8 +252,16 @@ struct task_group {
> * load_avg can be heavily contended at clock tick time, so put
> * it in its own cacheline separated from the fields above which
> * will also be accessed at each tick.
> + *
> + * The use_la_delta flag, if set, will enable the use of load_avg_delta
> + * to accumulate the delta and only change load_avg when the delta
> + * is big enough. This reduces the cacheline contention on load_avg.
> + * This flag will be set at allocation time depending on the system
> + * configuration.
> */
> + int use_la_delta;
> atomic_long_t load_avg ____cacheline_aligned;
> + atomic_long_t load_avg_delta ____cacheline_aligned;
This would only work if the structure itself is allocated with cacheline
alignment, and looking at sched_create_group(), we use a plain kzalloc()
for this, which doesn't guarantee any sort of alignment beyond machine
word size IIRC.
Also, you unconditionally grow the structure by a whole cacheline.
> #endif
> #endif
>
> --
> 1.7.1
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Waiman Long <waiman.long@hpe.com> |
|---|---|
| Date | 2015-11-30 20:20 +0100 |
| Subject | Re: [RFC PATCH 3/3] sched/fair: Use different cachelines for readers and writers of load_avg |
| Message-ID | <qAC9s-7Fj-9@gated-at.bofh.it> |
| In reply to | #1279754 |
On 11/30/2015 05:22 AM, Peter Zijlstra wrote:
> Please always Cc the people who wrote the code.
>
> +CC pjt, ben, morten, yuyang
Sorry for that. Their names didn't show up when I did get_maintainer.pl.
> On Wed, Nov 25, 2015 at 02:09:40PM -0500, Waiman Long wrote:
>> The load_avg statistical counter is only changed if the load on a CPU
>> deviates significantly from the previous tick. So there are usually
>> more readers than writers of load_avg. Still, on a large system,
>> the cacheline contention can cause significant slowdown and impact
>> performance.
>>
>> This patch attempts to separate those load_avg readers
>> (update_cfs_shares) and writers (task_tick_fair) to use different
>> cachelines instead. Writers of load_avg will now accumulates the
>> load delta into load_avg_delta which sits in a different cacheline.
>> If load_avg_delta is sufficiently large (> load_avg/64), it will then
>> be added back to load_avg.
>>
>> Running a java benchmark on a 16-socket IvyBridge-EX system (240 cores,
>> 480 threads), the perf profile before the patch was:
>>
>> 9.44% 0.00% java [kernel.vmlinux] [k] smp_apic_timer_interrupt
>> 8.74% 0.01% java [kernel.vmlinux] [k] hrtimer_interrupt
>> 7.83% 0.03% java [kernel.vmlinux] [k] tick_sched_timer
>> 7.74% 0.00% java [kernel.vmlinux] [k] update_process_times
>> 7.27% 0.03% java [kernel.vmlinux] [k] scheduler_tick
>> 5.94% 1.74% java [kernel.vmlinux] [k] task_tick_fair
>> 4.15% 3.92% java [kernel.vmlinux] [k] update_cfs_shares
>>
>> After the patch, it became:
>>
>> 2.94% 0.00% java [kernel.vmlinux] [k] smp_apic_timer_interrupt
>> 2.52% 0.01% java [kernel.vmlinux] [k] hrtimer_interrupt
>> 2.25% 0.02% java [kernel.vmlinux] [k] tick_sched_timer
>> 2.21% 0.00% java [kernel.vmlinux] [k] update_process_times
>> 1.70% 0.03% java [kernel.vmlinux] [k] scheduler_tick
>> 0.96% 0.34% java [kernel.vmlinux] [k] task_tick_fair
>> 0.61% 0.48% java [kernel.vmlinux] [k] update_cfs_shares
> This begs the question tough; why are you running a global load in a
> cgroup; and do we really need to update this for the root cgroup? It
> seems to me we don't need calc_tg_weight() for the root cgroup, it
> doesn't need to normalize its weight numbers.
>
> That is; isn't this simply a problem we should avoid?
I didn't use any cgroup in my test setup. Autogroup was enabled, though.
Booting up a 4.4-rc2 kernel caused sched_create_group() to be called 56
times.
>> The benchmark results before and after the patch were as follows:
>>
>> Before patch - Max-jOPs: 916011 Critical-jOps: 142366
>> AFter patch - Max-jOPs: 939130 Critical-jOps: 211937
>>
>> There was significant improvement in Critical-jOps which was latency
>> sensitive.
>>
>> This patch does introduce additional delay in getting the real load
>> average reflected in load_avg. It may also incur additional overhead
>> if the number of CPUs in a task group is small. As a result, this
>> change is only activated when running on a 4-socket or larger systems
>> which can get the most benefit from it.
> So I'm not particularly charmed by this; it rather makes a mess of
> things. Also this really wants a run of the cgroup fairness test thingy
> pjt/ben have somewhere.
I will be glad to run any additional tests, if necessary. I do need
pointers to those test, though.
>> Signed-off-by: Waiman Long<Waiman.Long@hpe.com>
>> ---
>> kernel/sched/core.c | 9 +++++++++
>> kernel/sched/fair.c | 30 ++++++++++++++++++++++++++++--
>> kernel/sched/sched.h | 8 ++++++++
>> 3 files changed, 45 insertions(+), 2 deletions(-)
>>
>> diff --git a/kernel/sched/core.c b/kernel/sched/core.c
>> index 4d568ac..f3075da 100644
>> --- a/kernel/sched/core.c
>> +++ b/kernel/sched/core.c
>> @@ -7356,6 +7356,12 @@ void __init sched_init(void)
>> root_task_group.cfs_rq = (struct cfs_rq **)ptr;
>> ptr += nr_cpu_ids * sizeof(void **);
>>
>> +#ifdef CONFIG_SMP
>> + /*
>> + * Use load_avg_delta if not 2P or less
>> + */
>> + root_task_group.use_la_delta = (num_possible_nodes()> 2);
>> +#endif /* CONFIG_SMP */
>> #endif /* CONFIG_FAIR_GROUP_SCHED */
>> #ifdef CONFIG_RT_GROUP_SCHED
>> root_task_group.rt_se = (struct sched_rt_entity **)ptr;
>> @@ -7691,6 +7697,9 @@ struct task_group *sched_create_group(struct task_group *parent)
>> if (!alloc_rt_sched_group(tg, parent))
>> goto err;
>>
>> +#if defined(CONFIG_FAIR_GROUP_SCHED)&& defined(CONFIG_SMP)
>> + tg->use_la_delta = root_task_group.use_la_delta;
>> +#endif
>> return tg;
>>
>> err:
>> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
>> index 8f1eccc..44732cc 100644
>> --- a/kernel/sched/fair.c
>> +++ b/kernel/sched/fair.c
>> @@ -2663,15 +2663,41 @@ __update_load_avg(u64 now, int cpu, struct sched_avg *sa,
>>
>> #ifdef CONFIG_FAIR_GROUP_SCHED
>> /*
>> - * Updating tg's load_avg is necessary before update_cfs_share (which is done)
>> + * Updating tg's load_avg is necessary before update_cfs_shares (which is done)
>> * and effective_load (which is not done because it is too costly).
>> + *
>> + * The tg's use_la_delta flag, if set, will cause the load_avg delta to be
>> + * accumulated into the load_avg_delta variable instead to reduce cacheline
>> + * contention on load_avg at the expense of more delay in reflecting the real
>> + * load_avg. The tg's load_avg and load_avg_delta variables are in separate
>> + * cachelines. With that flag set, load_avg will be read mostly whereas
>> + * load_avg_delta will be write mostly.
>> */
>> static inline void update_tg_load_avg(struct cfs_rq *cfs_rq, int force)
>> {
>> long delta = cfs_rq->avg.load_avg - cfs_rq->tg_load_avg_contrib;
>>
>> if (force || abs(delta)> cfs_rq->tg_load_avg_contrib / 64) {
>> - atomic_long_add(delta,&cfs_rq->tg->load_avg);
>> + struct task_group *tg = cfs_rq->tg;
>> + long load_avg, tot_delta;
>> +
>> + if (!tg->use_la_delta) {
>> + /*
>> + * If the use_la_delta isn't set, just add the
>> + * delta directly into load_avg.
>> + */
>> + atomic_long_add(delta,&tg->load_avg);
>> + goto set_contrib;
>> + }
>> +
>> + tot_delta = atomic_long_add_return(delta,&tg->load_avg_delta);
>> + load_avg = atomic_long_read(&tg->load_avg);
>> + if (abs(tot_delta)> load_avg / 64) {
>> + tot_delta = atomic_long_xchg(&tg->load_avg_delta, 0);
>> + if (tot_delta)
>> + atomic_long_add(tot_delta,&tg->load_avg);
>> + }
>> +set_contrib:
>> cfs_rq->tg_load_avg_contrib = cfs_rq->avg.load_avg;
>> }
>> }
> I'm thinking that its now far too big to retain the inline qualifier.
I can take the inline keyword out.
>
>> diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
>> index e679895..aef4e4e 100644
>> --- a/kernel/sched/sched.h
>> +++ b/kernel/sched/sched.h
>> @@ -252,8 +252,16 @@ struct task_group {
>> * load_avg can be heavily contended at clock tick time, so put
>> * it in its own cacheline separated from the fields above which
>> * will also be accessed at each tick.
>> + *
>> + * The use_la_delta flag, if set, will enable the use of load_avg_delta
>> + * to accumulate the delta and only change load_avg when the delta
>> + * is big enough. This reduces the cacheline contention on load_avg.
>> + * This flag will be set at allocation time depending on the system
>> + * configuration.
>> */
>> + int use_la_delta;
>> atomic_long_t load_avg ____cacheline_aligned;
>> + atomic_long_t load_avg_delta ____cacheline_aligned;
> This would only work if the structure itself is allocated with cacheline
> alignment, and looking at sched_create_group(), we use a plain kzalloc()
> for this, which doesn't guarantee any sort of alignment beyond machine
> word size IIRC.
With a RHEL 6 derived .config file, the size of the task_group structure
was 460 bytes on a 32-bit x86 kernel. Adding a ____cacheline_aligned tag
increase the size to 512 bytes. So it did make the structure a multiple
of the cacheline size. With both slub and slab, the allocated task group
pointers from kzalloc() in sched_create_group() were all multiples of
0x200. So they were properly aligned for the ____cacheline_aligned tag
to work.
> Also, you unconditionally grow the structure by a whole cacheline.
I know it is a drawback of using ____cacheline_aligned tag. However, we
probably won't create too many task groups in normal use. So the
increase in memory consumption shouldn't be noticeable.
Cheers,
Longman
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Date | 2015-11-30 23:20 +0100 |
| Subject | Re: [RFC PATCH 3/3] sched/fair: Use different cachelines for readers and writers of load_avg |
| Message-ID | <qAEXE-11R-23@gated-at.bofh.it> |
| In reply to | #1280215 |
On Mon, Nov 30, 2015 at 02:13:32PM -0500, Waiman Long wrote: > >This begs the question tough; why are you running a global load in a > >cgroup; and do we really need to update this for the root cgroup? It > >seems to me we don't need calc_tg_weight() for the root cgroup, it > >doesn't need to normalize its weight numbers. > > > >That is; isn't this simply a problem we should avoid? > > I didn't use any cgroup in my test setup. Autogroup was enabled, though. > Booting up a 4.4-rc2 kernel caused sched_create_group() to be called 56 > times. Yeah, can you kill autogroup and see if that helps? If not, we probably should add some code to avoid calculating things for the root group. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Waiman Long <waiman.long@hpe.com> |
|---|---|
| Date | 2015-12-01 05:00 +0100 |
| Subject | Re: [RFC PATCH 3/3] sched/fair: Use different cachelines for readers and writers of load_avg |
| Message-ID | <qAKgG-4kp-9@gated-at.bofh.it> |
| In reply to | #1280356 |
On 11/30/2015 05:09 PM, Peter Zijlstra wrote: > On Mon, Nov 30, 2015 at 02:13:32PM -0500, Waiman Long wrote: >>> This begs the question tough; why are you running a global load in a >>> cgroup; and do we really need to update this for the root cgroup? It >>> seems to me we don't need calc_tg_weight() for the root cgroup, it >>> doesn't need to normalize its weight numbers. >>> >>> That is; isn't this simply a problem we should avoid? >> I didn't use any cgroup in my test setup. Autogroup was enabled, though. >> Booting up a 4.4-rc2 kernel caused sched_create_group() to be called 56 >> times. > Yeah, can you kill autogroup and see if that helps? If not, we probably > should add some code to avoid calculating things for the root group. I will try that out tomorrow. However, SCHED_AUTOGROUP was enabled in the distribution kernels. So we still need to look at that with autogroup enabled. Cheers, Longman -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Date | 2015-12-01 09:50 +0100 |
| Subject | Re: [RFC PATCH 3/3] sched/fair: Use different cachelines for readers and writers of load_avg |
| Message-ID | <qAONk-7gM-13@gated-at.bofh.it> |
| In reply to | #1280554 |
On Mon, Nov 30, 2015 at 10:55:02PM -0500, Waiman Long wrote: > On 11/30/2015 05:09 PM, Peter Zijlstra wrote: > >On Mon, Nov 30, 2015 at 02:13:32PM -0500, Waiman Long wrote: > >>>This begs the question tough; why are you running a global load in a > >>>cgroup; and do we really need to update this for the root cgroup? It > >>>seems to me we don't need calc_tg_weight() for the root cgroup, it > >>>doesn't need to normalize its weight numbers. > >>> > >>>That is; isn't this simply a problem we should avoid? > >>I didn't use any cgroup in my test setup. Autogroup was enabled, though. > >>Booting up a 4.4-rc2 kernel caused sched_create_group() to be called 56 > >>times. > >Yeah, can you kill autogroup and see if that helps? If not, we probably > >should add some code to avoid calculating things for the root group. > > I will try that out tomorrow. However, SCHED_AUTOGROUP was enabled in the > distribution kernels. So we still need to look at that with autogroup > enabled. Meh, or just tell the people that have stupid large machines to use noautogroup on boot (its of questionable benefit in the first place imo, esp. on servers). -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Mike Galbraith <umgwanakikbuti@gmail.com> |
|---|---|
| Date | 2015-12-01 11:50 +0100 |
| Subject | Re: [RFC PATCH 3/3] sched/fair: Use different cachelines for readers and writers of load_avg |
| Message-ID | <qAQFs-8sH-31@gated-at.bofh.it> |
| In reply to | #1280651 |
On Tue, 2015-12-01 at 09:49 +0100, Peter Zijlstra wrote: > On Mon, Nov 30, 2015 at 10:55:02PM -0500, Waiman Long wrote: > > On 11/30/2015 05:09 PM, Peter Zijlstra wrote: > > >On Mon, Nov 30, 2015 at 02:13:32PM -0500, Waiman Long wrote: > > >>>This begs the question tough; why are you running a global load in a > > >>>cgroup; and do we really need to update this for the root cgroup? It > > >>>seems to me we don't need calc_tg_weight() for the root cgroup, it > > >>>doesn't need to normalize its weight numbers. > > >>> > > >>>That is; isn't this simply a problem we should avoid? > > >>I didn't use any cgroup in my test setup. Autogroup was enabled, though. > > >>Booting up a 4.4-rc2 kernel caused sched_create_group() to be called 56 > > >>times. > > >Yeah, can you kill autogroup and see if that helps? If not, we probably > > >should add some code to avoid calculating things for the root group. > > > > I will try that out tomorrow. However, SCHED_AUTOGROUP was enabled in the > > distribution kernels. So we still need to look at that with autogroup > > enabled. > > Meh, or just tell the people that have stupid large machines to use > noautogroup on boot (its of questionable benefit in the first place imo, > esp. on servers). Yup (and yup). Someone should also suggest to the systemd(isease) folks that they try actually measuring before turning everything in the world on. "Oo cgroups are cool" is NOT a good reason to turn it all on :) -Mike -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Waiman Long <waiman.long@hpe.com> |
|---|---|
| Date | 2015-12-02 19:50 +0100 |
| Subject | Re: [RFC PATCH 3/3] sched/fair: Use different cachelines for readers and writers of load_avg |
| Message-ID | <qBkDw-2x9-9@gated-at.bofh.it> |
| In reply to | #1280651 |
On 12/01/2015 03:49 AM, Peter Zijlstra wrote: > On Mon, Nov 30, 2015 at 10:55:02PM -0500, Waiman Long wrote: >> On 11/30/2015 05:09 PM, Peter Zijlstra wrote: >>> On Mon, Nov 30, 2015 at 02:13:32PM -0500, Waiman Long wrote: >>>>> This begs the question tough; why are you running a global load in a >>>>> cgroup; and do we really need to update this for the root cgroup? It >>>>> seems to me we don't need calc_tg_weight() for the root cgroup, it >>>>> doesn't need to normalize its weight numbers. >>>>> >>>>> That is; isn't this simply a problem we should avoid? >>>> I didn't use any cgroup in my test setup. Autogroup was enabled, though. >>>> Booting up a 4.4-rc2 kernel caused sched_create_group() to be called 56 >>>> times. >>> Yeah, can you kill autogroup and see if that helps? If not, we probably >>> should add some code to avoid calculating things for the root group. >> I will try that out tomorrow. However, SCHED_AUTOGROUP was enabled in the >> distribution kernels. So we still need to look at that with autogroup >> enabled. > Meh, or just tell the people that have stupid large machines to use > noautogroup on boot (its of questionable benefit in the first place imo, > esp. on servers). Yes, I was able to recover most of the lost performance by disabling autogroup. I did send out a new patch to disable load_avg update for root_task_group. I need that for backporting to earlier kernels which was forced to update load_avg for every clock tick even for root_task_group. Cheers, Longman -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Date | 2015-11-30 23:30 +0100 |
| Subject | Re: [RFC PATCH 3/3] sched/fair: Use different cachelines for readers and writers of load_avg |
| Message-ID | <qAF7k-15b-11@gated-at.bofh.it> |
| In reply to | #1280215 |
On Mon, Nov 30, 2015 at 02:13:32PM -0500, Waiman Long wrote: > >This would only work if the structure itself is allocated with cacheline > >alignment, and looking at sched_create_group(), we use a plain kzalloc() > >for this, which doesn't guarantee any sort of alignment beyond machine > >word size IIRC. > > With a RHEL 6 derived .config file, the size of the task_group structure was > 460 bytes on a 32-bit x86 kernel. Adding a ____cacheline_aligned tag > increase the size to 512 bytes. So it did make the structure a multiple of > the cacheline size. With both slub and slab, the allocated task group > pointers from kzalloc() in sched_create_group() were all multiples of 0x200. > So they were properly aligned for the ____cacheline_aligned tag to work. Not sure we should rely on sl*b doing the right thing here. KMALLOC_MIN_ALIGN is explicitly set to sizeof(long long). If you want explicit alignment, one should use KMEM_CACHE(). -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Waiman Long <waiman.long@hpe.com> |
|---|---|
| Date | 2015-12-01 05:10 +0100 |
| Subject | Re: [RFC PATCH 3/3] sched/fair: Use different cachelines for readers and writers of load_avg |
| Message-ID | <qAKql-4CV-3@gated-at.bofh.it> |
| In reply to | #1280367 |
On 11/30/2015 05:29 PM, Peter Zijlstra wrote: > On Mon, Nov 30, 2015 at 02:13:32PM -0500, Waiman Long wrote: >>> This would only work if the structure itself is allocated with cacheline >>> alignment, and looking at sched_create_group(), we use a plain kzalloc() >>> for this, which doesn't guarantee any sort of alignment beyond machine >>> word size IIRC. >> With a RHEL 6 derived .config file, the size of the task_group structure was >> 460 bytes on a 32-bit x86 kernel. Adding a ____cacheline_aligned tag >> increase the size to 512 bytes. So it did make the structure a multiple of >> the cacheline size. With both slub and slab, the allocated task group >> pointers from kzalloc() in sched_create_group() were all multiples of 0x200. >> So they were properly aligned for the ____cacheline_aligned tag to work. > Not sure we should rely on sl*b doing the right thing here. > KMALLOC_MIN_ALIGN is explicitly set to sizeof(long long). If you want > explicit alignment, one should use KMEM_CACHE(). I think the current kernel use power-of-2 kmemcaches to satisfy kalloc() requests except when the size is less than or equal to 192 where there are some non-power-of-2 kmemcaches available. Given that the task_group structure is large enough with FAIR_GROUP_SCHED enabled, we shouldn't hit the case that the allocated buffer is not cacheline aligned. Cheers, Longman -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Date | 2015-12-01 09:50 +0100 |
| Subject | Re: [RFC PATCH 3/3] sched/fair: Use different cachelines for readers and writers of load_avg |
| Message-ID | <qAONk-7gM-9@gated-at.bofh.it> |
| In reply to | #1280558 |
On Mon, Nov 30, 2015 at 11:00:35PM -0500, Waiman Long wrote: > I think the current kernel use power-of-2 kmemcaches to satisfy kalloc() > requests except when the size is less than or equal to 192 where there are > some non-power-of-2 kmemcaches available. Given that the task_group > structure is large enough with FAIR_GROUP_SCHED enabled, we shouldn't hit > the case that the allocated buffer is not cacheline aligned. Using out-of-object storage is allowed (none of the existing sl*b allocators do so iirc). That is, its perfectly valid for a sl*b allocator for 64 byte objects to allocate 72 bytes for each object and use the 'spare' 8 bytes for object tracking or whatnot. That would respect the minimum alignment guarantee of 8 bytes but not provide the 'expected' object size alignment you're assuming. Also, we have the proper interfaces to request the explicit alignment for a reason. So if you need the alignment for correctness, use those. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Waiman Long <waiman.long@hpe.com> |
|---|---|
| Date | 2015-12-02 19:50 +0100 |
| Subject | Re: [RFC PATCH 3/3] sched/fair: Use different cachelines for readers and writers of load_avg |
| Message-ID | <qBkDw-2x9-11@gated-at.bofh.it> |
| In reply to | #1280649 |
On 12/01/2015 03:47 AM, Peter Zijlstra wrote: > On Mon, Nov 30, 2015 at 11:00:35PM -0500, Waiman Long wrote: > >> I think the current kernel use power-of-2 kmemcaches to satisfy kalloc() >> requests except when the size is less than or equal to 192 where there are >> some non-power-of-2 kmemcaches available. Given that the task_group >> structure is large enough with FAIR_GROUP_SCHED enabled, we shouldn't hit >> the case that the allocated buffer is not cacheline aligned. > Using out-of-object storage is allowed (none of the existing sl*b > allocators do so iirc). > > That is, its perfectly valid for a sl*b allocator for 64 byte objects to > allocate 72 bytes for each object and use the 'spare' 8 bytes for object > tracking or whatnot. > > That would respect the minimum alignment guarantee of 8 bytes but not > provide the 'expected' object size alignment you're assuming. > > Also, we have the proper interfaces to request the explicit alignment > for a reason. So if you need the alignment for correctness, use those. Thanks for the tip. I have just sent out an updated patch set which create a cache-aligned memcache for task group. That should work under all kernel config setting. Cheers, Longman -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Date | 2015-11-30 23:40 +0100 |
| Subject | Re: [RFC PATCH 3/3] sched/fair: Use different cachelines for readers and writers of load_avg |
| Message-ID | <qAFh0-18d-19@gated-at.bofh.it> |
| In reply to | #1280215 |
On Mon, Nov 30, 2015 at 02:13:32PM -0500, Waiman Long wrote: > On 11/30/2015 05:22 AM, Peter Zijlstra wrote: > >Please always Cc the people who wrote the code. > > > >+CC pjt, ben, morten, yuyang > > Sorry for that. Their names didn't show up when I did get_maintainer.pl. Ah, I never much use get_maintainers.pl, but it might that --git-blame would yield some of the people who poked at this code. But I suspect its all yuyang now, seeing how he recently reworked it all. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web