aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2010-10-26 05:11:40 -0400
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2010-11-30 01:02:40 -0500
commit46fdb0937f26124700fc9fc80da4776330cc00d3 (patch)
treece3bdf6c0379fdab8c72085f885402751fadea52
parentdb3a8920995484e5e9a0abaf3bad2c7311b163db (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/Kconfig15
-rw-r--r--kernel/srcu.c8
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
491config 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
491endmenu # "RCU Subsystem" 506endmenu # "RCU Subsystem"
492 507
493config IKCONFIG 508config 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
36static int init_srcu_struct_fields(struct srcu_struct *sp) 37static 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