summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/kernel-parameters.txt19
-rw-r--r--include/linux/rcupdate.h6
-rw-r--r--kernel/ksysfs.c22
-rw-r--r--kernel/rcu/srcu.c2
-rw-r--r--kernel/rcu/tree.c6
-rw-r--r--kernel/rcu/tree_plugin.h6
-rw-r--r--kernel/rcu/update.c12
7 files changed, 65 insertions, 8 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 742f69d18fc8..7673943d3085 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -3296,6 +3296,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
3296 rcutorture.verbose= [KNL] 3296 rcutorture.verbose= [KNL]
3297 Enable additional printk() statements. 3297 Enable additional printk() statements.
3298 3298
3299 rcupdate.rcu_cpu_stall_suppress= [KNL]
3300 Suppress RCU CPU stall warning messages.
3301
3302 rcupdate.rcu_cpu_stall_timeout= [KNL]
3303 Set timeout for RCU CPU stall warning messages.
3304
3299 rcupdate.rcu_expedited= [KNL] 3305 rcupdate.rcu_expedited= [KNL]
3300 Use expedited grace-period primitives, for 3306 Use expedited grace-period primitives, for
3301 example, synchronize_rcu_expedited() instead 3307 example, synchronize_rcu_expedited() instead
@@ -3303,11 +3309,14 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
3303 but can increase CPU utilization, degrade 3309 but can increase CPU utilization, degrade
3304 real-time latency, and degrade energy efficiency. 3310 real-time latency, and degrade energy efficiency.
3305 3311
3306 rcupdate.rcu_cpu_stall_suppress= [KNL] 3312 rcupdate.rcu_normal= [KNL]
3307 Suppress RCU CPU stall warning messages. 3313 Use only normal grace-period primitives,
3308 3314 for example, synchronize_rcu() instead of
3309 rcupdate.rcu_cpu_stall_timeout= [KNL] 3315 synchronize_rcu_expedited(). This improves
3310 Set timeout for RCU CPU stall warning messages. 3316 real-time latency, CPU utilization, and energy
3317 efficiency, but can expose users to increased
3318 grace-period latency. This parameter overrides
3319 rcupdate.rcu_expedited.
3311 3320
3312 rcupdate.rcu_task_stall_timeout= [KNL] 3321 rcupdate.rcu_task_stall_timeout= [KNL]
3313 Set timeout in jiffies for RCU task stall warning 3322 Set timeout in jiffies for RCU task stall warning
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index a0189ba67fde..98d9f30c02d4 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -49,9 +49,14 @@
49#include <asm/barrier.h> 49#include <asm/barrier.h>
50 50
51extern int rcu_expedited; /* for sysctl */ 51extern int rcu_expedited; /* for sysctl */
52extern int rcu_normal; /* also for sysctl */
52 53
53#ifdef CONFIG_TINY_RCU 54#ifdef CONFIG_TINY_RCU
54/* Tiny RCU doesn't expedite, as its purpose in life is instead to be tiny. */ 55/* Tiny RCU doesn't expedite, as its purpose in life is instead to be tiny. */
56static inline bool rcu_gp_is_normal(void) /* Internal RCU use. */
57{
58 return true;
59}
55static inline bool rcu_gp_is_expedited(void) /* Internal RCU use. */ 60static inline bool rcu_gp_is_expedited(void) /* Internal RCU use. */
56{ 61{
57 return false; 62 return false;
@@ -65,6 +70,7 @@ static inline void rcu_unexpedite_gp(void)
65{ 70{
66} 71}
67#else /* #ifdef CONFIG_TINY_RCU */ 72#else /* #ifdef CONFIG_TINY_RCU */
73bool rcu_gp_is_normal(void); /* Internal RCU use. */
68bool rcu_gp_is_expedited(void); /* Internal RCU use. */ 74bool rcu_gp_is_expedited(void); /* Internal RCU use. */
69void rcu_expedite_gp(void); 75void rcu_expedite_gp(void);
70void rcu_unexpedite_gp(void); 76void rcu_unexpedite_gp(void);
diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c
index e83b26464061..b4e2fa52d8bc 100644
--- a/kernel/ksysfs.c
+++ b/kernel/ksysfs.c
@@ -20,7 +20,7 @@
20#include <linux/capability.h> 20#include <linux/capability.h>
21#include <linux/compiler.h> 21#include <linux/compiler.h>
22 22
23#include <linux/rcupdate.h> /* rcu_expedited */ 23#include <linux/rcupdate.h> /* rcu_expedited and rcu_normal */
24 24
25#define KERNEL_ATTR_RO(_name) \ 25#define KERNEL_ATTR_RO(_name) \
26static struct kobj_attribute _name##_attr = __ATTR_RO(_name) 26static struct kobj_attribute _name##_attr = __ATTR_RO(_name)
@@ -148,7 +148,7 @@ int rcu_expedited;
148static ssize_t rcu_expedited_show(struct kobject *kobj, 148static ssize_t rcu_expedited_show(struct kobject *kobj,
149 struct kobj_attribute *attr, char *buf) 149 struct kobj_attribute *attr, char *buf)
150{ 150{
151 return sprintf(buf, "%d\n", rcu_expedited); 151 return sprintf(buf, "%d\n", READ_ONCE(rcu_expedited));
152} 152}
153static ssize_t rcu_expedited_store(struct kobject *kobj, 153static ssize_t rcu_expedited_store(struct kobject *kobj,
154 struct kobj_attribute *attr, 154 struct kobj_attribute *attr,
@@ -161,6 +161,23 @@ static ssize_t rcu_expedited_store(struct kobject *kobj,
161} 161}
162KERNEL_ATTR_RW(rcu_expedited); 162KERNEL_ATTR_RW(rcu_expedited);
163 163
164int rcu_normal;
165static ssize_t rcu_normal_show(struct kobject *kobj,
166 struct kobj_attribute *attr, char *buf)
167{
168 return sprintf(buf, "%d\n", READ_ONCE(rcu_normal));
169}
170static ssize_t rcu_normal_store(struct kobject *kobj,
171 struct kobj_attribute *attr,
172 const char *buf, size_t count)
173{
174 if (kstrtoint(buf, 0, &rcu_normal))
175 return -EINVAL;
176
177 return count;
178}
179KERNEL_ATTR_RW(rcu_normal);
180
164/* 181/*
165 * Make /sys/kernel/notes give the raw contents of our kernel .notes section. 182 * Make /sys/kernel/notes give the raw contents of our kernel .notes section.
166 */ 183 */
@@ -203,6 +220,7 @@ static struct attribute * kernel_attrs[] = {
203 &vmcoreinfo_attr.attr, 220 &vmcoreinfo_attr.attr,
204#endif 221#endif
205 &rcu_expedited_attr.attr, 222 &rcu_expedited_attr.attr,
223 &rcu_normal_attr.attr,
206 NULL 224 NULL
207}; 225};
208 226
diff --git a/kernel/rcu/srcu.c b/kernel/rcu/srcu.c
index a63a1ea5a41b..9b9cdd549caa 100644
--- a/kernel/rcu/srcu.c
+++ b/kernel/rcu/srcu.c
@@ -489,7 +489,7 @@ static void __synchronize_srcu(struct srcu_struct *sp, int trycount)
489 */ 489 */
490void synchronize_srcu(struct srcu_struct *sp) 490void synchronize_srcu(struct srcu_struct *sp)
491{ 491{
492 __synchronize_srcu(sp, rcu_gp_is_expedited() 492 __synchronize_srcu(sp, (rcu_gp_is_expedited() && !rcu_gp_is_normal())
493 ? SYNCHRONIZE_SRCU_EXP_TRYCOUNT 493 ? SYNCHRONIZE_SRCU_EXP_TRYCOUNT
494 : SYNCHRONIZE_SRCU_TRYCOUNT); 494 : SYNCHRONIZE_SRCU_TRYCOUNT);
495} 495}
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index 6a652d1f3d7f..489992997c06 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -3841,6 +3841,12 @@ void synchronize_sched_expedited(void)
3841 if (rcu_blocking_is_gp()) 3841 if (rcu_blocking_is_gp())
3842 return; 3842 return;
3843 3843
3844 /* If expedited grace periods are prohibited, fall back to normal. */
3845 if (rcu_gp_is_normal()) {
3846 wait_rcu_gp(call_rcu_sched);
3847 return;
3848 }
3849
3844 /* Take a snapshot of the sequence number. */ 3850 /* Take a snapshot of the sequence number. */
3845 s = rcu_exp_gp_seq_snap(rsp); 3851 s = rcu_exp_gp_seq_snap(rsp);
3846 3852
diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h
index 57ba873d2f18..d45df3781551 100644
--- a/kernel/rcu/tree_plugin.h
+++ b/kernel/rcu/tree_plugin.h
@@ -746,6 +746,12 @@ void synchronize_rcu_expedited(void)
746 struct rcu_state *rsp = rcu_state_p; 746 struct rcu_state *rsp = rcu_state_p;
747 unsigned long s; 747 unsigned long s;
748 748
749 /* If expedited grace periods are prohibited, fall back to normal. */
750 if (rcu_gp_is_normal()) {
751 wait_rcu_gp(call_rcu);
752 return;
753 }
754
749 s = rcu_exp_gp_seq_snap(rsp); 755 s = rcu_exp_gp_seq_snap(rsp);
750 756
751 rnp_unlock = exp_funnel_lock(rsp, s); 757 rnp_unlock = exp_funnel_lock(rsp, s);
diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c
index 5f748c5a40f0..8fccda3a794d 100644
--- a/kernel/rcu/update.c
+++ b/kernel/rcu/update.c
@@ -61,6 +61,7 @@ MODULE_ALIAS("rcupdate");
61#define MODULE_PARAM_PREFIX "rcupdate." 61#define MODULE_PARAM_PREFIX "rcupdate."
62 62
63module_param(rcu_expedited, int, 0); 63module_param(rcu_expedited, int, 0);
64module_param(rcu_normal, int, 0);
64 65
65#if defined(CONFIG_DEBUG_LOCK_ALLOC) && defined(CONFIG_PREEMPT_COUNT) 66#if defined(CONFIG_DEBUG_LOCK_ALLOC) && defined(CONFIG_PREEMPT_COUNT)
66/** 67/**
@@ -113,6 +114,17 @@ EXPORT_SYMBOL(rcu_read_lock_sched_held);
113 114
114#ifndef CONFIG_TINY_RCU 115#ifndef CONFIG_TINY_RCU
115 116
117/*
118 * Should expedited grace-period primitives always fall back to their
119 * non-expedited counterparts? Intended for use within RCU. Note
120 * that if the user specifies both rcu_expedited and rcu_normal, then
121 * rcu_normal wins.
122 */
123bool rcu_gp_is_normal(void)
124{
125 return READ_ONCE(rcu_normal);
126}
127
116static atomic_t rcu_expedited_nesting = 128static atomic_t rcu_expedited_nesting =
117 ATOMIC_INIT(IS_ENABLED(CONFIG_RCU_EXPEDITE_BOOT) ? 1 : 0); 129 ATOMIC_INIT(IS_ENABLED(CONFIG_RCU_EXPEDITE_BOOT) ? 1 : 0);
118 130