aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2015-02-18 15:24:30 -0500
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2015-02-26 15:02:59 -0500
commit0d39482c3db13aae1db143d340816108dd53e443 (patch)
treedbcf5c785244bd29da2190d65a92fb1ca497a009
parentc517d838eb7d07bbe9507871fab3931deccff539 (diff)
rcu: Provide rcu_expedite_gp() and rcu_unexpedite_gp()
Currently, expediting of normal synchronous grace-period primitives (synchronize_rcu() and friends) is controlled by the rcu_expedited() boot/sysfs parameter. This works well, but does not handle nesting. This commit therefore provides rcu_expedite_gp() to enable expediting and rcu_unexpedite_gp() to cancel a prior rcu_expedite_gp(), both of which support nesting. Reported-by: Arjan van de Ven <arjan@linux.intel.com> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
-rw-r--r--include/linux/rcupdate.h20
-rw-r--r--kernel/rcu/update.c48
2 files changed, 68 insertions, 0 deletions
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 78097491cd99..57a4d1f73a00 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -48,6 +48,26 @@
48 48
49extern int rcu_expedited; /* for sysctl */ 49extern int rcu_expedited; /* for sysctl */
50 50
51#ifdef CONFIG_TINY_RCU
52/* Tiny RCU doesn't expedite, as its purpose in life is instead to be tiny. */
53static inline bool rcu_gp_is_expedited(void) /* Internal RCU use. */
54{
55 return false;
56}
57
58static inline void rcu_expedite_gp(void)
59{
60}
61
62static inline void rcu_unexpedite_gp(void)
63{
64}
65#else /* #ifdef CONFIG_TINY_RCU */
66bool rcu_gp_is_expedited(void); /* Internal RCU use. */
67void rcu_expedite_gp(void);
68void rcu_unexpedite_gp(void);
69#endif /* #else #ifdef CONFIG_TINY_RCU */
70
51enum rcutorture_type { 71enum rcutorture_type {
52 RCU_FLAVOR, 72 RCU_FLAVOR,
53 RCU_BH_FLAVOR, 73 RCU_BH_FLAVOR,
diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c
index e0d31a345ee6..5f850823c187 100644
--- a/kernel/rcu/update.c
+++ b/kernel/rcu/update.c
@@ -62,6 +62,54 @@ MODULE_ALIAS("rcupdate");
62 62
63module_param(rcu_expedited, int, 0); 63module_param(rcu_expedited, int, 0);
64 64
65#ifndef CONFIG_TINY_RCU
66
67static atomic_t rcu_expedited_nesting;
68
69/*
70 * Should normal grace-period primitives be expedited? Intended for
71 * use within RCU. Note that this function takes the rcu_expedited
72 * sysfs/boot variable into account as well as the rcu_expedite_gp()
73 * nesting. So looping on rcu_unexpedite_gp() until rcu_gp_is_expedited()
74 * returns false is a -really- bad idea.
75 */
76bool rcu_gp_is_expedited(void)
77{
78 return rcu_expedited || atomic_read(&rcu_expedited_nesting);
79}
80EXPORT_SYMBOL_GPL(rcu_gp_is_expedited);
81
82/**
83 * rcu_expedite_gp - Expedite future RCU grace periods
84 *
85 * After a call to this function, future calls to synchronize_rcu() and
86 * friends act as the corresponding synchronize_rcu_expedited() function
87 * had instead been called.
88 */
89void rcu_expedite_gp(void)
90{
91 atomic_inc(&rcu_expedited_nesting);
92}
93EXPORT_SYMBOL_GPL(rcu_expedite_gp);
94
95/**
96 * rcu_unexpedite_gp - Cancel prior rcu_expedite_gp() invocation
97 *
98 * Undo a prior call to rcu_expedite_gp(). If all prior calls to
99 * rcu_expedite_gp() are undone by a subsequent call to rcu_unexpedite_gp(),
100 * and if the rcu_expedited sysfs/boot parameter is not set, then all
101 * subsequent calls to synchronize_rcu() and friends will return to
102 * their normal non-expedited behavior.
103 */
104void rcu_unexpedite_gp(void)
105{
106 atomic_dec(&rcu_expedited_nesting);
107}
108EXPORT_SYMBOL_GPL(rcu_unexpedite_gp);
109
110#endif /* #ifndef CONFIG_TINY_RCU */
111
112
65#ifdef CONFIG_PREEMPT_RCU 113#ifdef CONFIG_PREEMPT_RCU
66 114
67/* 115/*