kernel/smp: Small csd_lock optimizations
cover kernel/smp: Small csd_lock optimizations
From: Davidlohr Bueso <[email protected]>
Hi,
Justifications are in each patch, there is slight impact (patch 2) on some tlb flushing intensive benchmarks (albeit using ipi batching nowadays). Specifically for the pft
benchmark, on a 12-core box:
pft faults
4.4 4.4
vanilla smp
Hmean faults/cpu-1 801432.1608 ( 0.00%) 795719.8859 ( -0.71%) Hmean faults/cpu-3 702578.6659 ( 0.00%) 752796.6960 ( 7.15%) Hmean faults/cpu-5 606080.3473 ( 0.00%) 595890.0451 ( -1.68%) Hmean faults/cpu-7 460369.0724 ( 0.00%) 485283.6343 ( 5.41%) Hmean faults/cpu-12 294445.4701 ( 0.00%) 298300.6011 ( 1.31%) Hmean faults/cpu-18 213156.0860 ( 0.00%) 213584.2741 ( 0.20%) Hmean faults/cpu-24 153104.2995 ( 0.00%) 153198.8473 ( 0.06%) Hmean faults/sec-1 796329.3184 ( 0.00%) 614222.4594 (-22.87%) Hmean faults/sec-3 1947806.7372 ( 0.00%) 2169267.1582 ( 11.37%) Hmean faults/sec-5 2611152.0422 ( 0.00%) 2544652.6871 ( -2.55%) Hmean faults/sec-7 2493705.4668 ( 0.00%) 2674847.5270 ( 7.26%) Hmean faults/sec-12 2583139.7724 ( 0.00%) 2614404.6002 ( 1.21%) Hmean faults/sec-18 2661410.8170 ( 0.00%) 2683427.0703 ( 0.83%) Hmean faults/sec-24 2670463.4814 ( 0.00%) 2666221.6332 ( -0.16%) Stddev faults/cpu-1 27537.6676 ( 0.00%) 25753.4945 ( 6.48%) Stddev faults/cpu-3 62616.8041 ( 0.00%) 44728.0990 ( 28.57%) Stddev faults/cpu-5 70976.9184 ( 0.00%) 74720.5716 ( -5.27%) Stddev faults/cpu-7 47426.5952 ( 0.00%) 32758.2705 ( 30.93%) Stddev faults/cpu-12 6951.8792 ( 0.00%) 9097.0782 (-30.86%) Stddev faults/cpu-18 4293.1696 ( 0.00%) 5826.9446 (-35.73%) Stddev faults/cpu-24 3195.0939 ( 0.00%) 3373.7230 ( -5.59%) Stddev faults/sec-1 27315.3093 ( 0.00%) 148601.7795 (-444.02%) Stddev faults/sec-3 271560.5941 ( 0.00%) 193681.0177 ( 28.68%) Stddev faults/sec-5 429633.7378 ( 0.00%) 458426.3306 ( -6.70%) Stddev faults/sec-7 338229.0746 ( 0.00%) 226146.3450 ( 33.14%) Stddev faults/sec-12 57766.4604 ( 0.00%) 82734.3638 (-43.22%) Stddev faults/sec-18 118572.1909 ( 0.00%) 134966.7210 (-13.83%) Stddev faults/sec-24 57452.7350 ( 0.00%) 57542.7755 ( -0.16%)
4.4 4.4
vanilla smpUser 11.91 11.85
System 197.11 194.69
Elapsed 44.24 40.26
While the single thread is an abnormality, overall we don't seem to do any harm (noise range). Could be give or take, but overall the patches at least make some sense afaict.
Thanks!
Davidlohr Bueso (2):
kernel/smp: Explicitly inline cds_lock helpers kernel/smp: Use make csd_lock_wait be smp_cond_acquire
kernel/smp.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
--
2.1.4
PATCH 1/2 kernel/smp: Explicitly inline cds_lock helpers
From: Davidlohr Bueso <[email protected]>
While the compiler tends to already to it for us (except for cds_unlock), make it explicit. These helpers mainly deal with the ->flags, are short-lived and can be called, for example, from smp_call_function_many().
--- kernel/smp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
kernel/smp.c +3 -3
@@ -105,13 +105,13 @@ void __init call_function_init(void)* previous function call. For multi-cpu calls its even more interesting * as we'll have to ensure no other cpu is observing our csd. */ -static void csd_lock_wait (struct call_single_data *csd) +static __always_inline void csd_lock_wait(struct call_single_data *csd) {while (smp_load_acquire (&csd->flags) &CSD_FLAG_LOCK )cpu_relax (); } -static void csd_lock (struct call_single_data *csd) +static __always_inline void csd_lock(struct call_single_data *csd) {csd_lock_wait (csd); csd->flags |=CSD_FLAG_LOCK ;
@@ -124,7 +124,7 @@ static void csd_lock(struct call_single_data *csd)smp_wmb (); } -static void csd_unlock (struct call_single_data *csd) +static __always_inline void csd_unlock(struct call_single_data *csd) {WARN_ON (!(csd->flags &CSD_FLAG_LOCK ));
Signature · 1 line
2.1.4
tip-bot for Davidlohr Bueso
merge bot[tip:locking/core] locking/csd_lock: Explicitly inline csd_lock*() helpers
locking/csd_lock: Explicitly inline csd_lock*() helpers
Commit-ID: 90d1098478fb08a1ef166fe91622d8046869e17b Gitweb: http://git.kernel.org/tip/90d1098478fb08a1ef166fe91622d8046869e17b Author: Davidlohr Bueso <[email protected]> AuthorDate: Wed, 9 Mar 2016 17:55:35 -0800 Committer: Ingo Molnar <[email protected]> CommitDate: Thu, 10 Mar 2016 10:28:35 +0100
locking/csd_lock: Explicitly inline csd_lock*() helpers
While the compiler tends to already to it for us (except for csd_unlock), make it explicit. These helpers mainly deal with the ->flags, are short-lived and can be called, for example, from smp_call_function_many().
--- kernel/smp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
kernel/smp.c +3 -3
@@ -105,13 +105,13 @@ void __init call_function_init(void)* previous function call. For multi-cpu calls its even more interesting * as we'll have to ensure no other cpu is observing our csd. */ -static void csd_lock_wait (struct call_single_data *csd) +static __always_inline void csd_lock_wait(struct call_single_data *csd) {while (smp_load_acquire (&csd->flags) &CSD_FLAG_LOCK )cpu_relax (); } -static void csd_lock (struct call_single_data *csd) +static __always_inline void csd_lock(struct call_single_data *csd) {csd_lock_wait (csd); csd->flags |=CSD_FLAG_LOCK ;
@@ -124,7 +124,7 @@ static void csd_lock(struct call_single_data *csd)smp_wmb (); } -static void csd_unlock (struct call_single_data *csd) +static __always_inline void csd_unlock(struct call_single_data *csd) {WARN_ON (!(csd->flags &CSD_FLAG_LOCK ));
PATCH 2/2 kernel/smp: Use make csd_lock_wait be smp_cond_acquire
In reply to Davidlohr BuesoFrom: Davidlohr Bueso <dave@stgolabs>
We can micro-optimize this call and mildly relax the barrier requirements by relying on ctrl + rmb, keeping the acquire semantics. In addition, this is pretty much the now standard for busy-waiting under such restraints.
--- kernel/smp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
kernel/smp.c +1 -2
@@ -107,8 +107,7 @@ void __init call_function_init(void)*/ static __always_inline void csd_lock_wait(struct call_single_data *csd) { -while (smp_load_acquire (&csd->flags) &CSD_FLAG_LOCK ) -cpu_relax (); +smp_cond_acquire (!(csd->flags &CSD_FLAG_LOCK )); } static __always_inline void csd_lock(struct call_single_data *csd)
Signature · 1 line
2.1.4
tip-bot for Davidlohr Bueso
merge bot[tip:locking/core] locking/csd_lock: Use smp_cond_acquire() in csd_lock_wait()
locking/csd_lock: Use smp_cond_acquire() in csd_lock_wait()
Commit-ID: 38460a2178d225b39ade5ac66586c3733391cf86 Gitweb: http://git.kernel.org/tip/38460a2178d225b39ade5ac66586c3733391cf86 Author: Davidlohr Bueso <dave@stgolabs> AuthorDate: Wed, 9 Mar 2016 17:55:36 -0800 Committer: Ingo Molnar <[email protected]> CommitDate: Thu, 10 Mar 2016 10:28:35 +0100
locking/csd_lock: Use smp_cond_acquire() in csd_lock_wait()
We can micro-optimize this call and mildly relax the barrier requirements by relying on ctrl + rmb, keeping the acquire semantics. In addition, this is pretty much the now standard for busy-waiting under such restraints.
--- kernel/smp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
kernel/smp.c +1 -2
@@ -107,8 +107,7 @@ void __init call_function_init(void)*/ static __always_inline void csd_lock_wait(struct call_single_data *csd) { -while (smp_load_acquire (&csd->flags) &CSD_FLAG_LOCK ) -cpu_relax (); +smp_cond_acquire (!(csd->flags &CSD_FLAG_LOCK )); } static __always_inline void csd_lock(struct call_single_data *csd)
Quoted 11 lines · Davidlohr Bueso
From: Davidlohr Bueso <[email protected]>
Hi,
Justifications are in each patch, there is slight impact (patch 2) on some tlb flushing intensive benchmarks (albeit using ipi batching nowadays). Specifically for the pft
benchmark, on a 12-core box:4.4 4.4 vanilla smp
Quoted 7 lines
User 11.91 11.85
System 197.11 194.69
Elapsed 44.24 40.26While the single thread is an abnormality, overall we don't seem to do any harm (noise range). Could be give or take, but overall the patches at least make some sense afaict.