diff options
author | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2010-10-26 05:11:40 -0400 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2010-11-30 01:02:40 -0500 |
commit | 46fdb0937f26124700fc9fc80da4776330cc00d3 (patch) | |
tree | ce3bdf6c0379fdab8c72085f885402751fadea52 | |
parent | db3a8920995484e5e9a0abaf3bad2c7311b163db (diff) |
rcu: Make synchronize_srcu_expedited() fast if running readers
The synchronize_srcu_expedited() function is currently quick if there
are no active readers, but will delay a full jiffy if there are any.
If these readers leave their SRCU read-side critical sections quickly,
this is way too long to wait. So this commit first waits ten microseconds,
and only then falls back to jiffy-at-a-time waiting.
Reported-by: Avi Kivity <avi@redhat.com>
Reported-by: Marcelo Tosatti <mtosatti@redhat.com>
Tested-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
-rw-r--r-- | init/Kconfig | 15 | ||||
-rw-r--r-- | kernel/srcu.c | 8 |
2 files changed, 22 insertions, 1 deletions
diff --git a/init/Kconfig b/init/Kconfig index 929adf6cb6b..35518243c4b 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -488,6 +488,21 @@ config RCU_BOOST_DELAY | |||
488 | 488 | ||
489 | Accept the default if unsure. | 489 | Accept the default if unsure. |
490 | 490 | ||
491 | config SRCU_SYNCHRONIZE_DELAY | ||
492 | int "Microseconds to delay before waiting for readers" | ||
493 | range 0 20 | ||
494 | default 10 | ||
495 | help | ||
496 | This option controls how long SRCU delays before entering its | ||
497 | loop waiting on SRCU readers. The purpose of this loop is | ||
498 | to avoid the unconditional context-switch penalty that would | ||
499 | otherwise be incurred if there was an active SRCU reader, | ||
500 | in a manner similar to adaptive locking schemes. This should | ||
501 | be set to be a bit longer than the common-case SRCU read-side | ||
502 | critical-section overhead. | ||
503 | |||
504 | Accept the default if unsure. | ||
505 | |||
491 | endmenu # "RCU Subsystem" | 506 | endmenu # "RCU Subsystem" |
492 | 507 | ||
493 | config IKCONFIG | 508 | config IKCONFIG |
diff --git a/kernel/srcu.c b/kernel/srcu.c index c71e0750053..98d8c1e80ed 100644 --- a/kernel/srcu.c +++ b/kernel/srcu.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/rcupdate.h> | 31 | #include <linux/rcupdate.h> |
32 | #include <linux/sched.h> | 32 | #include <linux/sched.h> |
33 | #include <linux/smp.h> | 33 | #include <linux/smp.h> |
34 | #include <linux/delay.h> | ||
34 | #include <linux/srcu.h> | 35 | #include <linux/srcu.h> |
35 | 36 | ||
36 | static int init_srcu_struct_fields(struct srcu_struct *sp) | 37 | static int init_srcu_struct_fields(struct srcu_struct *sp) |
@@ -203,9 +204,14 @@ static void __synchronize_srcu(struct srcu_struct *sp, void (*sync_func)(void)) | |||
203 | * all srcu_read_lock() calls using the old counters have completed. | 204 | * all srcu_read_lock() calls using the old counters have completed. |
204 | * Their corresponding critical sections might well be still | 205 | * Their corresponding critical sections might well be still |
205 | * executing, but the srcu_read_lock() primitives themselves | 206 | * executing, but the srcu_read_lock() primitives themselves |
206 | * will have finished executing. | 207 | * will have finished executing. We initially give readers |
208 | * an arbitrarily chosen 10 microseconds to get out of their | ||
209 | * SRCU read-side critical sections, then loop waiting 1/HZ | ||
210 | * seconds per iteration. | ||
207 | */ | 211 | */ |
208 | 212 | ||
213 | if (srcu_readers_active_idx(sp, idx)) | ||
214 | udelay(CONFIG_SRCU_SYNCHRONIZE_DELAY); | ||
209 | while (srcu_readers_active_idx(sp, idx)) | 215 | while (srcu_readers_active_idx(sp, idx)) |
210 | schedule_timeout_interruptible(1); | 216 | schedule_timeout_interruptible(1); |
211 | 217 | ||