diff options
author | Ingo Molnar <mingo@kernel.org> | 2018-01-03 08:14:18 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2018-01-03 08:14:18 -0500 |
commit | 475c5ee193fd682c6383b5e418e65e46a477d176 (patch) | |
tree | 43f70a77d919e10237edbbbc3ca7ac8076d27410 | |
parent | 30a7acd573899fd8b8ac39236eff6468b195ac7d (diff) | |
parent | 1dfa55e01987288d847220b8c027204871440ed1 (diff) |
Merge branch 'for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu into core/rcu
Pull RCU updates from Paul E. McKenney:
- Updates to use cond_resched() instead of cond_resched_rcu_qs()
where feasible (currently everywhere except in kernel/rcu and
in kernel/torture.c). Also a couple of fixes to avoid sending
IPIs to offline CPUs.
- Updates to simplify RCU's dyntick-idle handling.
- Updates to remove almost all uses of smp_read_barrier_depends()
and read_barrier_depends().
- Miscellaneous fixes.
- Torture-test updates.
Signed-off-by: Ingo Molnar <mingo@kernel.org>
81 files changed, 501 insertions, 748 deletions
diff --git a/Documentation/RCU/Design/Data-Structures/Data-Structures.html b/Documentation/RCU/Design/Data-Structures/Data-Structures.html index 38d6d800761f..6c06e10bd04b 100644 --- a/Documentation/RCU/Design/Data-Structures/Data-Structures.html +++ b/Documentation/RCU/Design/Data-Structures/Data-Structures.html | |||
@@ -1097,7 +1097,8 @@ will cause the CPU to disregard the values of its counters on | |||
1097 | its next exit from idle. | 1097 | its next exit from idle. |
1098 | Finally, the <tt>rcu_qs_ctr_snap</tt> field is used to detect | 1098 | Finally, the <tt>rcu_qs_ctr_snap</tt> field is used to detect |
1099 | cases where a given operation has resulted in a quiescent state | 1099 | cases where a given operation has resulted in a quiescent state |
1100 | for all flavors of RCU, for example, <tt>cond_resched_rcu_qs()</tt>. | 1100 | for all flavors of RCU, for example, <tt>cond_resched()</tt> |
1101 | when RCU has indicated a need for quiescent states. | ||
1101 | 1102 | ||
1102 | <h5>RCU Callback Handling</h5> | 1103 | <h5>RCU Callback Handling</h5> |
1103 | 1104 | ||
@@ -1182,8 +1183,8 @@ CPU (and from tracing) unless otherwise stated. | |||
1182 | Its fields are as follows: | 1183 | Its fields are as follows: |
1183 | 1184 | ||
1184 | <pre> | 1185 | <pre> |
1185 | 1 int dynticks_nesting; | 1186 | 1 long dynticks_nesting; |
1186 | 2 int dynticks_nmi_nesting; | 1187 | 2 long dynticks_nmi_nesting; |
1187 | 3 atomic_t dynticks; | 1188 | 3 atomic_t dynticks; |
1188 | 4 bool rcu_need_heavy_qs; | 1189 | 4 bool rcu_need_heavy_qs; |
1189 | 5 unsigned long rcu_qs_ctr; | 1190 | 5 unsigned long rcu_qs_ctr; |
@@ -1191,15 +1192,31 @@ Its fields are as follows: | |||
1191 | </pre> | 1192 | </pre> |
1192 | 1193 | ||
1193 | <p>The <tt>->dynticks_nesting</tt> field counts the | 1194 | <p>The <tt>->dynticks_nesting</tt> field counts the |
1194 | nesting depth of normal interrupts. | 1195 | nesting depth of process execution, so that in normal circumstances |
1195 | In addition, this counter is incremented when exiting dyntick-idle | 1196 | this counter has value zero or one. |
1196 | mode and decremented when entering it. | 1197 | NMIs, irqs, and tracers are counted by the <tt>->dynticks_nmi_nesting</tt> |
1198 | field. | ||
1199 | Because NMIs cannot be masked, changes to this variable have to be | ||
1200 | undertaken carefully using an algorithm provided by Andy Lutomirski. | ||
1201 | The initial transition from idle adds one, and nested transitions | ||
1202 | add two, so that a nesting level of five is represented by a | ||
1203 | <tt>->dynticks_nmi_nesting</tt> value of nine. | ||
1197 | This counter can therefore be thought of as counting the number | 1204 | This counter can therefore be thought of as counting the number |
1198 | of reasons why this CPU cannot be permitted to enter dyntick-idle | 1205 | of reasons why this CPU cannot be permitted to enter dyntick-idle |
1199 | mode, aside from non-maskable interrupts (NMIs). | 1206 | mode, aside from process-level transitions. |
1200 | NMIs are counted by the <tt>->dynticks_nmi_nesting</tt> | 1207 | |
1201 | field, except that NMIs that interrupt non-dyntick-idle execution | 1208 | <p>However, it turns out that when running in non-idle kernel context, |
1202 | are not counted. | 1209 | the Linux kernel is fully capable of entering interrupt handlers that |
1210 | never exit and perhaps also vice versa. | ||
1211 | Therefore, whenever the <tt>->dynticks_nesting</tt> field is | ||
1212 | incremented up from zero, the <tt>->dynticks_nmi_nesting</tt> field | ||
1213 | is set to a large positive number, and whenever the | ||
1214 | <tt>->dynticks_nesting</tt> field is decremented down to zero, | ||
1215 | the the <tt>->dynticks_nmi_nesting</tt> field is set to zero. | ||
1216 | Assuming that the number of misnested interrupts is not sufficient | ||
1217 | to overflow the counter, this approach corrects the | ||
1218 | <tt>->dynticks_nmi_nesting</tt> field every time the corresponding | ||
1219 | CPU enters the idle loop from process context. | ||
1203 | 1220 | ||
1204 | </p><p>The <tt>->dynticks</tt> field counts the corresponding | 1221 | </p><p>The <tt>->dynticks</tt> field counts the corresponding |
1205 | CPU's transitions to and from dyntick-idle mode, so that this counter | 1222 | CPU's transitions to and from dyntick-idle mode, so that this counter |
@@ -1231,14 +1248,16 @@ in response. | |||
1231 | <tr><th> </th></tr> | 1248 | <tr><th> </th></tr> |
1232 | <tr><th align="left">Quick Quiz:</th></tr> | 1249 | <tr><th align="left">Quick Quiz:</th></tr> |
1233 | <tr><td> | 1250 | <tr><td> |
1234 | Why not just count all NMIs? | 1251 | Why not simply combine the <tt>->dynticks_nesting</tt> |
1235 | Wouldn't that be simpler and less error prone? | 1252 | and <tt>->dynticks_nmi_nesting</tt> counters into a |
1253 | single counter that just counts the number of reasons that | ||
1254 | the corresponding CPU is non-idle? | ||
1236 | </td></tr> | 1255 | </td></tr> |
1237 | <tr><th align="left">Answer:</th></tr> | 1256 | <tr><th align="left">Answer:</th></tr> |
1238 | <tr><td bgcolor="#ffffff"><font color="ffffff"> | 1257 | <tr><td bgcolor="#ffffff"><font color="ffffff"> |
1239 | It seems simpler only until you think hard about how to go about | 1258 | Because this would fail in the presence of interrupts whose |
1240 | updating the <tt>rcu_dynticks</tt> structure's | 1259 | handlers never return and of handlers that manage to return |
1241 | <tt>->dynticks</tt> field. | 1260 | from a made-up interrupt. |
1242 | </font></td></tr> | 1261 | </font></td></tr> |
1243 | <tr><td> </td></tr> | 1262 | <tr><td> </td></tr> |
1244 | </table> | 1263 | </table> |
diff --git a/Documentation/RCU/Design/Requirements/Requirements.html b/Documentation/RCU/Design/Requirements/Requirements.html index 62e847bcdcdd..49690228b1c6 100644 --- a/Documentation/RCU/Design/Requirements/Requirements.html +++ b/Documentation/RCU/Design/Requirements/Requirements.html | |||
@@ -581,7 +581,8 @@ This guarantee was only partially premeditated. | |||
581 | DYNIX/ptx used an explicit memory barrier for publication, but had nothing | 581 | DYNIX/ptx used an explicit memory barrier for publication, but had nothing |
582 | resembling <tt>rcu_dereference()</tt> for subscription, nor did it | 582 | resembling <tt>rcu_dereference()</tt> for subscription, nor did it |
583 | have anything resembling the <tt>smp_read_barrier_depends()</tt> | 583 | have anything resembling the <tt>smp_read_barrier_depends()</tt> |
584 | that was later subsumed into <tt>rcu_dereference()</tt>. | 584 | that was later subsumed into <tt>rcu_dereference()</tt> and later |
585 | still into <tt>READ_ONCE()</tt>. | ||
585 | The need for these operations made itself known quite suddenly at a | 586 | The need for these operations made itself known quite suddenly at a |
586 | late-1990s meeting with the DEC Alpha architects, back in the days when | 587 | late-1990s meeting with the DEC Alpha architects, back in the days when |
587 | DEC was still a free-standing company. | 588 | DEC was still a free-standing company. |
@@ -2797,7 +2798,7 @@ RCU must avoid degrading real-time response for CPU-bound threads, whether | |||
2797 | executing in usermode (which is one use case for | 2798 | executing in usermode (which is one use case for |
2798 | <tt>CONFIG_NO_HZ_FULL=y</tt>) or in the kernel. | 2799 | <tt>CONFIG_NO_HZ_FULL=y</tt>) or in the kernel. |
2799 | That said, CPU-bound loops in the kernel must execute | 2800 | That said, CPU-bound loops in the kernel must execute |
2800 | <tt>cond_resched_rcu_qs()</tt> at least once per few tens of milliseconds | 2801 | <tt>cond_resched()</tt> at least once per few tens of milliseconds |
2801 | in order to avoid receiving an IPI from RCU. | 2802 | in order to avoid receiving an IPI from RCU. |
2802 | 2803 | ||
2803 | <p> | 2804 | <p> |
@@ -3128,7 +3129,7 @@ The solution, in the form of | |||
3128 | is to have implicit | 3129 | is to have implicit |
3129 | read-side critical sections that are delimited by voluntary context | 3130 | read-side critical sections that are delimited by voluntary context |
3130 | switches, that is, calls to <tt>schedule()</tt>, | 3131 | switches, that is, calls to <tt>schedule()</tt>, |
3131 | <tt>cond_resched_rcu_qs()</tt>, and | 3132 | <tt>cond_resched()</tt>, and |
3132 | <tt>synchronize_rcu_tasks()</tt>. | 3133 | <tt>synchronize_rcu_tasks()</tt>. |
3133 | In addition, transitions to and from userspace execution also delimit | 3134 | In addition, transitions to and from userspace execution also delimit |
3134 | tasks-RCU read-side critical sections. | 3135 | tasks-RCU read-side critical sections. |
diff --git a/Documentation/RCU/rcu_dereference.txt b/Documentation/RCU/rcu_dereference.txt index 1acb26b09b48..ab96227bad42 100644 --- a/Documentation/RCU/rcu_dereference.txt +++ b/Documentation/RCU/rcu_dereference.txt | |||
@@ -122,11 +122,7 @@ o Be very careful about comparing pointers obtained from | |||
122 | Note that if checks for being within an RCU read-side | 122 | Note that if checks for being within an RCU read-side |
123 | critical section are not required and the pointer is never | 123 | critical section are not required and the pointer is never |
124 | dereferenced, rcu_access_pointer() should be used in place | 124 | dereferenced, rcu_access_pointer() should be used in place |
125 | of rcu_dereference(). The rcu_access_pointer() primitive | 125 | of rcu_dereference(). |
126 | does not require an enclosing read-side critical section, | ||
127 | and also omits the smp_read_barrier_depends() included in | ||
128 | rcu_dereference(), which in turn should provide a small | ||
129 | performance gain in some CPUs (e.g., the DEC Alpha). | ||
130 | 126 | ||
131 | o The comparison is against a pointer that references memory | 127 | o The comparison is against a pointer that references memory |
132 | that was initialized "a long time ago." The reason | 128 | that was initialized "a long time ago." The reason |
diff --git a/Documentation/RCU/stallwarn.txt b/Documentation/RCU/stallwarn.txt index a08f928c8557..4259f95c3261 100644 --- a/Documentation/RCU/stallwarn.txt +++ b/Documentation/RCU/stallwarn.txt | |||
@@ -23,12 +23,10 @@ o A CPU looping with preemption disabled. This condition can | |||
23 | o A CPU looping with bottom halves disabled. This condition can | 23 | o A CPU looping with bottom halves disabled. This condition can |
24 | result in RCU-sched and RCU-bh stalls. | 24 | result in RCU-sched and RCU-bh stalls. |
25 | 25 | ||
26 | o For !CONFIG_PREEMPT kernels, a CPU looping anywhere in the | 26 | o For !CONFIG_PREEMPT kernels, a CPU looping anywhere in the kernel |
27 | kernel without invoking schedule(). Note that cond_resched() | 27 | without invoking schedule(). If the looping in the kernel is |
28 | does not necessarily prevent RCU CPU stall warnings. Therefore, | 28 | really expected and desirable behavior, you might need to add |
29 | if the looping in the kernel is really expected and desirable | 29 | some calls to cond_resched(). |
30 | behavior, you might need to replace some of the cond_resched() | ||
31 | calls with calls to cond_resched_rcu_qs(). | ||
32 | 30 | ||
33 | o Booting Linux using a console connection that is too slow to | 31 | o Booting Linux using a console connection that is too slow to |
34 | keep up with the boot-time console-message rate. For example, | 32 | keep up with the boot-time console-message rate. For example, |
diff --git a/Documentation/RCU/whatisRCU.txt b/Documentation/RCU/whatisRCU.txt index df62466da4e0..a27fbfb0efb8 100644 --- a/Documentation/RCU/whatisRCU.txt +++ b/Documentation/RCU/whatisRCU.txt | |||
@@ -600,8 +600,7 @@ don't forget about them when submitting patches making use of RCU!] | |||
600 | 600 | ||
601 | #define rcu_dereference(p) \ | 601 | #define rcu_dereference(p) \ |
602 | ({ \ | 602 | ({ \ |
603 | typeof(p) _________p1 = p; \ | 603 | typeof(p) _________p1 = READ_ONCE(p); \ |
604 | smp_read_barrier_depends(); \ | ||
605 | (_________p1); \ | 604 | (_________p1); \ |
606 | }) | 605 | }) |
607 | 606 | ||
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index af7104aaffd9..5e486b6509e5 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt | |||
@@ -2053,9 +2053,6 @@ | |||
2053 | This tests the locking primitive's ability to | 2053 | This tests the locking primitive's ability to |
2054 | transition abruptly to and from idle. | 2054 | transition abruptly to and from idle. |
2055 | 2055 | ||
2056 | locktorture.torture_runnable= [BOOT] | ||
2057 | Start locktorture running at boot time. | ||
2058 | |||
2059 | locktorture.torture_type= [KNL] | 2056 | locktorture.torture_type= [KNL] |
2060 | Specify the locking implementation to test. | 2057 | Specify the locking implementation to test. |
2061 | 2058 | ||
@@ -3471,9 +3468,6 @@ | |||
3471 | the same as for rcuperf.nreaders. | 3468 | the same as for rcuperf.nreaders. |
3472 | N, where N is the number of CPUs | 3469 | N, where N is the number of CPUs |
3473 | 3470 | ||
3474 | rcuperf.perf_runnable= [BOOT] | ||
3475 | Start rcuperf running at boot time. | ||
3476 | |||
3477 | rcuperf.perf_type= [KNL] | 3471 | rcuperf.perf_type= [KNL] |
3478 | Specify the RCU implementation to test. | 3472 | Specify the RCU implementation to test. |
3479 | 3473 | ||
@@ -3607,9 +3601,6 @@ | |||
3607 | Test RCU's dyntick-idle handling. See also the | 3601 | Test RCU's dyntick-idle handling. See also the |
3608 | rcutorture.shuffle_interval parameter. | 3602 | rcutorture.shuffle_interval parameter. |
3609 | 3603 | ||
3610 | rcutorture.torture_runnable= [BOOT] | ||
3611 | Start rcutorture running at boot time. | ||
3612 | |||
3613 | rcutorture.torture_type= [KNL] | 3604 | rcutorture.torture_type= [KNL] |
3614 | Specify the RCU implementation to test. | 3605 | Specify the RCU implementation to test. |
3615 | 3606 | ||
diff --git a/Documentation/circular-buffers.txt b/Documentation/circular-buffers.txt index d4628174b7c5..53e51caa3347 100644 --- a/Documentation/circular-buffers.txt +++ b/Documentation/circular-buffers.txt | |||
@@ -220,8 +220,7 @@ before it writes the new tail pointer, which will erase the item. | |||
220 | 220 | ||
221 | Note the use of READ_ONCE() and smp_load_acquire() to read the | 221 | Note the use of READ_ONCE() and smp_load_acquire() to read the |
222 | opposition index. This prevents the compiler from discarding and | 222 | opposition index. This prevents the compiler from discarding and |
223 | reloading its cached value - which some compilers will do across | 223 | reloading its cached value. This isn't strictly needed if you can |
224 | smp_read_barrier_depends(). This isn't strictly needed if you can | ||
225 | be sure that the opposition index will _only_ be used the once. | 224 | be sure that the opposition index will _only_ be used the once. |
226 | The smp_load_acquire() additionally forces the CPU to order against | 225 | The smp_load_acquire() additionally forces the CPU to order against |
227 | subsequent memory references. Similarly, smp_store_release() is used | 226 | subsequent memory references. Similarly, smp_store_release() is used |
diff --git a/Documentation/locking/locktorture.txt b/Documentation/locking/locktorture.txt index a2ef3a929bf1..6a8df4cd19bf 100644 --- a/Documentation/locking/locktorture.txt +++ b/Documentation/locking/locktorture.txt | |||
@@ -57,11 +57,6 @@ torture_type Type of lock to torture. By default, only spinlocks will | |||
57 | 57 | ||
58 | o "rwsem_lock": read/write down() and up() semaphore pairs. | 58 | o "rwsem_lock": read/write down() and up() semaphore pairs. |
59 | 59 | ||
60 | torture_runnable Start locktorture at boot time in the case where the | ||
61 | module is built into the kernel, otherwise wait for | ||
62 | torture_runnable to be set via sysfs before starting. | ||
63 | By default it will begin once the module is loaded. | ||
64 | |||
65 | 60 | ||
66 | ** Torture-framework (RCU + locking) ** | 61 | ** Torture-framework (RCU + locking) ** |
67 | 62 | ||
diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt index 479ecec80593..a863009849a3 100644 --- a/Documentation/memory-barriers.txt +++ b/Documentation/memory-barriers.txt | |||
@@ -227,17 +227,20 @@ There are some minimal guarantees that may be expected of a CPU: | |||
227 | (*) On any given CPU, dependent memory accesses will be issued in order, with | 227 | (*) On any given CPU, dependent memory accesses will be issued in order, with |
228 | respect to itself. This means that for: | 228 | respect to itself. This means that for: |
229 | 229 | ||
230 | Q = READ_ONCE(P); smp_read_barrier_depends(); D = READ_ONCE(*Q); | 230 | Q = READ_ONCE(P); D = READ_ONCE(*Q); |
231 | 231 | ||
232 | the CPU will issue the following memory operations: | 232 | the CPU will issue the following memory operations: |
233 | 233 | ||
234 | Q = LOAD P, D = LOAD *Q | 234 | Q = LOAD P, D = LOAD *Q |
235 | 235 | ||
236 | and always in that order. On most systems, smp_read_barrier_depends() | 236 | and always in that order. However, on DEC Alpha, READ_ONCE() also |
237 | does nothing, but it is required for DEC Alpha. The READ_ONCE() | 237 | emits a memory-barrier instruction, so that a DEC Alpha CPU will |
238 | is required to prevent compiler mischief. Please note that you | 238 | instead issue the following memory operations: |
239 | should normally use something like rcu_dereference() instead of | 239 | |
240 | open-coding smp_read_barrier_depends(). | 240 | Q = LOAD P, MEMORY_BARRIER, D = LOAD *Q, MEMORY_BARRIER |
241 | |||
242 | Whether on DEC Alpha or not, the READ_ONCE() also prevents compiler | ||
243 | mischief. | ||
241 | 244 | ||
242 | (*) Overlapping loads and stores within a particular CPU will appear to be | 245 | (*) Overlapping loads and stores within a particular CPU will appear to be |
243 | ordered within that CPU. This means that for: | 246 | ordered within that CPU. This means that for: |
@@ -1815,7 +1818,7 @@ The Linux kernel has eight basic CPU memory barriers: | |||
1815 | GENERAL mb() smp_mb() | 1818 | GENERAL mb() smp_mb() |
1816 | WRITE wmb() smp_wmb() | 1819 | WRITE wmb() smp_wmb() |
1817 | READ rmb() smp_rmb() | 1820 | READ rmb() smp_rmb() |
1818 | DATA DEPENDENCY read_barrier_depends() smp_read_barrier_depends() | 1821 | DATA DEPENDENCY READ_ONCE() |
1819 | 1822 | ||
1820 | 1823 | ||
1821 | All memory barriers except the data dependency barriers imply a compiler | 1824 | All memory barriers except the data dependency barriers imply a compiler |
@@ -2864,7 +2867,10 @@ access depends on a read, not all do, so it may not be relied on. | |||
2864 | 2867 | ||
2865 | Other CPUs may also have split caches, but must coordinate between the various | 2868 | Other CPUs may also have split caches, but must coordinate between the various |
2866 | cachelets for normal memory accesses. The semantics of the Alpha removes the | 2869 | cachelets for normal memory accesses. The semantics of the Alpha removes the |
2867 | need for coordination in the absence of memory barriers. | 2870 | need for hardware coordination in the absence of memory barriers, which |
2871 | permitted Alpha to sport higher CPU clock rates back in the day. However, | ||
2872 | please note that smp_read_barrier_depends() should not be used except in | ||
2873 | Alpha arch-specific code and within the READ_ONCE() macro. | ||
2868 | 2874 | ||
2869 | 2875 | ||
2870 | CACHE COHERENCY VS DMA | 2876 | CACHE COHERENCY VS DMA |
diff --git a/MAINTAINERS b/MAINTAINERS index b46c9cea5ae5..f12475919bef 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -8193,6 +8193,7 @@ F: arch/*/include/asm/rwsem.h | |||
8193 | F: include/linux/seqlock.h | 8193 | F: include/linux/seqlock.h |
8194 | F: lib/locking*.[ch] | 8194 | F: lib/locking*.[ch] |
8195 | F: kernel/locking/ | 8195 | F: kernel/locking/ |
8196 | X: kernel/locking/locktorture.c | ||
8196 | 8197 | ||
8197 | LOGICAL DISK MANAGER SUPPORT (LDM, Windows 2000/XP/Vista Dynamic Disks) | 8198 | LOGICAL DISK MANAGER SUPPORT (LDM, Windows 2000/XP/Vista Dynamic Disks) |
8198 | M: "Richard Russon (FlatCap)" <ldm@flatcap.org> | 8199 | M: "Richard Russon (FlatCap)" <ldm@flatcap.org> |
@@ -11450,15 +11451,6 @@ L: linux-wireless@vger.kernel.org | |||
11450 | S: Orphan | 11451 | S: Orphan |
11451 | F: drivers/net/wireless/ray* | 11452 | F: drivers/net/wireless/ray* |
11452 | 11453 | ||
11453 | RCUTORTURE MODULE | ||
11454 | M: Josh Triplett <josh@joshtriplett.org> | ||
11455 | M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> | ||
11456 | L: linux-kernel@vger.kernel.org | ||
11457 | S: Supported | ||
11458 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git | ||
11459 | F: Documentation/RCU/torture.txt | ||
11460 | F: kernel/rcu/rcutorture.c | ||
11461 | |||
11462 | RCUTORTURE TEST FRAMEWORK | 11454 | RCUTORTURE TEST FRAMEWORK |
11463 | M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> | 11455 | M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> |
11464 | M: Josh Triplett <josh@joshtriplett.org> | 11456 | M: Josh Triplett <josh@joshtriplett.org> |
@@ -13767,6 +13759,18 @@ L: platform-driver-x86@vger.kernel.org | |||
13767 | S: Maintained | 13759 | S: Maintained |
13768 | F: drivers/platform/x86/topstar-laptop.c | 13760 | F: drivers/platform/x86/topstar-laptop.c |
13769 | 13761 | ||
13762 | TORTURE-TEST MODULES | ||
13763 | M: Davidlohr Bueso <dave@stgolabs.net> | ||
13764 | M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> | ||
13765 | M: Josh Triplett <josh@joshtriplett.org> | ||
13766 | L: linux-kernel@vger.kernel.org | ||
13767 | S: Supported | ||
13768 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git | ||
13769 | F: Documentation/RCU/torture.txt | ||
13770 | F: kernel/torture.c | ||
13771 | F: kernel/rcu/rcutorture.c | ||
13772 | F: kernel/locking/locktorture.c | ||
13773 | |||
13770 | TOSHIBA ACPI EXTRAS DRIVER | 13774 | TOSHIBA ACPI EXTRAS DRIVER |
13771 | M: Azael Avalos <coproscefalo@gmail.com> | 13775 | M: Azael Avalos <coproscefalo@gmail.com> |
13772 | L: platform-driver-x86@vger.kernel.org | 13776 | L: platform-driver-x86@vger.kernel.org |
diff --git a/arch/mn10300/kernel/mn10300-serial.c b/arch/mn10300/kernel/mn10300-serial.c index d7ef1232a82a..4994b570dfd9 100644 --- a/arch/mn10300/kernel/mn10300-serial.c +++ b/arch/mn10300/kernel/mn10300-serial.c | |||
@@ -550,7 +550,7 @@ try_again: | |||
550 | return; | 550 | return; |
551 | } | 551 | } |
552 | 552 | ||
553 | smp_read_barrier_depends(); | 553 | /* READ_ONCE() enforces dependency, but dangerous through integer!!! */ |
554 | ch = port->rx_buffer[ix++]; | 554 | ch = port->rx_buffer[ix++]; |
555 | st = port->rx_buffer[ix++]; | 555 | st = port->rx_buffer[ix++]; |
556 | smp_mb(); | 556 | smp_mb(); |
@@ -1728,7 +1728,10 @@ static int mn10300_serial_poll_get_char(struct uart_port *_port) | |||
1728 | if (CIRC_CNT(port->rx_inp, ix, MNSC_BUFFER_SIZE) == 0) | 1728 | if (CIRC_CNT(port->rx_inp, ix, MNSC_BUFFER_SIZE) == 0) |
1729 | return NO_POLL_CHAR; | 1729 | return NO_POLL_CHAR; |
1730 | 1730 | ||
1731 | smp_read_barrier_depends(); | 1731 | /* |
1732 | * READ_ONCE() enforces dependency, but dangerous | ||
1733 | * through integer!!! | ||
1734 | */ | ||
1732 | ch = port->rx_buffer[ix++]; | 1735 | ch = port->rx_buffer[ix++]; |
1733 | st = port->rx_buffer[ix++]; | 1736 | st = port->rx_buffer[ix++]; |
1734 | smp_mb(); | 1737 | smp_mb(); |
diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c index 58d4ccd33672..8b5b23a8ace9 100644 --- a/drivers/dma/ioat/dma.c +++ b/drivers/dma/ioat/dma.c | |||
@@ -597,7 +597,6 @@ static void __cleanup(struct ioatdma_chan *ioat_chan, dma_addr_t phys_complete) | |||
597 | for (i = 0; i < active && !seen_current; i++) { | 597 | for (i = 0; i < active && !seen_current; i++) { |
598 | struct dma_async_tx_descriptor *tx; | 598 | struct dma_async_tx_descriptor *tx; |
599 | 599 | ||
600 | smp_read_barrier_depends(); | ||
601 | prefetch(ioat_get_ring_ent(ioat_chan, idx + i + 1)); | 600 | prefetch(ioat_get_ring_ent(ioat_chan, idx + i + 1)); |
602 | desc = ioat_get_ring_ent(ioat_chan, idx + i); | 601 | desc = ioat_get_ring_ent(ioat_chan, idx + i); |
603 | dump_desc_dbg(ioat_chan, desc); | 602 | dump_desc_dbg(ioat_chan, desc); |
@@ -715,7 +714,6 @@ static void ioat_abort_descs(struct ioatdma_chan *ioat_chan) | |||
715 | for (i = 1; i < active; i++) { | 714 | for (i = 1; i < active; i++) { |
716 | struct dma_async_tx_descriptor *tx; | 715 | struct dma_async_tx_descriptor *tx; |
717 | 716 | ||
718 | smp_read_barrier_depends(); | ||
719 | prefetch(ioat_get_ring_ent(ioat_chan, idx + i + 1)); | 717 | prefetch(ioat_get_ring_ent(ioat_chan, idx + i + 1)); |
720 | desc = ioat_get_ring_ent(ioat_chan, idx + i); | 718 | desc = ioat_get_ring_ent(ioat_chan, idx + i); |
721 | 719 | ||
diff --git a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig index cbf186522016..5cd700421695 100644 --- a/drivers/infiniband/Kconfig +++ b/drivers/infiniband/Kconfig | |||
@@ -4,6 +4,7 @@ menuconfig INFINIBAND | |||
4 | depends on NET | 4 | depends on NET |
5 | depends on INET | 5 | depends on INET |
6 | depends on m || IPV6 != m | 6 | depends on m || IPV6 != m |
7 | depends on !ALPHA | ||
7 | select IRQ_POLL | 8 | select IRQ_POLL |
8 | ---help--- | 9 | ---help--- |
9 | Core support for InfiniBand (IB). Make sure to also select | 10 | Core support for InfiniBand (IB). Make sure to also select |
diff --git a/drivers/infiniband/hw/hfi1/rc.c b/drivers/infiniband/hw/hfi1/rc.c index af5f7936f7e5..7eb5d50578ba 100644 --- a/drivers/infiniband/hw/hfi1/rc.c +++ b/drivers/infiniband/hw/hfi1/rc.c | |||
@@ -302,7 +302,6 @@ int hfi1_make_rc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps) | |||
302 | if (!(ib_rvt_state_ops[qp->state] & RVT_FLUSH_SEND)) | 302 | if (!(ib_rvt_state_ops[qp->state] & RVT_FLUSH_SEND)) |
303 | goto bail; | 303 | goto bail; |
304 | /* We are in the error state, flush the work request. */ | 304 | /* We are in the error state, flush the work request. */ |
305 | smp_read_barrier_depends(); /* see post_one_send() */ | ||
306 | if (qp->s_last == READ_ONCE(qp->s_head)) | 305 | if (qp->s_last == READ_ONCE(qp->s_head)) |
307 | goto bail; | 306 | goto bail; |
308 | /* If DMAs are in progress, we can't flush immediately. */ | 307 | /* If DMAs are in progress, we can't flush immediately. */ |
@@ -346,7 +345,6 @@ int hfi1_make_rc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps) | |||
346 | newreq = 0; | 345 | newreq = 0; |
347 | if (qp->s_cur == qp->s_tail) { | 346 | if (qp->s_cur == qp->s_tail) { |
348 | /* Check if send work queue is empty. */ | 347 | /* Check if send work queue is empty. */ |
349 | smp_read_barrier_depends(); /* see post_one_send() */ | ||
350 | if (qp->s_tail == READ_ONCE(qp->s_head)) { | 348 | if (qp->s_tail == READ_ONCE(qp->s_head)) { |
351 | clear_ahg(qp); | 349 | clear_ahg(qp); |
352 | goto bail; | 350 | goto bail; |
@@ -900,7 +898,6 @@ void hfi1_send_rc_ack(struct hfi1_ctxtdata *rcd, | |||
900 | } | 898 | } |
901 | 899 | ||
902 | /* Ensure s_rdma_ack_cnt changes are committed */ | 900 | /* Ensure s_rdma_ack_cnt changes are committed */ |
903 | smp_read_barrier_depends(); | ||
904 | if (qp->s_rdma_ack_cnt) { | 901 | if (qp->s_rdma_ack_cnt) { |
905 | hfi1_queue_rc_ack(qp, is_fecn); | 902 | hfi1_queue_rc_ack(qp, is_fecn); |
906 | return; | 903 | return; |
@@ -1562,7 +1559,6 @@ static void rc_rcv_resp(struct hfi1_packet *packet) | |||
1562 | trace_hfi1_ack(qp, psn); | 1559 | trace_hfi1_ack(qp, psn); |
1563 | 1560 | ||
1564 | /* Ignore invalid responses. */ | 1561 | /* Ignore invalid responses. */ |
1565 | smp_read_barrier_depends(); /* see post_one_send */ | ||
1566 | if (cmp_psn(psn, READ_ONCE(qp->s_next_psn)) >= 0) | 1562 | if (cmp_psn(psn, READ_ONCE(qp->s_next_psn)) >= 0) |
1567 | goto ack_done; | 1563 | goto ack_done; |
1568 | 1564 | ||
diff --git a/drivers/infiniband/hw/hfi1/ruc.c b/drivers/infiniband/hw/hfi1/ruc.c index 2c7fc6e331ea..13b994738f41 100644 --- a/drivers/infiniband/hw/hfi1/ruc.c +++ b/drivers/infiniband/hw/hfi1/ruc.c | |||
@@ -362,7 +362,6 @@ static void ruc_loopback(struct rvt_qp *sqp) | |||
362 | sqp->s_flags |= RVT_S_BUSY; | 362 | sqp->s_flags |= RVT_S_BUSY; |
363 | 363 | ||
364 | again: | 364 | again: |
365 | smp_read_barrier_depends(); /* see post_one_send() */ | ||
366 | if (sqp->s_last == READ_ONCE(sqp->s_head)) | 365 | if (sqp->s_last == READ_ONCE(sqp->s_head)) |
367 | goto clr_busy; | 366 | goto clr_busy; |
368 | wqe = rvt_get_swqe_ptr(sqp, sqp->s_last); | 367 | wqe = rvt_get_swqe_ptr(sqp, sqp->s_last); |
diff --git a/drivers/infiniband/hw/hfi1/sdma.c b/drivers/infiniband/hw/hfi1/sdma.c index 31c8f89b5fc8..61c130dbed10 100644 --- a/drivers/infiniband/hw/hfi1/sdma.c +++ b/drivers/infiniband/hw/hfi1/sdma.c | |||
@@ -553,7 +553,6 @@ static void sdma_hw_clean_up_task(unsigned long opaque) | |||
553 | 553 | ||
554 | static inline struct sdma_txreq *get_txhead(struct sdma_engine *sde) | 554 | static inline struct sdma_txreq *get_txhead(struct sdma_engine *sde) |
555 | { | 555 | { |
556 | smp_read_barrier_depends(); /* see sdma_update_tail() */ | ||
557 | return sde->tx_ring[sde->tx_head & sde->sdma_mask]; | 556 | return sde->tx_ring[sde->tx_head & sde->sdma_mask]; |
558 | } | 557 | } |
559 | 558 | ||
diff --git a/drivers/infiniband/hw/hfi1/uc.c b/drivers/infiniband/hw/hfi1/uc.c index 991bbee04821..132b63e787d1 100644 --- a/drivers/infiniband/hw/hfi1/uc.c +++ b/drivers/infiniband/hw/hfi1/uc.c | |||
@@ -79,7 +79,6 @@ int hfi1_make_uc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps) | |||
79 | if (!(ib_rvt_state_ops[qp->state] & RVT_FLUSH_SEND)) | 79 | if (!(ib_rvt_state_ops[qp->state] & RVT_FLUSH_SEND)) |
80 | goto bail; | 80 | goto bail; |
81 | /* We are in the error state, flush the work request. */ | 81 | /* We are in the error state, flush the work request. */ |
82 | smp_read_barrier_depends(); /* see post_one_send() */ | ||
83 | if (qp->s_last == READ_ONCE(qp->s_head)) | 82 | if (qp->s_last == READ_ONCE(qp->s_head)) |
84 | goto bail; | 83 | goto bail; |
85 | /* If DMAs are in progress, we can't flush immediately. */ | 84 | /* If DMAs are in progress, we can't flush immediately. */ |
@@ -119,7 +118,6 @@ int hfi1_make_uc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps) | |||
119 | RVT_PROCESS_NEXT_SEND_OK)) | 118 | RVT_PROCESS_NEXT_SEND_OK)) |
120 | goto bail; | 119 | goto bail; |
121 | /* Check if send work queue is empty. */ | 120 | /* Check if send work queue is empty. */ |
122 | smp_read_barrier_depends(); /* see post_one_send() */ | ||
123 | if (qp->s_cur == READ_ONCE(qp->s_head)) { | 121 | if (qp->s_cur == READ_ONCE(qp->s_head)) { |
124 | clear_ahg(qp); | 122 | clear_ahg(qp); |
125 | goto bail; | 123 | goto bail; |
diff --git a/drivers/infiniband/hw/hfi1/ud.c b/drivers/infiniband/hw/hfi1/ud.c index beb5091eccca..deb184574395 100644 --- a/drivers/infiniband/hw/hfi1/ud.c +++ b/drivers/infiniband/hw/hfi1/ud.c | |||
@@ -486,7 +486,6 @@ int hfi1_make_ud_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps) | |||
486 | if (!(ib_rvt_state_ops[qp->state] & RVT_FLUSH_SEND)) | 486 | if (!(ib_rvt_state_ops[qp->state] & RVT_FLUSH_SEND)) |
487 | goto bail; | 487 | goto bail; |
488 | /* We are in the error state, flush the work request. */ | 488 | /* We are in the error state, flush the work request. */ |
489 | smp_read_barrier_depends(); /* see post_one_send */ | ||
490 | if (qp->s_last == READ_ONCE(qp->s_head)) | 489 | if (qp->s_last == READ_ONCE(qp->s_head)) |
491 | goto bail; | 490 | goto bail; |
492 | /* If DMAs are in progress, we can't flush immediately. */ | 491 | /* If DMAs are in progress, we can't flush immediately. */ |
@@ -500,7 +499,6 @@ int hfi1_make_ud_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps) | |||
500 | } | 499 | } |
501 | 500 | ||
502 | /* see post_one_send() */ | 501 | /* see post_one_send() */ |
503 | smp_read_barrier_depends(); | ||
504 | if (qp->s_cur == READ_ONCE(qp->s_head)) | 502 | if (qp->s_cur == READ_ONCE(qp->s_head)) |
505 | goto bail; | 503 | goto bail; |
506 | 504 | ||
diff --git a/drivers/infiniband/hw/qib/qib_rc.c b/drivers/infiniband/hw/qib/qib_rc.c index 8f5754fb8579..1a785c37ad0a 100644 --- a/drivers/infiniband/hw/qib/qib_rc.c +++ b/drivers/infiniband/hw/qib/qib_rc.c | |||
@@ -246,7 +246,6 @@ int qib_make_rc_req(struct rvt_qp *qp, unsigned long *flags) | |||
246 | if (!(ib_rvt_state_ops[qp->state] & RVT_FLUSH_SEND)) | 246 | if (!(ib_rvt_state_ops[qp->state] & RVT_FLUSH_SEND)) |
247 | goto bail; | 247 | goto bail; |
248 | /* We are in the error state, flush the work request. */ | 248 | /* We are in the error state, flush the work request. */ |
249 | smp_read_barrier_depends(); /* see post_one_send() */ | ||
250 | if (qp->s_last == READ_ONCE(qp->s_head)) | 249 | if (qp->s_last == READ_ONCE(qp->s_head)) |
251 | goto bail; | 250 | goto bail; |
252 | /* If DMAs are in progress, we can't flush immediately. */ | 251 | /* If DMAs are in progress, we can't flush immediately. */ |
@@ -293,7 +292,6 @@ int qib_make_rc_req(struct rvt_qp *qp, unsigned long *flags) | |||
293 | newreq = 0; | 292 | newreq = 0; |
294 | if (qp->s_cur == qp->s_tail) { | 293 | if (qp->s_cur == qp->s_tail) { |
295 | /* Check if send work queue is empty. */ | 294 | /* Check if send work queue is empty. */ |
296 | smp_read_barrier_depends(); /* see post_one_send() */ | ||
297 | if (qp->s_tail == READ_ONCE(qp->s_head)) | 295 | if (qp->s_tail == READ_ONCE(qp->s_head)) |
298 | goto bail; | 296 | goto bail; |
299 | /* | 297 | /* |
@@ -1340,7 +1338,6 @@ static void qib_rc_rcv_resp(struct qib_ibport *ibp, | |||
1340 | goto ack_done; | 1338 | goto ack_done; |
1341 | 1339 | ||
1342 | /* Ignore invalid responses. */ | 1340 | /* Ignore invalid responses. */ |
1343 | smp_read_barrier_depends(); /* see post_one_send */ | ||
1344 | if (qib_cmp24(psn, READ_ONCE(qp->s_next_psn)) >= 0) | 1341 | if (qib_cmp24(psn, READ_ONCE(qp->s_next_psn)) >= 0) |
1345 | goto ack_done; | 1342 | goto ack_done; |
1346 | 1343 | ||
diff --git a/drivers/infiniband/hw/qib/qib_ruc.c b/drivers/infiniband/hw/qib/qib_ruc.c index 9a37e844d4c8..4662cc7bde92 100644 --- a/drivers/infiniband/hw/qib/qib_ruc.c +++ b/drivers/infiniband/hw/qib/qib_ruc.c | |||
@@ -367,7 +367,6 @@ static void qib_ruc_loopback(struct rvt_qp *sqp) | |||
367 | sqp->s_flags |= RVT_S_BUSY; | 367 | sqp->s_flags |= RVT_S_BUSY; |
368 | 368 | ||
369 | again: | 369 | again: |
370 | smp_read_barrier_depends(); /* see post_one_send() */ | ||
371 | if (sqp->s_last == READ_ONCE(sqp->s_head)) | 370 | if (sqp->s_last == READ_ONCE(sqp->s_head)) |
372 | goto clr_busy; | 371 | goto clr_busy; |
373 | wqe = rvt_get_swqe_ptr(sqp, sqp->s_last); | 372 | wqe = rvt_get_swqe_ptr(sqp, sqp->s_last); |
diff --git a/drivers/infiniband/hw/qib/qib_uc.c b/drivers/infiniband/hw/qib/qib_uc.c index bddcc37ace44..70c58b88192c 100644 --- a/drivers/infiniband/hw/qib/qib_uc.c +++ b/drivers/infiniband/hw/qib/qib_uc.c | |||
@@ -60,7 +60,6 @@ int qib_make_uc_req(struct rvt_qp *qp, unsigned long *flags) | |||
60 | if (!(ib_rvt_state_ops[qp->state] & RVT_FLUSH_SEND)) | 60 | if (!(ib_rvt_state_ops[qp->state] & RVT_FLUSH_SEND)) |
61 | goto bail; | 61 | goto bail; |
62 | /* We are in the error state, flush the work request. */ | 62 | /* We are in the error state, flush the work request. */ |
63 | smp_read_barrier_depends(); /* see post_one_send() */ | ||
64 | if (qp->s_last == READ_ONCE(qp->s_head)) | 63 | if (qp->s_last == READ_ONCE(qp->s_head)) |
65 | goto bail; | 64 | goto bail; |
66 | /* If DMAs are in progress, we can't flush immediately. */ | 65 | /* If DMAs are in progress, we can't flush immediately. */ |
@@ -90,7 +89,6 @@ int qib_make_uc_req(struct rvt_qp *qp, unsigned long *flags) | |||
90 | RVT_PROCESS_NEXT_SEND_OK)) | 89 | RVT_PROCESS_NEXT_SEND_OK)) |
91 | goto bail; | 90 | goto bail; |
92 | /* Check if send work queue is empty. */ | 91 | /* Check if send work queue is empty. */ |
93 | smp_read_barrier_depends(); /* see post_one_send() */ | ||
94 | if (qp->s_cur == READ_ONCE(qp->s_head)) | 92 | if (qp->s_cur == READ_ONCE(qp->s_head)) |
95 | goto bail; | 93 | goto bail; |
96 | /* | 94 | /* |
diff --git a/drivers/infiniband/hw/qib/qib_ud.c b/drivers/infiniband/hw/qib/qib_ud.c index 15962ed193ce..386c3c4da0c7 100644 --- a/drivers/infiniband/hw/qib/qib_ud.c +++ b/drivers/infiniband/hw/qib/qib_ud.c | |||
@@ -252,7 +252,6 @@ int qib_make_ud_req(struct rvt_qp *qp, unsigned long *flags) | |||
252 | if (!(ib_rvt_state_ops[qp->state] & RVT_FLUSH_SEND)) | 252 | if (!(ib_rvt_state_ops[qp->state] & RVT_FLUSH_SEND)) |
253 | goto bail; | 253 | goto bail; |
254 | /* We are in the error state, flush the work request. */ | 254 | /* We are in the error state, flush the work request. */ |
255 | smp_read_barrier_depends(); /* see post_one_send */ | ||
256 | if (qp->s_last == READ_ONCE(qp->s_head)) | 255 | if (qp->s_last == READ_ONCE(qp->s_head)) |
257 | goto bail; | 256 | goto bail; |
258 | /* If DMAs are in progress, we can't flush immediately. */ | 257 | /* If DMAs are in progress, we can't flush immediately. */ |
@@ -266,7 +265,6 @@ int qib_make_ud_req(struct rvt_qp *qp, unsigned long *flags) | |||
266 | } | 265 | } |
267 | 266 | ||
268 | /* see post_one_send() */ | 267 | /* see post_one_send() */ |
269 | smp_read_barrier_depends(); | ||
270 | if (qp->s_cur == READ_ONCE(qp->s_head)) | 268 | if (qp->s_cur == READ_ONCE(qp->s_head)) |
271 | goto bail; | 269 | goto bail; |
272 | 270 | ||
diff --git a/drivers/infiniband/sw/rdmavt/qp.c b/drivers/infiniband/sw/rdmavt/qp.c index 9177df60742a..eae84c216e2f 100644 --- a/drivers/infiniband/sw/rdmavt/qp.c +++ b/drivers/infiniband/sw/rdmavt/qp.c | |||
@@ -1684,7 +1684,6 @@ static inline int rvt_qp_is_avail( | |||
1684 | /* non-reserved operations */ | 1684 | /* non-reserved operations */ |
1685 | if (likely(qp->s_avail)) | 1685 | if (likely(qp->s_avail)) |
1686 | return 0; | 1686 | return 0; |
1687 | smp_read_barrier_depends(); /* see rc.c */ | ||
1688 | slast = READ_ONCE(qp->s_last); | 1687 | slast = READ_ONCE(qp->s_last); |
1689 | if (qp->s_head >= slast) | 1688 | if (qp->s_head >= slast) |
1690 | avail = qp->s_size - (qp->s_head - slast); | 1689 | avail = qp->s_size - (qp->s_head - slast); |
diff --git a/drivers/net/ethernet/qlogic/qed/qed_spq.c b/drivers/net/ethernet/qlogic/qed/qed_spq.c index be48d9abd001..c1237ec58b6c 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_spq.c +++ b/drivers/net/ethernet/qlogic/qed/qed_spq.c | |||
@@ -97,9 +97,7 @@ static int __qed_spq_block(struct qed_hwfn *p_hwfn, | |||
97 | 97 | ||
98 | while (iter_cnt--) { | 98 | while (iter_cnt--) { |
99 | /* Validate we receive completion update */ | 99 | /* Validate we receive completion update */ |
100 | if (READ_ONCE(comp_done->done) == 1) { | 100 | if (smp_load_acquire(&comp_done->done) == 1) { /* ^^^ */ |
101 | /* Read updated FW return value */ | ||
102 | smp_read_barrier_depends(); | ||
103 | if (p_fw_ret) | 101 | if (p_fw_ret) |
104 | *p_fw_ret = comp_done->fw_return_code; | 102 | *p_fw_ret = comp_done->fw_return_code; |
105 | return 0; | 103 | return 0; |
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 33ac2b186b85..78b5940a415a 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c | |||
@@ -1877,12 +1877,7 @@ static unsigned next_desc(struct vhost_virtqueue *vq, struct vring_desc *desc) | |||
1877 | return -1U; | 1877 | return -1U; |
1878 | 1878 | ||
1879 | /* Check they're not leading us off end of descriptors. */ | 1879 | /* Check they're not leading us off end of descriptors. */ |
1880 | next = vhost16_to_cpu(vq, desc->next); | 1880 | next = vhost16_to_cpu(vq, READ_ONCE(desc->next)); |
1881 | /* Make sure compiler knows to grab that: we don't want it changing! */ | ||
1882 | /* We will use the result as an index in an array, so most | ||
1883 | * architectures only need a compiler barrier here. */ | ||
1884 | read_barrier_depends(); | ||
1885 | |||
1886 | return next; | 1881 | return next; |
1887 | } | 1882 | } |
1888 | 1883 | ||
diff --git a/fs/dcache.c b/fs/dcache.c index 5c7df1df81ff..379dce86f001 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -1636,8 +1636,7 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name) | |||
1636 | dname[name->len] = 0; | 1636 | dname[name->len] = 0; |
1637 | 1637 | ||
1638 | /* Make sure we always see the terminating NUL character */ | 1638 | /* Make sure we always see the terminating NUL character */ |
1639 | smp_wmb(); | 1639 | smp_store_release(&dentry->d_name.name, dname); /* ^^^ */ |
1640 | dentry->d_name.name = dname; | ||
1641 | 1640 | ||
1642 | dentry->d_lockref.count = 1; | 1641 | dentry->d_lockref.count = 1; |
1643 | dentry->d_flags = 0; | 1642 | dentry->d_flags = 0; |
@@ -3047,17 +3046,14 @@ static int prepend(char **buffer, int *buflen, const char *str, int namelen) | |||
3047 | * retry it again when a d_move() does happen. So any garbage in the buffer | 3046 | * retry it again when a d_move() does happen. So any garbage in the buffer |
3048 | * due to mismatched pointer and length will be discarded. | 3047 | * due to mismatched pointer and length will be discarded. |
3049 | * | 3048 | * |
3050 | * Data dependency barrier is needed to make sure that we see that terminating | 3049 | * Load acquire is needed to make sure that we see that terminating NUL. |
3051 | * NUL. Alpha strikes again, film at 11... | ||
3052 | */ | 3050 | */ |
3053 | static int prepend_name(char **buffer, int *buflen, const struct qstr *name) | 3051 | static int prepend_name(char **buffer, int *buflen, const struct qstr *name) |
3054 | { | 3052 | { |
3055 | const char *dname = READ_ONCE(name->name); | 3053 | const char *dname = smp_load_acquire(&name->name); /* ^^^ */ |
3056 | u32 dlen = READ_ONCE(name->len); | 3054 | u32 dlen = READ_ONCE(name->len); |
3057 | char *p; | 3055 | char *p; |
3058 | 3056 | ||
3059 | smp_read_barrier_depends(); | ||
3060 | |||
3061 | *buflen -= dlen + 1; | 3057 | *buflen -= dlen + 1; |
3062 | if (*buflen < 0) | 3058 | if (*buflen < 0) |
3063 | return -ENAMETOOLONG; | 3059 | return -ENAMETOOLONG; |
@@ -391,7 +391,7 @@ static struct fdtable *close_files(struct files_struct * files) | |||
391 | struct file * file = xchg(&fdt->fd[i], NULL); | 391 | struct file * file = xchg(&fdt->fd[i], NULL); |
392 | if (file) { | 392 | if (file) { |
393 | filp_close(file, files); | 393 | filp_close(file, files); |
394 | cond_resched_rcu_qs(); | 394 | cond_resched(); |
395 | } | 395 | } |
396 | } | 396 | } |
397 | i++; | 397 | i++; |
diff --git a/include/linux/genetlink.h b/include/linux/genetlink.h index ecc2928e8046..bc738504ab4a 100644 --- a/include/linux/genetlink.h +++ b/include/linux/genetlink.h | |||
@@ -31,8 +31,7 @@ extern wait_queue_head_t genl_sk_destructing_waitq; | |||
31 | * @p: The pointer to read, prior to dereferencing | 31 | * @p: The pointer to read, prior to dereferencing |
32 | * | 32 | * |
33 | * Return the value of the specified RCU-protected pointer, but omit | 33 | * Return the value of the specified RCU-protected pointer, but omit |
34 | * both the smp_read_barrier_depends() and the READ_ONCE(), because | 34 | * the READ_ONCE(), because caller holds genl mutex. |
35 | * caller holds genl mutex. | ||
36 | */ | 35 | */ |
37 | #define genl_dereference(p) \ | 36 | #define genl_dereference(p) \ |
38 | rcu_dereference_protected(p, lockdep_genl_is_held()) | 37 | rcu_dereference_protected(p, lockdep_genl_is_held()) |
diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h index 495ba4dd9da5..34551f8aaf9d 100644 --- a/include/linux/netfilter/nfnetlink.h +++ b/include/linux/netfilter/nfnetlink.h | |||
@@ -67,8 +67,7 @@ static inline bool lockdep_nfnl_is_held(__u8 subsys_id) | |||
67 | * @ss: The nfnetlink subsystem ID | 67 | * @ss: The nfnetlink subsystem ID |
68 | * | 68 | * |
69 | * Return the value of the specified RCU-protected pointer, but omit | 69 | * Return the value of the specified RCU-protected pointer, but omit |
70 | * both the smp_read_barrier_depends() and the READ_ONCE(), because | 70 | * the READ_ONCE(), because caller holds the NFNL subsystem mutex. |
71 | * caller holds the NFNL subsystem mutex. | ||
72 | */ | 71 | */ |
73 | #define nfnl_dereference(p, ss) \ | 72 | #define nfnl_dereference(p, ss) \ |
74 | rcu_dereference_protected(p, lockdep_nfnl_is_held(ss)) | 73 | rcu_dereference_protected(p, lockdep_nfnl_is_held(ss)) |
diff --git a/include/linux/percpu-refcount.h b/include/linux/percpu-refcount.h index 6658d9ee5257..864d167a1073 100644 --- a/include/linux/percpu-refcount.h +++ b/include/linux/percpu-refcount.h | |||
@@ -139,12 +139,12 @@ static inline bool __ref_is_percpu(struct percpu_ref *ref, | |||
139 | * when using it as a pointer, __PERCPU_REF_ATOMIC may be set in | 139 | * when using it as a pointer, __PERCPU_REF_ATOMIC may be set in |
140 | * between contaminating the pointer value, meaning that | 140 | * between contaminating the pointer value, meaning that |
141 | * READ_ONCE() is required when fetching it. | 141 | * READ_ONCE() is required when fetching it. |
142 | * | ||
143 | * The smp_read_barrier_depends() implied by READ_ONCE() pairs | ||
144 | * with smp_store_release() in __percpu_ref_switch_to_percpu(). | ||
142 | */ | 145 | */ |
143 | percpu_ptr = READ_ONCE(ref->percpu_count_ptr); | 146 | percpu_ptr = READ_ONCE(ref->percpu_count_ptr); |
144 | 147 | ||
145 | /* paired with smp_store_release() in __percpu_ref_switch_to_percpu() */ | ||
146 | smp_read_barrier_depends(); | ||
147 | |||
148 | /* | 148 | /* |
149 | * Theoretically, the following could test just ATOMIC; however, | 149 | * Theoretically, the following could test just ATOMIC; however, |
150 | * then we'd have to mask off DEAD separately as DEAD may be | 150 | * then we'd have to mask off DEAD separately as DEAD may be |
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index a6ddc42f87a5..043d04784675 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h | |||
@@ -197,7 +197,7 @@ static inline void exit_tasks_rcu_finish(void) { } | |||
197 | #define cond_resched_rcu_qs() \ | 197 | #define cond_resched_rcu_qs() \ |
198 | do { \ | 198 | do { \ |
199 | if (!cond_resched()) \ | 199 | if (!cond_resched()) \ |
200 | rcu_note_voluntary_context_switch(current); \ | 200 | rcu_note_voluntary_context_switch_lite(current); \ |
201 | } while (0) | 201 | } while (0) |
202 | 202 | ||
203 | /* | 203 | /* |
@@ -433,12 +433,12 @@ static inline void rcu_preempt_sleep_check(void) { } | |||
433 | * @p: The pointer to read | 433 | * @p: The pointer to read |
434 | * | 434 | * |
435 | * Return the value of the specified RCU-protected pointer, but omit the | 435 | * Return the value of the specified RCU-protected pointer, but omit the |
436 | * smp_read_barrier_depends() and keep the READ_ONCE(). This is useful | 436 | * lockdep checks for being in an RCU read-side critical section. This is |
437 | * when the value of this pointer is accessed, but the pointer is not | 437 | * useful when the value of this pointer is accessed, but the pointer is |
438 | * dereferenced, for example, when testing an RCU-protected pointer against | 438 | * not dereferenced, for example, when testing an RCU-protected pointer |
439 | * NULL. Although rcu_access_pointer() may also be used in cases where | 439 | * against NULL. Although rcu_access_pointer() may also be used in cases |
440 | * update-side locks prevent the value of the pointer from changing, you | 440 | * where update-side locks prevent the value of the pointer from changing, |
441 | * should instead use rcu_dereference_protected() for this use case. | 441 | * you should instead use rcu_dereference_protected() for this use case. |
442 | * | 442 | * |
443 | * It is also permissible to use rcu_access_pointer() when read-side | 443 | * It is also permissible to use rcu_access_pointer() when read-side |
444 | * access to the pointer was removed at least one grace period ago, as | 444 | * access to the pointer was removed at least one grace period ago, as |
@@ -521,12 +521,11 @@ static inline void rcu_preempt_sleep_check(void) { } | |||
521 | * @c: The conditions under which the dereference will take place | 521 | * @c: The conditions under which the dereference will take place |
522 | * | 522 | * |
523 | * Return the value of the specified RCU-protected pointer, but omit | 523 | * Return the value of the specified RCU-protected pointer, but omit |
524 | * both the smp_read_barrier_depends() and the READ_ONCE(). This | 524 | * the READ_ONCE(). This is useful in cases where update-side locks |
525 | * is useful in cases where update-side locks prevent the value of the | 525 | * prevent the value of the pointer from changing. Please note that this |
526 | * pointer from changing. Please note that this primitive does *not* | 526 | * primitive does *not* prevent the compiler from repeating this reference |
527 | * prevent the compiler from repeating this reference or combining it | 527 | * or combining it with other references, so it should not be used without |
528 | * with other references, so it should not be used without protection | 528 | * protection of appropriate locks. |
529 | * of appropriate locks. | ||
530 | * | 529 | * |
531 | * This function is only for update-side use. Using this function | 530 | * This function is only for update-side use. Using this function |
532 | * when protected only by rcu_read_lock() will result in infrequent | 531 | * when protected only by rcu_read_lock() will result in infrequent |
diff --git a/include/linux/rcutiny.h b/include/linux/rcutiny.h index b3dbf9502fd0..ce9beec35e34 100644 --- a/include/linux/rcutiny.h +++ b/include/linux/rcutiny.h | |||
@@ -111,7 +111,6 @@ static inline void rcu_cpu_stall_reset(void) { } | |||
111 | static inline void rcu_idle_enter(void) { } | 111 | static inline void rcu_idle_enter(void) { } |
112 | static inline void rcu_idle_exit(void) { } | 112 | static inline void rcu_idle_exit(void) { } |
113 | static inline void rcu_irq_enter(void) { } | 113 | static inline void rcu_irq_enter(void) { } |
114 | static inline bool rcu_irq_enter_disabled(void) { return false; } | ||
115 | static inline void rcu_irq_exit_irqson(void) { } | 114 | static inline void rcu_irq_exit_irqson(void) { } |
116 | static inline void rcu_irq_enter_irqson(void) { } | 115 | static inline void rcu_irq_enter_irqson(void) { } |
117 | static inline void rcu_irq_exit(void) { } | 116 | static inline void rcu_irq_exit(void) { } |
diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h index 37d6fd3b7ff8..fd996cdf1833 100644 --- a/include/linux/rcutree.h +++ b/include/linux/rcutree.h | |||
@@ -85,7 +85,6 @@ void rcu_irq_enter(void); | |||
85 | void rcu_irq_exit(void); | 85 | void rcu_irq_exit(void); |
86 | void rcu_irq_enter_irqson(void); | 86 | void rcu_irq_enter_irqson(void); |
87 | void rcu_irq_exit_irqson(void); | 87 | void rcu_irq_exit_irqson(void); |
88 | bool rcu_irq_enter_disabled(void); | ||
89 | 88 | ||
90 | void exit_rcu(void); | 89 | void exit_rcu(void); |
91 | 90 | ||
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index 2032ce2eb20b..1eadec3fc228 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h | |||
@@ -70,8 +70,7 @@ static inline bool lockdep_rtnl_is_held(void) | |||
70 | * @p: The pointer to read, prior to dereferencing | 70 | * @p: The pointer to read, prior to dereferencing |
71 | * | 71 | * |
72 | * Return the value of the specified RCU-protected pointer, but omit | 72 | * Return the value of the specified RCU-protected pointer, but omit |
73 | * both the smp_read_barrier_depends() and the READ_ONCE(), because | 73 | * the READ_ONCE(), because caller holds RTNL. |
74 | * caller holds RTNL. | ||
75 | */ | 74 | */ |
76 | #define rtnl_dereference(p) \ | 75 | #define rtnl_dereference(p) \ |
77 | rcu_dereference_protected(p, lockdep_rtnl_is_held()) | 76 | rcu_dereference_protected(p, lockdep_rtnl_is_held()) |
diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h index f189a8a3bbb8..bcf4cf26b8c8 100644 --- a/include/linux/seqlock.h +++ b/include/linux/seqlock.h | |||
@@ -278,9 +278,8 @@ static inline void raw_write_seqcount_barrier(seqcount_t *s) | |||
278 | 278 | ||
279 | static inline int raw_read_seqcount_latch(seqcount_t *s) | 279 | static inline int raw_read_seqcount_latch(seqcount_t *s) |
280 | { | 280 | { |
281 | int seq = READ_ONCE(s->sequence); | ||
282 | /* Pairs with the first smp_wmb() in raw_write_seqcount_latch() */ | 281 | /* Pairs with the first smp_wmb() in raw_write_seqcount_latch() */ |
283 | smp_read_barrier_depends(); | 282 | int seq = READ_ONCE(s->sequence); /* ^^^ */ |
284 | return seq; | 283 | return seq; |
285 | } | 284 | } |
286 | 285 | ||
diff --git a/include/linux/srcutree.h b/include/linux/srcutree.h index a949f4f9e4d7..4eda108abee0 100644 --- a/include/linux/srcutree.h +++ b/include/linux/srcutree.h | |||
@@ -40,7 +40,7 @@ struct srcu_data { | |||
40 | unsigned long srcu_unlock_count[2]; /* Unlocks per CPU. */ | 40 | unsigned long srcu_unlock_count[2]; /* Unlocks per CPU. */ |
41 | 41 | ||
42 | /* Update-side state. */ | 42 | /* Update-side state. */ |
43 | raw_spinlock_t __private lock ____cacheline_internodealigned_in_smp; | 43 | spinlock_t __private lock ____cacheline_internodealigned_in_smp; |
44 | struct rcu_segcblist srcu_cblist; /* List of callbacks.*/ | 44 | struct rcu_segcblist srcu_cblist; /* List of callbacks.*/ |
45 | unsigned long srcu_gp_seq_needed; /* Furthest future GP needed. */ | 45 | unsigned long srcu_gp_seq_needed; /* Furthest future GP needed. */ |
46 | unsigned long srcu_gp_seq_needed_exp; /* Furthest future exp GP. */ | 46 | unsigned long srcu_gp_seq_needed_exp; /* Furthest future exp GP. */ |
@@ -58,7 +58,7 @@ struct srcu_data { | |||
58 | * Node in SRCU combining tree, similar in function to rcu_data. | 58 | * Node in SRCU combining tree, similar in function to rcu_data. |
59 | */ | 59 | */ |
60 | struct srcu_node { | 60 | struct srcu_node { |
61 | raw_spinlock_t __private lock; | 61 | spinlock_t __private lock; |
62 | unsigned long srcu_have_cbs[4]; /* GP seq for children */ | 62 | unsigned long srcu_have_cbs[4]; /* GP seq for children */ |
63 | /* having CBs, but only */ | 63 | /* having CBs, but only */ |
64 | /* is > ->srcu_gq_seq. */ | 64 | /* is > ->srcu_gq_seq. */ |
@@ -78,7 +78,7 @@ struct srcu_struct { | |||
78 | struct srcu_node *level[RCU_NUM_LVLS + 1]; | 78 | struct srcu_node *level[RCU_NUM_LVLS + 1]; |
79 | /* First node at each level. */ | 79 | /* First node at each level. */ |
80 | struct mutex srcu_cb_mutex; /* Serialize CB preparation. */ | 80 | struct mutex srcu_cb_mutex; /* Serialize CB preparation. */ |
81 | raw_spinlock_t __private lock; /* Protect counters */ | 81 | spinlock_t __private lock; /* Protect counters */ |
82 | struct mutex srcu_gp_mutex; /* Serialize GP work. */ | 82 | struct mutex srcu_gp_mutex; /* Serialize GP work. */ |
83 | unsigned int srcu_idx; /* Current rdr array element. */ | 83 | unsigned int srcu_idx; /* Current rdr array element. */ |
84 | unsigned long srcu_gp_seq; /* Grace-period seq #. */ | 84 | unsigned long srcu_gp_seq; /* Grace-period seq #. */ |
@@ -107,7 +107,7 @@ struct srcu_struct { | |||
107 | #define __SRCU_STRUCT_INIT(name) \ | 107 | #define __SRCU_STRUCT_INIT(name) \ |
108 | { \ | 108 | { \ |
109 | .sda = &name##_srcu_data, \ | 109 | .sda = &name##_srcu_data, \ |
110 | .lock = __RAW_SPIN_LOCK_UNLOCKED(name.lock), \ | 110 | .lock = __SPIN_LOCK_UNLOCKED(name.lock), \ |
111 | .srcu_gp_seq_needed = 0 - 1, \ | 111 | .srcu_gp_seq_needed = 0 - 1, \ |
112 | __SRCU_DEP_MAP_INIT(name) \ | 112 | __SRCU_DEP_MAP_INIT(name) \ |
113 | } | 113 | } |
diff --git a/include/linux/torture.h b/include/linux/torture.h index a45702eb3e7b..66272862070b 100644 --- a/include/linux/torture.h +++ b/include/linux/torture.h | |||
@@ -79,7 +79,7 @@ void stutter_wait(const char *title); | |||
79 | int torture_stutter_init(int s); | 79 | int torture_stutter_init(int s); |
80 | 80 | ||
81 | /* Initialization and cleanup. */ | 81 | /* Initialization and cleanup. */ |
82 | bool torture_init_begin(char *ttype, bool v, int *runnable); | 82 | bool torture_init_begin(char *ttype, bool v); |
83 | void torture_init_end(void); | 83 | void torture_init_end(void); |
84 | bool torture_cleanup_begin(void); | 84 | bool torture_cleanup_begin(void); |
85 | void torture_cleanup_end(void); | 85 | void torture_cleanup_end(void); |
@@ -96,4 +96,10 @@ void _torture_stop_kthread(char *m, struct task_struct **tp); | |||
96 | #define torture_stop_kthread(n, tp) \ | 96 | #define torture_stop_kthread(n, tp) \ |
97 | _torture_stop_kthread("Stopping " #n " task", &(tp)) | 97 | _torture_stop_kthread("Stopping " #n " task", &(tp)) |
98 | 98 | ||
99 | #ifdef CONFIG_PREEMPT | ||
100 | #define torture_preempt_schedule() preempt_schedule() | ||
101 | #else | ||
102 | #define torture_preempt_schedule() | ||
103 | #endif | ||
104 | |||
99 | #endif /* __LINUX_TORTURE_H */ | 105 | #endif /* __LINUX_TORTURE_H */ |
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index a26ffbe09e71..c94f466d57ef 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h | |||
@@ -137,11 +137,8 @@ extern void syscall_unregfunc(void); | |||
137 | \ | 137 | \ |
138 | if (!(cond)) \ | 138 | if (!(cond)) \ |
139 | return; \ | 139 | return; \ |
140 | if (rcucheck) { \ | 140 | if (rcucheck) \ |
141 | if (WARN_ON_ONCE(rcu_irq_enter_disabled())) \ | ||
142 | return; \ | ||
143 | rcu_irq_enter_irqson(); \ | 141 | rcu_irq_enter_irqson(); \ |
144 | } \ | ||
145 | rcu_read_lock_sched_notrace(); \ | 142 | rcu_read_lock_sched_notrace(); \ |
146 | it_func_ptr = rcu_dereference_sched((tp)->funcs); \ | 143 | it_func_ptr = rcu_dereference_sched((tp)->funcs); \ |
147 | if (it_func_ptr) { \ | 144 | if (it_func_ptr) { \ |
diff --git a/include/trace/events/rcu.h b/include/trace/events/rcu.h index 59d40c454aa0..0b50fda80db0 100644 --- a/include/trace/events/rcu.h +++ b/include/trace/events/rcu.h | |||
@@ -243,6 +243,7 @@ TRACE_EVENT(rcu_exp_funnel_lock, | |||
243 | __entry->grphi, __entry->gpevent) | 243 | __entry->grphi, __entry->gpevent) |
244 | ); | 244 | ); |
245 | 245 | ||
246 | #ifdef CONFIG_RCU_NOCB_CPU | ||
246 | /* | 247 | /* |
247 | * Tracepoint for RCU no-CBs CPU callback handoffs. This event is intended | 248 | * Tracepoint for RCU no-CBs CPU callback handoffs. This event is intended |
248 | * to assist debugging of these handoffs. | 249 | * to assist debugging of these handoffs. |
@@ -285,6 +286,7 @@ TRACE_EVENT(rcu_nocb_wake, | |||
285 | 286 | ||
286 | TP_printk("%s %d %s", __entry->rcuname, __entry->cpu, __entry->reason) | 287 | TP_printk("%s %d %s", __entry->rcuname, __entry->cpu, __entry->reason) |
287 | ); | 288 | ); |
289 | #endif | ||
288 | 290 | ||
289 | /* | 291 | /* |
290 | * Tracepoint for tasks blocking within preemptible-RCU read-side | 292 | * Tracepoint for tasks blocking within preemptible-RCU read-side |
@@ -421,76 +423,40 @@ TRACE_EVENT(rcu_fqs, | |||
421 | 423 | ||
422 | /* | 424 | /* |
423 | * Tracepoint for dyntick-idle entry/exit events. These take a string | 425 | * Tracepoint for dyntick-idle entry/exit events. These take a string |
424 | * as argument: "Start" for entering dyntick-idle mode, "End" for | 426 | * as argument: "Start" for entering dyntick-idle mode, "Startirq" for |
425 | * leaving it, "--=" for events moving towards idle, and "++=" for events | 427 | * entering it from irq/NMI, "End" for leaving it, "Endirq" for leaving it |
426 | * moving away from idle. "Error on entry: not idle task" and "Error on | 428 | * to irq/NMI, "--=" for events moving towards idle, and "++=" for events |
427 | * exit: not idle task" indicate that a non-idle task is erroneously | 429 | * moving away from idle. |
428 | * toying with the idle loop. | ||
429 | * | 430 | * |
430 | * These events also take a pair of numbers, which indicate the nesting | 431 | * These events also take a pair of numbers, which indicate the nesting |
431 | * depth before and after the event of interest. Note that task-related | 432 | * depth before and after the event of interest, and a third number that is |
432 | * events use the upper bits of each number, while interrupt-related | 433 | * the ->dynticks counter. Note that task-related and interrupt-related |
433 | * events use the lower bits. | 434 | * events use two separate counters, and that the "++=" and "--=" events |
435 | * for irq/NMI will change the counter by two, otherwise by one. | ||
434 | */ | 436 | */ |
435 | TRACE_EVENT(rcu_dyntick, | 437 | TRACE_EVENT(rcu_dyntick, |
436 | 438 | ||
437 | TP_PROTO(const char *polarity, long long oldnesting, long long newnesting), | 439 | TP_PROTO(const char *polarity, long oldnesting, long newnesting, atomic_t dynticks), |
438 | 440 | ||
439 | TP_ARGS(polarity, oldnesting, newnesting), | 441 | TP_ARGS(polarity, oldnesting, newnesting, dynticks), |
440 | 442 | ||
441 | TP_STRUCT__entry( | 443 | TP_STRUCT__entry( |
442 | __field(const char *, polarity) | 444 | __field(const char *, polarity) |
443 | __field(long long, oldnesting) | 445 | __field(long, oldnesting) |
444 | __field(long long, newnesting) | 446 | __field(long, newnesting) |
447 | __field(int, dynticks) | ||
445 | ), | 448 | ), |
446 | 449 | ||
447 | TP_fast_assign( | 450 | TP_fast_assign( |
448 | __entry->polarity = polarity; | 451 | __entry->polarity = polarity; |
449 | __entry->oldnesting = oldnesting; | 452 | __entry->oldnesting = oldnesting; |
450 | __entry->newnesting = newnesting; | 453 | __entry->newnesting = newnesting; |
454 | __entry->dynticks = atomic_read(&dynticks); | ||
451 | ), | 455 | ), |
452 | 456 | ||
453 | TP_printk("%s %llx %llx", __entry->polarity, | 457 | TP_printk("%s %lx %lx %#3x", __entry->polarity, |
454 | __entry->oldnesting, __entry->newnesting) | 458 | __entry->oldnesting, __entry->newnesting, |
455 | ); | 459 | __entry->dynticks & 0xfff) |
456 | |||
457 | /* | ||
458 | * Tracepoint for RCU preparation for idle, the goal being to get RCU | ||
459 | * processing done so that the current CPU can shut off its scheduling | ||
460 | * clock and enter dyntick-idle mode. One way to accomplish this is | ||
461 | * to drain all RCU callbacks from this CPU, and the other is to have | ||
462 | * done everything RCU requires for the current grace period. In this | ||
463 | * latter case, the CPU will be awakened at the end of the current grace | ||
464 | * period in order to process the remainder of its callbacks. | ||
465 | * | ||
466 | * These tracepoints take a string as argument: | ||
467 | * | ||
468 | * "No callbacks": Nothing to do, no callbacks on this CPU. | ||
469 | * "In holdoff": Nothing to do, holding off after unsuccessful attempt. | ||
470 | * "Begin holdoff": Attempt failed, don't retry until next jiffy. | ||
471 | * "Dyntick with callbacks": Entering dyntick-idle despite callbacks. | ||
472 | * "Dyntick with lazy callbacks": Entering dyntick-idle w/lazy callbacks. | ||
473 | * "More callbacks": Still more callbacks, try again to clear them out. | ||
474 | * "Callbacks drained": All callbacks processed, off to dyntick idle! | ||
475 | * "Timer": Timer fired to cause CPU to continue processing callbacks. | ||
476 | * "Demigrate": Timer fired on wrong CPU, woke up correct CPU. | ||
477 | * "Cleanup after idle": Idle exited, timer canceled. | ||
478 | */ | ||
479 | TRACE_EVENT(rcu_prep_idle, | ||
480 | |||
481 | TP_PROTO(const char *reason), | ||
482 | |||
483 | TP_ARGS(reason), | ||
484 | |||
485 | TP_STRUCT__entry( | ||
486 | __field(const char *, reason) | ||
487 | ), | ||
488 | |||
489 | TP_fast_assign( | ||
490 | __entry->reason = reason; | ||
491 | ), | ||
492 | |||
493 | TP_printk("%s", __entry->reason) | ||
494 | ); | 460 | ); |
495 | 461 | ||
496 | /* | 462 | /* |
@@ -799,8 +765,7 @@ TRACE_EVENT(rcu_barrier, | |||
799 | grplo, grphi, gp_tasks) do { } \ | 765 | grplo, grphi, gp_tasks) do { } \ |
800 | while (0) | 766 | while (0) |
801 | #define trace_rcu_fqs(rcuname, gpnum, cpu, qsevent) do { } while (0) | 767 | #define trace_rcu_fqs(rcuname, gpnum, cpu, qsevent) do { } while (0) |
802 | #define trace_rcu_dyntick(polarity, oldnesting, newnesting) do { } while (0) | 768 | #define trace_rcu_dyntick(polarity, oldnesting, newnesting, dyntick) do { } while (0) |
803 | #define trace_rcu_prep_idle(reason) do { } while (0) | ||
804 | #define trace_rcu_callback(rcuname, rhp, qlen_lazy, qlen) do { } while (0) | 769 | #define trace_rcu_callback(rcuname, rhp, qlen_lazy, qlen) do { } while (0) |
805 | #define trace_rcu_kfree_callback(rcuname, rhp, offset, qlen_lazy, qlen) \ | 770 | #define trace_rcu_kfree_callback(rcuname, rhp, offset, qlen_lazy, qlen) \ |
806 | do { } while (0) | 771 | do { } while (0) |
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 267f6ef91d97..ce6848e46e94 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c | |||
@@ -1167,8 +1167,8 @@ static int xol_add_vma(struct mm_struct *mm, struct xol_area *area) | |||
1167 | } | 1167 | } |
1168 | 1168 | ||
1169 | ret = 0; | 1169 | ret = 0; |
1170 | smp_wmb(); /* pairs with get_xol_area() */ | 1170 | /* pairs with get_xol_area() */ |
1171 | mm->uprobes_state.xol_area = area; | 1171 | smp_store_release(&mm->uprobes_state.xol_area, area); /* ^^^ */ |
1172 | fail: | 1172 | fail: |
1173 | up_write(&mm->mmap_sem); | 1173 | up_write(&mm->mmap_sem); |
1174 | 1174 | ||
@@ -1230,8 +1230,8 @@ static struct xol_area *get_xol_area(void) | |||
1230 | if (!mm->uprobes_state.xol_area) | 1230 | if (!mm->uprobes_state.xol_area) |
1231 | __create_xol_area(0); | 1231 | __create_xol_area(0); |
1232 | 1232 | ||
1233 | area = mm->uprobes_state.xol_area; | 1233 | /* Pairs with xol_add_vma() smp_store_release() */ |
1234 | smp_read_barrier_depends(); /* pairs with wmb in xol_add_vma() */ | 1234 | area = READ_ONCE(mm->uprobes_state.xol_area); /* ^^^ */ |
1235 | return area; | 1235 | return area; |
1236 | } | 1236 | } |
1237 | 1237 | ||
@@ -1528,8 +1528,8 @@ static unsigned long get_trampoline_vaddr(void) | |||
1528 | struct xol_area *area; | 1528 | struct xol_area *area; |
1529 | unsigned long trampoline_vaddr = -1; | 1529 | unsigned long trampoline_vaddr = -1; |
1530 | 1530 | ||
1531 | area = current->mm->uprobes_state.xol_area; | 1531 | /* Pairs with xol_add_vma() smp_store_release() */ |
1532 | smp_read_barrier_depends(); | 1532 | area = READ_ONCE(current->mm->uprobes_state.xol_area); /* ^^^ */ |
1533 | if (area) | 1533 | if (area) |
1534 | trampoline_vaddr = area->vaddr; | 1534 | trampoline_vaddr = area->vaddr; |
1535 | 1535 | ||
diff --git a/kernel/locking/locktorture.c b/kernel/locking/locktorture.c index f24582d4dad3..6850ffd69125 100644 --- a/kernel/locking/locktorture.c +++ b/kernel/locking/locktorture.c | |||
@@ -77,10 +77,6 @@ struct lock_stress_stats { | |||
77 | long n_lock_acquired; | 77 | long n_lock_acquired; |
78 | }; | 78 | }; |
79 | 79 | ||
80 | int torture_runnable = IS_ENABLED(MODULE); | ||
81 | module_param(torture_runnable, int, 0444); | ||
82 | MODULE_PARM_DESC(torture_runnable, "Start locktorture at module init"); | ||
83 | |||
84 | /* Forward reference. */ | 80 | /* Forward reference. */ |
85 | static void lock_torture_cleanup(void); | 81 | static void lock_torture_cleanup(void); |
86 | 82 | ||
@@ -130,10 +126,8 @@ static void torture_lock_busted_write_delay(struct torture_random_state *trsp) | |||
130 | if (!(torture_random(trsp) % | 126 | if (!(torture_random(trsp) % |
131 | (cxt.nrealwriters_stress * 2000 * longdelay_ms))) | 127 | (cxt.nrealwriters_stress * 2000 * longdelay_ms))) |
132 | mdelay(longdelay_ms); | 128 | mdelay(longdelay_ms); |
133 | #ifdef CONFIG_PREEMPT | ||
134 | if (!(torture_random(trsp) % (cxt.nrealwriters_stress * 20000))) | 129 | if (!(torture_random(trsp) % (cxt.nrealwriters_stress * 20000))) |
135 | preempt_schedule(); /* Allow test to be preempted. */ | 130 | torture_preempt_schedule(); /* Allow test to be preempted. */ |
136 | #endif | ||
137 | } | 131 | } |
138 | 132 | ||
139 | static void torture_lock_busted_write_unlock(void) | 133 | static void torture_lock_busted_write_unlock(void) |
@@ -179,10 +173,8 @@ static void torture_spin_lock_write_delay(struct torture_random_state *trsp) | |||
179 | if (!(torture_random(trsp) % | 173 | if (!(torture_random(trsp) % |
180 | (cxt.nrealwriters_stress * 2 * shortdelay_us))) | 174 | (cxt.nrealwriters_stress * 2 * shortdelay_us))) |
181 | udelay(shortdelay_us); | 175 | udelay(shortdelay_us); |
182 | #ifdef CONFIG_PREEMPT | ||
183 | if (!(torture_random(trsp) % (cxt.nrealwriters_stress * 20000))) | 176 | if (!(torture_random(trsp) % (cxt.nrealwriters_stress * 20000))) |
184 | preempt_schedule(); /* Allow test to be preempted. */ | 177 | torture_preempt_schedule(); /* Allow test to be preempted. */ |
185 | #endif | ||
186 | } | 178 | } |
187 | 179 | ||
188 | static void torture_spin_lock_write_unlock(void) __releases(torture_spinlock) | 180 | static void torture_spin_lock_write_unlock(void) __releases(torture_spinlock) |
@@ -352,10 +344,8 @@ static void torture_mutex_delay(struct torture_random_state *trsp) | |||
352 | mdelay(longdelay_ms * 5); | 344 | mdelay(longdelay_ms * 5); |
353 | else | 345 | else |
354 | mdelay(longdelay_ms / 5); | 346 | mdelay(longdelay_ms / 5); |
355 | #ifdef CONFIG_PREEMPT | ||
356 | if (!(torture_random(trsp) % (cxt.nrealwriters_stress * 20000))) | 347 | if (!(torture_random(trsp) % (cxt.nrealwriters_stress * 20000))) |
357 | preempt_schedule(); /* Allow test to be preempted. */ | 348 | torture_preempt_schedule(); /* Allow test to be preempted. */ |
358 | #endif | ||
359 | } | 349 | } |
360 | 350 | ||
361 | static void torture_mutex_unlock(void) __releases(torture_mutex) | 351 | static void torture_mutex_unlock(void) __releases(torture_mutex) |
@@ -507,10 +497,8 @@ static void torture_rtmutex_delay(struct torture_random_state *trsp) | |||
507 | if (!(torture_random(trsp) % | 497 | if (!(torture_random(trsp) % |
508 | (cxt.nrealwriters_stress * 2 * shortdelay_us))) | 498 | (cxt.nrealwriters_stress * 2 * shortdelay_us))) |
509 | udelay(shortdelay_us); | 499 | udelay(shortdelay_us); |
510 | #ifdef CONFIG_PREEMPT | ||
511 | if (!(torture_random(trsp) % (cxt.nrealwriters_stress * 20000))) | 500 | if (!(torture_random(trsp) % (cxt.nrealwriters_stress * 20000))) |
512 | preempt_schedule(); /* Allow test to be preempted. */ | 501 | torture_preempt_schedule(); /* Allow test to be preempted. */ |
513 | #endif | ||
514 | } | 502 | } |
515 | 503 | ||
516 | static void torture_rtmutex_unlock(void) __releases(torture_rtmutex) | 504 | static void torture_rtmutex_unlock(void) __releases(torture_rtmutex) |
@@ -547,10 +535,8 @@ static void torture_rwsem_write_delay(struct torture_random_state *trsp) | |||
547 | mdelay(longdelay_ms * 10); | 535 | mdelay(longdelay_ms * 10); |
548 | else | 536 | else |
549 | mdelay(longdelay_ms / 10); | 537 | mdelay(longdelay_ms / 10); |
550 | #ifdef CONFIG_PREEMPT | ||
551 | if (!(torture_random(trsp) % (cxt.nrealwriters_stress * 20000))) | 538 | if (!(torture_random(trsp) % (cxt.nrealwriters_stress * 20000))) |
552 | preempt_schedule(); /* Allow test to be preempted. */ | 539 | torture_preempt_schedule(); /* Allow test to be preempted. */ |
553 | #endif | ||
554 | } | 540 | } |
555 | 541 | ||
556 | static void torture_rwsem_up_write(void) __releases(torture_rwsem) | 542 | static void torture_rwsem_up_write(void) __releases(torture_rwsem) |
@@ -570,14 +556,12 @@ static void torture_rwsem_read_delay(struct torture_random_state *trsp) | |||
570 | 556 | ||
571 | /* We want a long delay occasionally to force massive contention. */ | 557 | /* We want a long delay occasionally to force massive contention. */ |
572 | if (!(torture_random(trsp) % | 558 | if (!(torture_random(trsp) % |
573 | (cxt.nrealwriters_stress * 2000 * longdelay_ms))) | 559 | (cxt.nrealreaders_stress * 2000 * longdelay_ms))) |
574 | mdelay(longdelay_ms * 2); | 560 | mdelay(longdelay_ms * 2); |
575 | else | 561 | else |
576 | mdelay(longdelay_ms / 2); | 562 | mdelay(longdelay_ms / 2); |
577 | #ifdef CONFIG_PREEMPT | ||
578 | if (!(torture_random(trsp) % (cxt.nrealreaders_stress * 20000))) | 563 | if (!(torture_random(trsp) % (cxt.nrealreaders_stress * 20000))) |
579 | preempt_schedule(); /* Allow test to be preempted. */ | 564 | torture_preempt_schedule(); /* Allow test to be preempted. */ |
580 | #endif | ||
581 | } | 565 | } |
582 | 566 | ||
583 | static void torture_rwsem_up_read(void) __releases(torture_rwsem) | 567 | static void torture_rwsem_up_read(void) __releases(torture_rwsem) |
@@ -715,8 +699,7 @@ static void __torture_print_stats(char *page, | |||
715 | { | 699 | { |
716 | bool fail = 0; | 700 | bool fail = 0; |
717 | int i, n_stress; | 701 | int i, n_stress; |
718 | long max = 0; | 702 | long max = 0, min = statp ? statp[0].n_lock_acquired : 0; |
719 | long min = statp[0].n_lock_acquired; | ||
720 | long long sum = 0; | 703 | long long sum = 0; |
721 | 704 | ||
722 | n_stress = write ? cxt.nrealwriters_stress : cxt.nrealreaders_stress; | 705 | n_stress = write ? cxt.nrealwriters_stress : cxt.nrealreaders_stress; |
@@ -823,7 +806,7 @@ static void lock_torture_cleanup(void) | |||
823 | * such, only perform the underlying torture-specific cleanups, | 806 | * such, only perform the underlying torture-specific cleanups, |
824 | * and avoid anything related to locktorture. | 807 | * and avoid anything related to locktorture. |
825 | */ | 808 | */ |
826 | if (!cxt.lwsa) | 809 | if (!cxt.lwsa && !cxt.lrsa) |
827 | goto end; | 810 | goto end; |
828 | 811 | ||
829 | if (writer_tasks) { | 812 | if (writer_tasks) { |
@@ -879,7 +862,7 @@ static int __init lock_torture_init(void) | |||
879 | &percpu_rwsem_lock_ops, | 862 | &percpu_rwsem_lock_ops, |
880 | }; | 863 | }; |
881 | 864 | ||
882 | if (!torture_init_begin(torture_type, verbose, &torture_runnable)) | 865 | if (!torture_init_begin(torture_type, verbose)) |
883 | return -EBUSY; | 866 | return -EBUSY; |
884 | 867 | ||
885 | /* Process args and tell the world that the torturer is on the job. */ | 868 | /* Process args and tell the world that the torturer is on the job. */ |
@@ -898,6 +881,13 @@ static int __init lock_torture_init(void) | |||
898 | firsterr = -EINVAL; | 881 | firsterr = -EINVAL; |
899 | goto unwind; | 882 | goto unwind; |
900 | } | 883 | } |
884 | |||
885 | if (nwriters_stress == 0 && nreaders_stress == 0) { | ||
886 | pr_alert("lock-torture: must run at least one locking thread\n"); | ||
887 | firsterr = -EINVAL; | ||
888 | goto unwind; | ||
889 | } | ||
890 | |||
901 | if (cxt.cur_ops->init) | 891 | if (cxt.cur_ops->init) |
902 | cxt.cur_ops->init(); | 892 | cxt.cur_ops->init(); |
903 | 893 | ||
@@ -921,17 +911,19 @@ static int __init lock_torture_init(void) | |||
921 | #endif | 911 | #endif |
922 | 912 | ||
923 | /* Initialize the statistics so that each run gets its own numbers. */ | 913 | /* Initialize the statistics so that each run gets its own numbers. */ |
914 | if (nwriters_stress) { | ||
915 | lock_is_write_held = 0; | ||
916 | cxt.lwsa = kmalloc(sizeof(*cxt.lwsa) * cxt.nrealwriters_stress, GFP_KERNEL); | ||
917 | if (cxt.lwsa == NULL) { | ||
918 | VERBOSE_TOROUT_STRING("cxt.lwsa: Out of memory"); | ||
919 | firsterr = -ENOMEM; | ||
920 | goto unwind; | ||
921 | } | ||
924 | 922 | ||
925 | lock_is_write_held = 0; | 923 | for (i = 0; i < cxt.nrealwriters_stress; i++) { |
926 | cxt.lwsa = kmalloc(sizeof(*cxt.lwsa) * cxt.nrealwriters_stress, GFP_KERNEL); | 924 | cxt.lwsa[i].n_lock_fail = 0; |
927 | if (cxt.lwsa == NULL) { | 925 | cxt.lwsa[i].n_lock_acquired = 0; |
928 | VERBOSE_TOROUT_STRING("cxt.lwsa: Out of memory"); | 926 | } |
929 | firsterr = -ENOMEM; | ||
930 | goto unwind; | ||
931 | } | ||
932 | for (i = 0; i < cxt.nrealwriters_stress; i++) { | ||
933 | cxt.lwsa[i].n_lock_fail = 0; | ||
934 | cxt.lwsa[i].n_lock_acquired = 0; | ||
935 | } | 927 | } |
936 | 928 | ||
937 | if (cxt.cur_ops->readlock) { | 929 | if (cxt.cur_ops->readlock) { |
@@ -948,19 +940,21 @@ static int __init lock_torture_init(void) | |||
948 | cxt.nrealreaders_stress = cxt.nrealwriters_stress; | 940 | cxt.nrealreaders_stress = cxt.nrealwriters_stress; |
949 | } | 941 | } |
950 | 942 | ||
951 | lock_is_read_held = 0; | 943 | if (nreaders_stress) { |
952 | cxt.lrsa = kmalloc(sizeof(*cxt.lrsa) * cxt.nrealreaders_stress, GFP_KERNEL); | 944 | lock_is_read_held = 0; |
953 | if (cxt.lrsa == NULL) { | 945 | cxt.lrsa = kmalloc(sizeof(*cxt.lrsa) * cxt.nrealreaders_stress, GFP_KERNEL); |
954 | VERBOSE_TOROUT_STRING("cxt.lrsa: Out of memory"); | 946 | if (cxt.lrsa == NULL) { |
955 | firsterr = -ENOMEM; | 947 | VERBOSE_TOROUT_STRING("cxt.lrsa: Out of memory"); |
956 | kfree(cxt.lwsa); | 948 | firsterr = -ENOMEM; |
957 | cxt.lwsa = NULL; | 949 | kfree(cxt.lwsa); |
958 | goto unwind; | 950 | cxt.lwsa = NULL; |
959 | } | 951 | goto unwind; |
960 | 952 | } | |
961 | for (i = 0; i < cxt.nrealreaders_stress; i++) { | 953 | |
962 | cxt.lrsa[i].n_lock_fail = 0; | 954 | for (i = 0; i < cxt.nrealreaders_stress; i++) { |
963 | cxt.lrsa[i].n_lock_acquired = 0; | 955 | cxt.lrsa[i].n_lock_fail = 0; |
956 | cxt.lrsa[i].n_lock_acquired = 0; | ||
957 | } | ||
964 | } | 958 | } |
965 | } | 959 | } |
966 | 960 | ||
@@ -990,12 +984,14 @@ static int __init lock_torture_init(void) | |||
990 | goto unwind; | 984 | goto unwind; |
991 | } | 985 | } |
992 | 986 | ||
993 | writer_tasks = kzalloc(cxt.nrealwriters_stress * sizeof(writer_tasks[0]), | 987 | if (nwriters_stress) { |
994 | GFP_KERNEL); | 988 | writer_tasks = kzalloc(cxt.nrealwriters_stress * sizeof(writer_tasks[0]), |
995 | if (writer_tasks == NULL) { | 989 | GFP_KERNEL); |
996 | VERBOSE_TOROUT_ERRSTRING("writer_tasks: Out of memory"); | 990 | if (writer_tasks == NULL) { |
997 | firsterr = -ENOMEM; | 991 | VERBOSE_TOROUT_ERRSTRING("writer_tasks: Out of memory"); |
998 | goto unwind; | 992 | firsterr = -ENOMEM; |
993 | goto unwind; | ||
994 | } | ||
999 | } | 995 | } |
1000 | 996 | ||
1001 | if (cxt.cur_ops->readlock) { | 997 | if (cxt.cur_ops->readlock) { |
diff --git a/kernel/locking/qspinlock.c b/kernel/locking/qspinlock.c index 294294c71ba4..38ece035039e 100644 --- a/kernel/locking/qspinlock.c +++ b/kernel/locking/qspinlock.c | |||
@@ -170,7 +170,7 @@ static __always_inline void clear_pending_set_locked(struct qspinlock *lock) | |||
170 | * @tail : The new queue tail code word | 170 | * @tail : The new queue tail code word |
171 | * Return: The previous queue tail code word | 171 | * Return: The previous queue tail code word |
172 | * | 172 | * |
173 | * xchg(lock, tail) | 173 | * xchg(lock, tail), which heads an address dependency |
174 | * | 174 | * |
175 | * p,*,* -> n,*,* ; prev = xchg(lock, node) | 175 | * p,*,* -> n,*,* ; prev = xchg(lock, node) |
176 | */ | 176 | */ |
@@ -409,13 +409,11 @@ queue: | |||
409 | if (old & _Q_TAIL_MASK) { | 409 | if (old & _Q_TAIL_MASK) { |
410 | prev = decode_tail(old); | 410 | prev = decode_tail(old); |
411 | /* | 411 | /* |
412 | * The above xchg_tail() is also a load of @lock which generates, | 412 | * The above xchg_tail() is also a load of @lock which |
413 | * through decode_tail(), a pointer. | 413 | * generates, through decode_tail(), a pointer. The address |
414 | * | 414 | * dependency matches the RELEASE of xchg_tail() such that |
415 | * The address dependency matches the RELEASE of xchg_tail() | 415 | * the subsequent access to @prev happens after. |
416 | * such that the access to @prev must happen after. | ||
417 | */ | 416 | */ |
418 | smp_read_barrier_depends(); | ||
419 | 417 | ||
420 | WRITE_ONCE(prev->next, node); | 418 | WRITE_ONCE(prev->next, node); |
421 | 419 | ||
diff --git a/kernel/rcu/rcu.h b/kernel/rcu/rcu.h index 59c471de342a..6334f2c1abd0 100644 --- a/kernel/rcu/rcu.h +++ b/kernel/rcu/rcu.h | |||
@@ -30,31 +30,8 @@ | |||
30 | #define RCU_TRACE(stmt) | 30 | #define RCU_TRACE(stmt) |
31 | #endif /* #else #ifdef CONFIG_RCU_TRACE */ | 31 | #endif /* #else #ifdef CONFIG_RCU_TRACE */ |
32 | 32 | ||
33 | /* | 33 | /* Offset to allow for unmatched rcu_irq_{enter,exit}(). */ |
34 | * Process-level increment to ->dynticks_nesting field. This allows for | 34 | #define DYNTICK_IRQ_NONIDLE ((LONG_MAX / 2) + 1) |
35 | * architectures that use half-interrupts and half-exceptions from | ||
36 | * process context. | ||
37 | * | ||
38 | * DYNTICK_TASK_NEST_MASK defines a field of width DYNTICK_TASK_NEST_WIDTH | ||
39 | * that counts the number of process-based reasons why RCU cannot | ||
40 | * consider the corresponding CPU to be idle, and DYNTICK_TASK_NEST_VALUE | ||
41 | * is the value used to increment or decrement this field. | ||
42 | * | ||
43 | * The rest of the bits could in principle be used to count interrupts, | ||
44 | * but this would mean that a negative-one value in the interrupt | ||
45 | * field could incorrectly zero out the DYNTICK_TASK_NEST_MASK field. | ||
46 | * We therefore provide a two-bit guard field defined by DYNTICK_TASK_MASK | ||
47 | * that is set to DYNTICK_TASK_FLAG upon initial exit from idle. | ||
48 | * The DYNTICK_TASK_EXIT_IDLE value is thus the combined value used upon | ||
49 | * initial exit from idle. | ||
50 | */ | ||
51 | #define DYNTICK_TASK_NEST_WIDTH 7 | ||
52 | #define DYNTICK_TASK_NEST_VALUE ((LLONG_MAX >> DYNTICK_TASK_NEST_WIDTH) + 1) | ||
53 | #define DYNTICK_TASK_NEST_MASK (LLONG_MAX - DYNTICK_TASK_NEST_VALUE + 1) | ||
54 | #define DYNTICK_TASK_FLAG ((DYNTICK_TASK_NEST_VALUE / 8) * 2) | ||
55 | #define DYNTICK_TASK_MASK ((DYNTICK_TASK_NEST_VALUE / 8) * 3) | ||
56 | #define DYNTICK_TASK_EXIT_IDLE (DYNTICK_TASK_NEST_VALUE + \ | ||
57 | DYNTICK_TASK_FLAG) | ||
58 | 35 | ||
59 | 36 | ||
60 | /* | 37 | /* |
diff --git a/kernel/rcu/rcuperf.c b/kernel/rcu/rcuperf.c index 1f87a02c3399..d1ebdf9868bb 100644 --- a/kernel/rcu/rcuperf.c +++ b/kernel/rcu/rcuperf.c | |||
@@ -106,10 +106,6 @@ static int rcu_perf_writer_state; | |||
106 | #define MAX_MEAS 10000 | 106 | #define MAX_MEAS 10000 |
107 | #define MIN_MEAS 100 | 107 | #define MIN_MEAS 100 |
108 | 108 | ||
109 | static int perf_runnable = IS_ENABLED(MODULE); | ||
110 | module_param(perf_runnable, int, 0444); | ||
111 | MODULE_PARM_DESC(perf_runnable, "Start rcuperf at boot"); | ||
112 | |||
113 | /* | 109 | /* |
114 | * Operations vector for selecting different types of tests. | 110 | * Operations vector for selecting different types of tests. |
115 | */ | 111 | */ |
@@ -646,7 +642,7 @@ rcu_perf_init(void) | |||
646 | &tasks_ops, | 642 | &tasks_ops, |
647 | }; | 643 | }; |
648 | 644 | ||
649 | if (!torture_init_begin(perf_type, verbose, &perf_runnable)) | 645 | if (!torture_init_begin(perf_type, verbose)) |
650 | return -EBUSY; | 646 | return -EBUSY; |
651 | 647 | ||
652 | /* Process args and tell the world that the perf'er is on the job. */ | 648 | /* Process args and tell the world that the perf'er is on the job. */ |
diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c index 74f6b0146b98..308e6fdbced8 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c | |||
@@ -187,10 +187,6 @@ static const char *rcu_torture_writer_state_getname(void) | |||
187 | return rcu_torture_writer_state_names[i]; | 187 | return rcu_torture_writer_state_names[i]; |
188 | } | 188 | } |
189 | 189 | ||
190 | static int torture_runnable = IS_ENABLED(MODULE); | ||
191 | module_param(torture_runnable, int, 0444); | ||
192 | MODULE_PARM_DESC(torture_runnable, "Start rcutorture at boot"); | ||
193 | |||
194 | #if defined(CONFIG_RCU_BOOST) && !defined(CONFIG_HOTPLUG_CPU) | 190 | #if defined(CONFIG_RCU_BOOST) && !defined(CONFIG_HOTPLUG_CPU) |
195 | #define rcu_can_boost() 1 | 191 | #define rcu_can_boost() 1 |
196 | #else /* #if defined(CONFIG_RCU_BOOST) && !defined(CONFIG_HOTPLUG_CPU) */ | 192 | #else /* #if defined(CONFIG_RCU_BOOST) && !defined(CONFIG_HOTPLUG_CPU) */ |
@@ -315,11 +311,9 @@ static void rcu_read_delay(struct torture_random_state *rrsp) | |||
315 | } | 311 | } |
316 | if (!(torture_random(rrsp) % (nrealreaders * 2 * shortdelay_us))) | 312 | if (!(torture_random(rrsp) % (nrealreaders * 2 * shortdelay_us))) |
317 | udelay(shortdelay_us); | 313 | udelay(shortdelay_us); |
318 | #ifdef CONFIG_PREEMPT | ||
319 | if (!preempt_count() && | 314 | if (!preempt_count() && |
320 | !(torture_random(rrsp) % (nrealreaders * 20000))) | 315 | !(torture_random(rrsp) % (nrealreaders * 500))) |
321 | preempt_schedule(); /* No QS if preempt_disable() in effect */ | 316 | torture_preempt_schedule(); /* QS only if preemptible. */ |
322 | #endif | ||
323 | } | 317 | } |
324 | 318 | ||
325 | static void rcu_torture_read_unlock(int idx) __releases(RCU) | 319 | static void rcu_torture_read_unlock(int idx) __releases(RCU) |
@@ -1731,7 +1725,7 @@ rcu_torture_init(void) | |||
1731 | &sched_ops, &tasks_ops, | 1725 | &sched_ops, &tasks_ops, |
1732 | }; | 1726 | }; |
1733 | 1727 | ||
1734 | if (!torture_init_begin(torture_type, verbose, &torture_runnable)) | 1728 | if (!torture_init_begin(torture_type, verbose)) |
1735 | return -EBUSY; | 1729 | return -EBUSY; |
1736 | 1730 | ||
1737 | /* Process args and tell the world that the torturer is on the job. */ | 1731 | /* Process args and tell the world that the torturer is on the job. */ |
diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c index 6d5880089ff6..d5cea81378cc 100644 --- a/kernel/rcu/srcutree.c +++ b/kernel/rcu/srcutree.c | |||
@@ -53,6 +53,33 @@ static void srcu_invoke_callbacks(struct work_struct *work); | |||
53 | static void srcu_reschedule(struct srcu_struct *sp, unsigned long delay); | 53 | static void srcu_reschedule(struct srcu_struct *sp, unsigned long delay); |
54 | static void process_srcu(struct work_struct *work); | 54 | static void process_srcu(struct work_struct *work); |
55 | 55 | ||
56 | /* Wrappers for lock acquisition and release, see raw_spin_lock_rcu_node(). */ | ||
57 | #define spin_lock_rcu_node(p) \ | ||
58 | do { \ | ||
59 | spin_lock(&ACCESS_PRIVATE(p, lock)); \ | ||
60 | smp_mb__after_unlock_lock(); \ | ||
61 | } while (0) | ||
62 | |||
63 | #define spin_unlock_rcu_node(p) spin_unlock(&ACCESS_PRIVATE(p, lock)) | ||
64 | |||
65 | #define spin_lock_irq_rcu_node(p) \ | ||
66 | do { \ | ||
67 | spin_lock_irq(&ACCESS_PRIVATE(p, lock)); \ | ||
68 | smp_mb__after_unlock_lock(); \ | ||
69 | } while (0) | ||
70 | |||
71 | #define spin_unlock_irq_rcu_node(p) \ | ||
72 | spin_unlock_irq(&ACCESS_PRIVATE(p, lock)) | ||
73 | |||
74 | #define spin_lock_irqsave_rcu_node(p, flags) \ | ||
75 | do { \ | ||
76 | spin_lock_irqsave(&ACCESS_PRIVATE(p, lock), flags); \ | ||
77 | smp_mb__after_unlock_lock(); \ | ||
78 | } while (0) | ||
79 | |||
80 | #define spin_unlock_irqrestore_rcu_node(p, flags) \ | ||
81 | spin_unlock_irqrestore(&ACCESS_PRIVATE(p, lock), flags) \ | ||
82 | |||
56 | /* | 83 | /* |
57 | * Initialize SRCU combining tree. Note that statically allocated | 84 | * Initialize SRCU combining tree. Note that statically allocated |
58 | * srcu_struct structures might already have srcu_read_lock() and | 85 | * srcu_struct structures might already have srcu_read_lock() and |
@@ -77,7 +104,7 @@ static void init_srcu_struct_nodes(struct srcu_struct *sp, bool is_static) | |||
77 | 104 | ||
78 | /* Each pass through this loop initializes one srcu_node structure. */ | 105 | /* Each pass through this loop initializes one srcu_node structure. */ |
79 | rcu_for_each_node_breadth_first(sp, snp) { | 106 | rcu_for_each_node_breadth_first(sp, snp) { |
80 | raw_spin_lock_init(&ACCESS_PRIVATE(snp, lock)); | 107 | spin_lock_init(&ACCESS_PRIVATE(snp, lock)); |
81 | WARN_ON_ONCE(ARRAY_SIZE(snp->srcu_have_cbs) != | 108 | WARN_ON_ONCE(ARRAY_SIZE(snp->srcu_have_cbs) != |
82 | ARRAY_SIZE(snp->srcu_data_have_cbs)); | 109 | ARRAY_SIZE(snp->srcu_data_have_cbs)); |
83 | for (i = 0; i < ARRAY_SIZE(snp->srcu_have_cbs); i++) { | 110 | for (i = 0; i < ARRAY_SIZE(snp->srcu_have_cbs); i++) { |
@@ -111,7 +138,7 @@ static void init_srcu_struct_nodes(struct srcu_struct *sp, bool is_static) | |||
111 | snp_first = sp->level[level]; | 138 | snp_first = sp->level[level]; |
112 | for_each_possible_cpu(cpu) { | 139 | for_each_possible_cpu(cpu) { |
113 | sdp = per_cpu_ptr(sp->sda, cpu); | 140 | sdp = per_cpu_ptr(sp->sda, cpu); |
114 | raw_spin_lock_init(&ACCESS_PRIVATE(sdp, lock)); | 141 | spin_lock_init(&ACCESS_PRIVATE(sdp, lock)); |
115 | rcu_segcblist_init(&sdp->srcu_cblist); | 142 | rcu_segcblist_init(&sdp->srcu_cblist); |
116 | sdp->srcu_cblist_invoking = false; | 143 | sdp->srcu_cblist_invoking = false; |
117 | sdp->srcu_gp_seq_needed = sp->srcu_gp_seq; | 144 | sdp->srcu_gp_seq_needed = sp->srcu_gp_seq; |
@@ -170,7 +197,7 @@ int __init_srcu_struct(struct srcu_struct *sp, const char *name, | |||
170 | /* Don't re-initialize a lock while it is held. */ | 197 | /* Don't re-initialize a lock while it is held. */ |
171 | debug_check_no_locks_freed((void *)sp, sizeof(*sp)); | 198 | debug_check_no_locks_freed((void *)sp, sizeof(*sp)); |
172 | lockdep_init_map(&sp->dep_map, name, key, 0); | 199 | lockdep_init_map(&sp->dep_map, name, key, 0); |
173 | raw_spin_lock_init(&ACCESS_PRIVATE(sp, lock)); | 200 | spin_lock_init(&ACCESS_PRIVATE(sp, lock)); |
174 | return init_srcu_struct_fields(sp, false); | 201 | return init_srcu_struct_fields(sp, false); |
175 | } | 202 | } |
176 | EXPORT_SYMBOL_GPL(__init_srcu_struct); | 203 | EXPORT_SYMBOL_GPL(__init_srcu_struct); |
@@ -187,7 +214,7 @@ EXPORT_SYMBOL_GPL(__init_srcu_struct); | |||
187 | */ | 214 | */ |
188 | int init_srcu_struct(struct srcu_struct *sp) | 215 | int init_srcu_struct(struct srcu_struct *sp) |
189 | { | 216 | { |
190 | raw_spin_lock_init(&ACCESS_PRIVATE(sp, lock)); | 217 | spin_lock_init(&ACCESS_PRIVATE(sp, lock)); |
191 | return init_srcu_struct_fields(sp, false); | 218 | return init_srcu_struct_fields(sp, false); |
192 | } | 219 | } |
193 | EXPORT_SYMBOL_GPL(init_srcu_struct); | 220 | EXPORT_SYMBOL_GPL(init_srcu_struct); |
@@ -210,13 +237,13 @@ static void check_init_srcu_struct(struct srcu_struct *sp) | |||
210 | /* The smp_load_acquire() pairs with the smp_store_release(). */ | 237 | /* The smp_load_acquire() pairs with the smp_store_release(). */ |
211 | if (!rcu_seq_state(smp_load_acquire(&sp->srcu_gp_seq_needed))) /*^^^*/ | 238 | if (!rcu_seq_state(smp_load_acquire(&sp->srcu_gp_seq_needed))) /*^^^*/ |
212 | return; /* Already initialized. */ | 239 | return; /* Already initialized. */ |
213 | raw_spin_lock_irqsave_rcu_node(sp, flags); | 240 | spin_lock_irqsave_rcu_node(sp, flags); |
214 | if (!rcu_seq_state(sp->srcu_gp_seq_needed)) { | 241 | if (!rcu_seq_state(sp->srcu_gp_seq_needed)) { |
215 | raw_spin_unlock_irqrestore_rcu_node(sp, flags); | 242 | spin_unlock_irqrestore_rcu_node(sp, flags); |
216 | return; | 243 | return; |
217 | } | 244 | } |
218 | init_srcu_struct_fields(sp, true); | 245 | init_srcu_struct_fields(sp, true); |
219 | raw_spin_unlock_irqrestore_rcu_node(sp, flags); | 246 | spin_unlock_irqrestore_rcu_node(sp, flags); |
220 | } | 247 | } |
221 | 248 | ||
222 | /* | 249 | /* |
@@ -513,7 +540,7 @@ static void srcu_gp_end(struct srcu_struct *sp) | |||
513 | mutex_lock(&sp->srcu_cb_mutex); | 540 | mutex_lock(&sp->srcu_cb_mutex); |
514 | 541 | ||
515 | /* End the current grace period. */ | 542 | /* End the current grace period. */ |
516 | raw_spin_lock_irq_rcu_node(sp); | 543 | spin_lock_irq_rcu_node(sp); |
517 | idx = rcu_seq_state(sp->srcu_gp_seq); | 544 | idx = rcu_seq_state(sp->srcu_gp_seq); |
518 | WARN_ON_ONCE(idx != SRCU_STATE_SCAN2); | 545 | WARN_ON_ONCE(idx != SRCU_STATE_SCAN2); |
519 | cbdelay = srcu_get_delay(sp); | 546 | cbdelay = srcu_get_delay(sp); |
@@ -522,7 +549,7 @@ static void srcu_gp_end(struct srcu_struct *sp) | |||
522 | gpseq = rcu_seq_current(&sp->srcu_gp_seq); | 549 | gpseq = rcu_seq_current(&sp->srcu_gp_seq); |
523 | if (ULONG_CMP_LT(sp->srcu_gp_seq_needed_exp, gpseq)) | 550 | if (ULONG_CMP_LT(sp->srcu_gp_seq_needed_exp, gpseq)) |
524 | sp->srcu_gp_seq_needed_exp = gpseq; | 551 | sp->srcu_gp_seq_needed_exp = gpseq; |
525 | raw_spin_unlock_irq_rcu_node(sp); | 552 | spin_unlock_irq_rcu_node(sp); |
526 | mutex_unlock(&sp->srcu_gp_mutex); | 553 | mutex_unlock(&sp->srcu_gp_mutex); |
527 | /* A new grace period can start at this point. But only one. */ | 554 | /* A new grace period can start at this point. But only one. */ |
528 | 555 | ||
@@ -530,7 +557,7 @@ static void srcu_gp_end(struct srcu_struct *sp) | |||
530 | idx = rcu_seq_ctr(gpseq) % ARRAY_SIZE(snp->srcu_have_cbs); | 557 | idx = rcu_seq_ctr(gpseq) % ARRAY_SIZE(snp->srcu_have_cbs); |
531 | idxnext = (idx + 1) % ARRAY_SIZE(snp->srcu_have_cbs); | 558 | idxnext = (idx + 1) % ARRAY_SIZE(snp->srcu_have_cbs); |
532 | rcu_for_each_node_breadth_first(sp, snp) { | 559 | rcu_for_each_node_breadth_first(sp, snp) { |
533 | raw_spin_lock_irq_rcu_node(snp); | 560 | spin_lock_irq_rcu_node(snp); |
534 | cbs = false; | 561 | cbs = false; |
535 | if (snp >= sp->level[rcu_num_lvls - 1]) | 562 | if (snp >= sp->level[rcu_num_lvls - 1]) |
536 | cbs = snp->srcu_have_cbs[idx] == gpseq; | 563 | cbs = snp->srcu_have_cbs[idx] == gpseq; |
@@ -540,7 +567,7 @@ static void srcu_gp_end(struct srcu_struct *sp) | |||
540 | snp->srcu_gp_seq_needed_exp = gpseq; | 567 | snp->srcu_gp_seq_needed_exp = gpseq; |
541 | mask = snp->srcu_data_have_cbs[idx]; | 568 | mask = snp->srcu_data_have_cbs[idx]; |
542 | snp->srcu_data_have_cbs[idx] = 0; | 569 | snp->srcu_data_have_cbs[idx] = 0; |
543 | raw_spin_unlock_irq_rcu_node(snp); | 570 | spin_unlock_irq_rcu_node(snp); |
544 | if (cbs) | 571 | if (cbs) |
545 | srcu_schedule_cbs_snp(sp, snp, mask, cbdelay); | 572 | srcu_schedule_cbs_snp(sp, snp, mask, cbdelay); |
546 | 573 | ||
@@ -548,11 +575,11 @@ static void srcu_gp_end(struct srcu_struct *sp) | |||
548 | if (!(gpseq & counter_wrap_check)) | 575 | if (!(gpseq & counter_wrap_check)) |
549 | for (cpu = snp->grplo; cpu <= snp->grphi; cpu++) { | 576 | for (cpu = snp->grplo; cpu <= snp->grphi; cpu++) { |
550 | sdp = per_cpu_ptr(sp->sda, cpu); | 577 | sdp = per_cpu_ptr(sp->sda, cpu); |
551 | raw_spin_lock_irqsave_rcu_node(sdp, flags); | 578 | spin_lock_irqsave_rcu_node(sdp, flags); |
552 | if (ULONG_CMP_GE(gpseq, | 579 | if (ULONG_CMP_GE(gpseq, |
553 | sdp->srcu_gp_seq_needed + 100)) | 580 | sdp->srcu_gp_seq_needed + 100)) |
554 | sdp->srcu_gp_seq_needed = gpseq; | 581 | sdp->srcu_gp_seq_needed = gpseq; |
555 | raw_spin_unlock_irqrestore_rcu_node(sdp, flags); | 582 | spin_unlock_irqrestore_rcu_node(sdp, flags); |
556 | } | 583 | } |
557 | } | 584 | } |
558 | 585 | ||
@@ -560,17 +587,17 @@ static void srcu_gp_end(struct srcu_struct *sp) | |||
560 | mutex_unlock(&sp->srcu_cb_mutex); | 587 | mutex_unlock(&sp->srcu_cb_mutex); |
561 | 588 | ||
562 | /* Start a new grace period if needed. */ | 589 | /* Start a new grace period if needed. */ |
563 | raw_spin_lock_irq_rcu_node(sp); | 590 | spin_lock_irq_rcu_node(sp); |
564 | gpseq = rcu_seq_current(&sp->srcu_gp_seq); | 591 | gpseq = rcu_seq_current(&sp->srcu_gp_seq); |
565 | if (!rcu_seq_state(gpseq) && | 592 | if (!rcu_seq_state(gpseq) && |
566 | ULONG_CMP_LT(gpseq, sp->srcu_gp_seq_needed)) { | 593 | ULONG_CMP_LT(gpseq, sp->srcu_gp_seq_needed)) { |
567 | srcu_gp_start(sp); | 594 | srcu_gp_start(sp); |
568 | raw_spin_unlock_irq_rcu_node(sp); | 595 | spin_unlock_irq_rcu_node(sp); |
569 | /* Throttle expedited grace periods: Should be rare! */ | 596 | /* Throttle expedited grace periods: Should be rare! */ |
570 | srcu_reschedule(sp, rcu_seq_ctr(gpseq) & 0x3ff | 597 | srcu_reschedule(sp, rcu_seq_ctr(gpseq) & 0x3ff |
571 | ? 0 : SRCU_INTERVAL); | 598 | ? 0 : SRCU_INTERVAL); |
572 | } else { | 599 | } else { |
573 | raw_spin_unlock_irq_rcu_node(sp); | 600 | spin_unlock_irq_rcu_node(sp); |
574 | } | 601 | } |
575 | } | 602 | } |
576 | 603 | ||
@@ -590,18 +617,18 @@ static void srcu_funnel_exp_start(struct srcu_struct *sp, struct srcu_node *snp, | |||
590 | if (rcu_seq_done(&sp->srcu_gp_seq, s) || | 617 | if (rcu_seq_done(&sp->srcu_gp_seq, s) || |
591 | ULONG_CMP_GE(READ_ONCE(snp->srcu_gp_seq_needed_exp), s)) | 618 | ULONG_CMP_GE(READ_ONCE(snp->srcu_gp_seq_needed_exp), s)) |
592 | return; | 619 | return; |
593 | raw_spin_lock_irqsave_rcu_node(snp, flags); | 620 | spin_lock_irqsave_rcu_node(snp, flags); |
594 | if (ULONG_CMP_GE(snp->srcu_gp_seq_needed_exp, s)) { | 621 | if (ULONG_CMP_GE(snp->srcu_gp_seq_needed_exp, s)) { |
595 | raw_spin_unlock_irqrestore_rcu_node(snp, flags); | 622 | spin_unlock_irqrestore_rcu_node(snp, flags); |
596 | return; | 623 | return; |
597 | } | 624 | } |
598 | WRITE_ONCE(snp->srcu_gp_seq_needed_exp, s); | 625 | WRITE_ONCE(snp->srcu_gp_seq_needed_exp, s); |
599 | raw_spin_unlock_irqrestore_rcu_node(snp, flags); | 626 | spin_unlock_irqrestore_rcu_node(snp, flags); |
600 | } | 627 | } |
601 | raw_spin_lock_irqsave_rcu_node(sp, flags); | 628 | spin_lock_irqsave_rcu_node(sp, flags); |
602 | if (!ULONG_CMP_LT(sp->srcu_gp_seq_needed_exp, s)) | 629 | if (!ULONG_CMP_LT(sp->srcu_gp_seq_needed_exp, s)) |
603 | sp->srcu_gp_seq_needed_exp = s; | 630 | sp->srcu_gp_seq_needed_exp = s; |
604 | raw_spin_unlock_irqrestore_rcu_node(sp, flags); | 631 | spin_unlock_irqrestore_rcu_node(sp, flags); |
605 | } | 632 | } |
606 | 633 | ||
607 | /* | 634 | /* |
@@ -623,12 +650,12 @@ static void srcu_funnel_gp_start(struct srcu_struct *sp, struct srcu_data *sdp, | |||
623 | for (; snp != NULL; snp = snp->srcu_parent) { | 650 | for (; snp != NULL; snp = snp->srcu_parent) { |
624 | if (rcu_seq_done(&sp->srcu_gp_seq, s) && snp != sdp->mynode) | 651 | if (rcu_seq_done(&sp->srcu_gp_seq, s) && snp != sdp->mynode) |
625 | return; /* GP already done and CBs recorded. */ | 652 | return; /* GP already done and CBs recorded. */ |
626 | raw_spin_lock_irqsave_rcu_node(snp, flags); | 653 | spin_lock_irqsave_rcu_node(snp, flags); |
627 | if (ULONG_CMP_GE(snp->srcu_have_cbs[idx], s)) { | 654 | if (ULONG_CMP_GE(snp->srcu_have_cbs[idx], s)) { |
628 | snp_seq = snp->srcu_have_cbs[idx]; | 655 | snp_seq = snp->srcu_have_cbs[idx]; |
629 | if (snp == sdp->mynode && snp_seq == s) | 656 | if (snp == sdp->mynode && snp_seq == s) |
630 | snp->srcu_data_have_cbs[idx] |= sdp->grpmask; | 657 | snp->srcu_data_have_cbs[idx] |= sdp->grpmask; |
631 | raw_spin_unlock_irqrestore_rcu_node(snp, flags); | 658 | spin_unlock_irqrestore_rcu_node(snp, flags); |
632 | if (snp == sdp->mynode && snp_seq != s) { | 659 | if (snp == sdp->mynode && snp_seq != s) { |
633 | srcu_schedule_cbs_sdp(sdp, do_norm | 660 | srcu_schedule_cbs_sdp(sdp, do_norm |
634 | ? SRCU_INTERVAL | 661 | ? SRCU_INTERVAL |
@@ -644,11 +671,11 @@ static void srcu_funnel_gp_start(struct srcu_struct *sp, struct srcu_data *sdp, | |||
644 | snp->srcu_data_have_cbs[idx] |= sdp->grpmask; | 671 | snp->srcu_data_have_cbs[idx] |= sdp->grpmask; |
645 | if (!do_norm && ULONG_CMP_LT(snp->srcu_gp_seq_needed_exp, s)) | 672 | if (!do_norm && ULONG_CMP_LT(snp->srcu_gp_seq_needed_exp, s)) |
646 | snp->srcu_gp_seq_needed_exp = s; | 673 | snp->srcu_gp_seq_needed_exp = s; |
647 | raw_spin_unlock_irqrestore_rcu_node(snp, flags); | 674 | spin_unlock_irqrestore_rcu_node(snp, flags); |
648 | } | 675 | } |
649 | 676 | ||
650 | /* Top of tree, must ensure the grace period will be started. */ | 677 | /* Top of tree, must ensure the grace period will be started. */ |
651 | raw_spin_lock_irqsave_rcu_node(sp, flags); | 678 | spin_lock_irqsave_rcu_node(sp, flags); |
652 | if (ULONG_CMP_LT(sp->srcu_gp_seq_needed, s)) { | 679 | if (ULONG_CMP_LT(sp->srcu_gp_seq_needed, s)) { |
653 | /* | 680 | /* |
654 | * Record need for grace period s. Pair with load | 681 | * Record need for grace period s. Pair with load |
@@ -667,7 +694,7 @@ static void srcu_funnel_gp_start(struct srcu_struct *sp, struct srcu_data *sdp, | |||
667 | queue_delayed_work(system_power_efficient_wq, &sp->work, | 694 | queue_delayed_work(system_power_efficient_wq, &sp->work, |
668 | srcu_get_delay(sp)); | 695 | srcu_get_delay(sp)); |
669 | } | 696 | } |
670 | raw_spin_unlock_irqrestore_rcu_node(sp, flags); | 697 | spin_unlock_irqrestore_rcu_node(sp, flags); |
671 | } | 698 | } |
672 | 699 | ||
673 | /* | 700 | /* |
@@ -830,7 +857,7 @@ void __call_srcu(struct srcu_struct *sp, struct rcu_head *rhp, | |||
830 | rhp->func = func; | 857 | rhp->func = func; |
831 | local_irq_save(flags); | 858 | local_irq_save(flags); |
832 | sdp = this_cpu_ptr(sp->sda); | 859 | sdp = this_cpu_ptr(sp->sda); |
833 | raw_spin_lock_rcu_node(sdp); | 860 | spin_lock_rcu_node(sdp); |
834 | rcu_segcblist_enqueue(&sdp->srcu_cblist, rhp, false); | 861 | rcu_segcblist_enqueue(&sdp->srcu_cblist, rhp, false); |
835 | rcu_segcblist_advance(&sdp->srcu_cblist, | 862 | rcu_segcblist_advance(&sdp->srcu_cblist, |
836 | rcu_seq_current(&sp->srcu_gp_seq)); | 863 | rcu_seq_current(&sp->srcu_gp_seq)); |
@@ -844,7 +871,7 @@ void __call_srcu(struct srcu_struct *sp, struct rcu_head *rhp, | |||
844 | sdp->srcu_gp_seq_needed_exp = s; | 871 | sdp->srcu_gp_seq_needed_exp = s; |
845 | needexp = true; | 872 | needexp = true; |
846 | } | 873 | } |
847 | raw_spin_unlock_irqrestore_rcu_node(sdp, flags); | 874 | spin_unlock_irqrestore_rcu_node(sdp, flags); |
848 | if (needgp) | 875 | if (needgp) |
849 | srcu_funnel_gp_start(sp, sdp, s, do_norm); | 876 | srcu_funnel_gp_start(sp, sdp, s, do_norm); |
850 | else if (needexp) | 877 | else if (needexp) |
@@ -900,7 +927,7 @@ static void __synchronize_srcu(struct srcu_struct *sp, bool do_norm) | |||
900 | 927 | ||
901 | /* | 928 | /* |
902 | * Make sure that later code is ordered after the SRCU grace | 929 | * Make sure that later code is ordered after the SRCU grace |
903 | * period. This pairs with the raw_spin_lock_irq_rcu_node() | 930 | * period. This pairs with the spin_lock_irq_rcu_node() |
904 | * in srcu_invoke_callbacks(). Unlike Tree RCU, this is needed | 931 | * in srcu_invoke_callbacks(). Unlike Tree RCU, this is needed |
905 | * because the current CPU might have been totally uninvolved with | 932 | * because the current CPU might have been totally uninvolved with |
906 | * (and thus unordered against) that grace period. | 933 | * (and thus unordered against) that grace period. |
@@ -1024,7 +1051,7 @@ void srcu_barrier(struct srcu_struct *sp) | |||
1024 | */ | 1051 | */ |
1025 | for_each_possible_cpu(cpu) { | 1052 | for_each_possible_cpu(cpu) { |
1026 | sdp = per_cpu_ptr(sp->sda, cpu); | 1053 | sdp = per_cpu_ptr(sp->sda, cpu); |
1027 | raw_spin_lock_irq_rcu_node(sdp); | 1054 | spin_lock_irq_rcu_node(sdp); |
1028 | atomic_inc(&sp->srcu_barrier_cpu_cnt); | 1055 | atomic_inc(&sp->srcu_barrier_cpu_cnt); |
1029 | sdp->srcu_barrier_head.func = srcu_barrier_cb; | 1056 | sdp->srcu_barrier_head.func = srcu_barrier_cb; |
1030 | debug_rcu_head_queue(&sdp->srcu_barrier_head); | 1057 | debug_rcu_head_queue(&sdp->srcu_barrier_head); |
@@ -1033,7 +1060,7 @@ void srcu_barrier(struct srcu_struct *sp) | |||
1033 | debug_rcu_head_unqueue(&sdp->srcu_barrier_head); | 1060 | debug_rcu_head_unqueue(&sdp->srcu_barrier_head); |
1034 | atomic_dec(&sp->srcu_barrier_cpu_cnt); | 1061 | atomic_dec(&sp->srcu_barrier_cpu_cnt); |
1035 | } | 1062 | } |
1036 | raw_spin_unlock_irq_rcu_node(sdp); | 1063 | spin_unlock_irq_rcu_node(sdp); |
1037 | } | 1064 | } |
1038 | 1065 | ||
1039 | /* Remove the initial count, at which point reaching zero can happen. */ | 1066 | /* Remove the initial count, at which point reaching zero can happen. */ |
@@ -1082,17 +1109,17 @@ static void srcu_advance_state(struct srcu_struct *sp) | |||
1082 | */ | 1109 | */ |
1083 | idx = rcu_seq_state(smp_load_acquire(&sp->srcu_gp_seq)); /* ^^^ */ | 1110 | idx = rcu_seq_state(smp_load_acquire(&sp->srcu_gp_seq)); /* ^^^ */ |
1084 | if (idx == SRCU_STATE_IDLE) { | 1111 | if (idx == SRCU_STATE_IDLE) { |
1085 | raw_spin_lock_irq_rcu_node(sp); | 1112 | spin_lock_irq_rcu_node(sp); |
1086 | if (ULONG_CMP_GE(sp->srcu_gp_seq, sp->srcu_gp_seq_needed)) { | 1113 | if (ULONG_CMP_GE(sp->srcu_gp_seq, sp->srcu_gp_seq_needed)) { |
1087 | WARN_ON_ONCE(rcu_seq_state(sp->srcu_gp_seq)); | 1114 | WARN_ON_ONCE(rcu_seq_state(sp->srcu_gp_seq)); |
1088 | raw_spin_unlock_irq_rcu_node(sp); | 1115 | spin_unlock_irq_rcu_node(sp); |
1089 | mutex_unlock(&sp->srcu_gp_mutex); | 1116 | mutex_unlock(&sp->srcu_gp_mutex); |
1090 | return; | 1117 | return; |
1091 | } | 1118 | } |
1092 | idx = rcu_seq_state(READ_ONCE(sp->srcu_gp_seq)); | 1119 | idx = rcu_seq_state(READ_ONCE(sp->srcu_gp_seq)); |
1093 | if (idx == SRCU_STATE_IDLE) | 1120 | if (idx == SRCU_STATE_IDLE) |
1094 | srcu_gp_start(sp); | 1121 | srcu_gp_start(sp); |
1095 | raw_spin_unlock_irq_rcu_node(sp); | 1122 | spin_unlock_irq_rcu_node(sp); |
1096 | if (idx != SRCU_STATE_IDLE) { | 1123 | if (idx != SRCU_STATE_IDLE) { |
1097 | mutex_unlock(&sp->srcu_gp_mutex); | 1124 | mutex_unlock(&sp->srcu_gp_mutex); |
1098 | return; /* Someone else started the grace period. */ | 1125 | return; /* Someone else started the grace period. */ |
@@ -1141,19 +1168,19 @@ static void srcu_invoke_callbacks(struct work_struct *work) | |||
1141 | sdp = container_of(work, struct srcu_data, work.work); | 1168 | sdp = container_of(work, struct srcu_data, work.work); |
1142 | sp = sdp->sp; | 1169 | sp = sdp->sp; |
1143 | rcu_cblist_init(&ready_cbs); | 1170 | rcu_cblist_init(&ready_cbs); |
1144 | raw_spin_lock_irq_rcu_node(sdp); | 1171 | spin_lock_irq_rcu_node(sdp); |
1145 | rcu_segcblist_advance(&sdp->srcu_cblist, | 1172 | rcu_segcblist_advance(&sdp->srcu_cblist, |
1146 | rcu_seq_current(&sp->srcu_gp_seq)); | 1173 | rcu_seq_current(&sp->srcu_gp_seq)); |
1147 | if (sdp->srcu_cblist_invoking || | 1174 | if (sdp->srcu_cblist_invoking || |
1148 | !rcu_segcblist_ready_cbs(&sdp->srcu_cblist)) { | 1175 | !rcu_segcblist_ready_cbs(&sdp->srcu_cblist)) { |
1149 | raw_spin_unlock_irq_rcu_node(sdp); | 1176 | spin_unlock_irq_rcu_node(sdp); |
1150 | return; /* Someone else on the job or nothing to do. */ | 1177 | return; /* Someone else on the job or nothing to do. */ |
1151 | } | 1178 | } |
1152 | 1179 | ||
1153 | /* We are on the job! Extract and invoke ready callbacks. */ | 1180 | /* We are on the job! Extract and invoke ready callbacks. */ |
1154 | sdp->srcu_cblist_invoking = true; | 1181 | sdp->srcu_cblist_invoking = true; |
1155 | rcu_segcblist_extract_done_cbs(&sdp->srcu_cblist, &ready_cbs); | 1182 | rcu_segcblist_extract_done_cbs(&sdp->srcu_cblist, &ready_cbs); |
1156 | raw_spin_unlock_irq_rcu_node(sdp); | 1183 | spin_unlock_irq_rcu_node(sdp); |
1157 | rhp = rcu_cblist_dequeue(&ready_cbs); | 1184 | rhp = rcu_cblist_dequeue(&ready_cbs); |
1158 | for (; rhp != NULL; rhp = rcu_cblist_dequeue(&ready_cbs)) { | 1185 | for (; rhp != NULL; rhp = rcu_cblist_dequeue(&ready_cbs)) { |
1159 | debug_rcu_head_unqueue(rhp); | 1186 | debug_rcu_head_unqueue(rhp); |
@@ -1166,13 +1193,13 @@ static void srcu_invoke_callbacks(struct work_struct *work) | |||
1166 | * Update counts, accelerate new callbacks, and if needed, | 1193 | * Update counts, accelerate new callbacks, and if needed, |
1167 | * schedule another round of callback invocation. | 1194 | * schedule another round of callback invocation. |
1168 | */ | 1195 | */ |
1169 | raw_spin_lock_irq_rcu_node(sdp); | 1196 | spin_lock_irq_rcu_node(sdp); |
1170 | rcu_segcblist_insert_count(&sdp->srcu_cblist, &ready_cbs); | 1197 | rcu_segcblist_insert_count(&sdp->srcu_cblist, &ready_cbs); |
1171 | (void)rcu_segcblist_accelerate(&sdp->srcu_cblist, | 1198 | (void)rcu_segcblist_accelerate(&sdp->srcu_cblist, |
1172 | rcu_seq_snap(&sp->srcu_gp_seq)); | 1199 | rcu_seq_snap(&sp->srcu_gp_seq)); |
1173 | sdp->srcu_cblist_invoking = false; | 1200 | sdp->srcu_cblist_invoking = false; |
1174 | more = rcu_segcblist_ready_cbs(&sdp->srcu_cblist); | 1201 | more = rcu_segcblist_ready_cbs(&sdp->srcu_cblist); |
1175 | raw_spin_unlock_irq_rcu_node(sdp); | 1202 | spin_unlock_irq_rcu_node(sdp); |
1176 | if (more) | 1203 | if (more) |
1177 | srcu_schedule_cbs_sdp(sdp, 0); | 1204 | srcu_schedule_cbs_sdp(sdp, 0); |
1178 | } | 1205 | } |
@@ -1185,7 +1212,7 @@ static void srcu_reschedule(struct srcu_struct *sp, unsigned long delay) | |||
1185 | { | 1212 | { |
1186 | bool pushgp = true; | 1213 | bool pushgp = true; |
1187 | 1214 | ||
1188 | raw_spin_lock_irq_rcu_node(sp); | 1215 | spin_lock_irq_rcu_node(sp); |
1189 | if (ULONG_CMP_GE(sp->srcu_gp_seq, sp->srcu_gp_seq_needed)) { | 1216 | if (ULONG_CMP_GE(sp->srcu_gp_seq, sp->srcu_gp_seq_needed)) { |
1190 | if (!WARN_ON_ONCE(rcu_seq_state(sp->srcu_gp_seq))) { | 1217 | if (!WARN_ON_ONCE(rcu_seq_state(sp->srcu_gp_seq))) { |
1191 | /* All requests fulfilled, time to go idle. */ | 1218 | /* All requests fulfilled, time to go idle. */ |
@@ -1195,7 +1222,7 @@ static void srcu_reschedule(struct srcu_struct *sp, unsigned long delay) | |||
1195 | /* Outstanding request and no GP. Start one. */ | 1222 | /* Outstanding request and no GP. Start one. */ |
1196 | srcu_gp_start(sp); | 1223 | srcu_gp_start(sp); |
1197 | } | 1224 | } |
1198 | raw_spin_unlock_irq_rcu_node(sp); | 1225 | spin_unlock_irq_rcu_node(sp); |
1199 | 1226 | ||
1200 | if (pushgp) | 1227 | if (pushgp) |
1201 | queue_delayed_work(system_power_efficient_wq, &sp->work, delay); | 1228 | queue_delayed_work(system_power_efficient_wq, &sp->work, delay); |
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index f9c0ca2ccf0c..491bdf39f276 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c | |||
@@ -265,25 +265,12 @@ void rcu_bh_qs(void) | |||
265 | #endif | 265 | #endif |
266 | 266 | ||
267 | static DEFINE_PER_CPU(struct rcu_dynticks, rcu_dynticks) = { | 267 | static DEFINE_PER_CPU(struct rcu_dynticks, rcu_dynticks) = { |
268 | .dynticks_nesting = DYNTICK_TASK_EXIT_IDLE, | 268 | .dynticks_nesting = 1, |
269 | .dynticks_nmi_nesting = DYNTICK_IRQ_NONIDLE, | ||
269 | .dynticks = ATOMIC_INIT(RCU_DYNTICK_CTRL_CTR), | 270 | .dynticks = ATOMIC_INIT(RCU_DYNTICK_CTRL_CTR), |
270 | }; | 271 | }; |
271 | 272 | ||
272 | /* | 273 | /* |
273 | * There's a few places, currently just in the tracing infrastructure, | ||
274 | * that uses rcu_irq_enter() to make sure RCU is watching. But there's | ||
275 | * a small location where that will not even work. In those cases | ||
276 | * rcu_irq_enter_disabled() needs to be checked to make sure rcu_irq_enter() | ||
277 | * can be called. | ||
278 | */ | ||
279 | static DEFINE_PER_CPU(bool, disable_rcu_irq_enter); | ||
280 | |||
281 | bool rcu_irq_enter_disabled(void) | ||
282 | { | ||
283 | return this_cpu_read(disable_rcu_irq_enter); | ||
284 | } | ||
285 | |||
286 | /* | ||
287 | * Record entry into an extended quiescent state. This is only to be | 274 | * Record entry into an extended quiescent state. This is only to be |
288 | * called when not already in an extended quiescent state. | 275 | * called when not already in an extended quiescent state. |
289 | */ | 276 | */ |
@@ -762,68 +749,39 @@ cpu_needs_another_gp(struct rcu_state *rsp, struct rcu_data *rdp) | |||
762 | } | 749 | } |
763 | 750 | ||
764 | /* | 751 | /* |
765 | * rcu_eqs_enter_common - current CPU is entering an extended quiescent state | 752 | * Enter an RCU extended quiescent state, which can be either the |
753 | * idle loop or adaptive-tickless usermode execution. | ||
766 | * | 754 | * |
767 | * Enter idle, doing appropriate accounting. The caller must have | 755 | * We crowbar the ->dynticks_nmi_nesting field to zero to allow for |
768 | * disabled interrupts. | 756 | * the possibility of usermode upcalls having messed up our count |
757 | * of interrupt nesting level during the prior busy period. | ||
769 | */ | 758 | */ |
770 | static void rcu_eqs_enter_common(bool user) | 759 | static void rcu_eqs_enter(bool user) |
771 | { | 760 | { |
772 | struct rcu_state *rsp; | 761 | struct rcu_state *rsp; |
773 | struct rcu_data *rdp; | 762 | struct rcu_data *rdp; |
774 | struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks); | 763 | struct rcu_dynticks *rdtp; |
775 | 764 | ||
776 | lockdep_assert_irqs_disabled(); | 765 | rdtp = this_cpu_ptr(&rcu_dynticks); |
777 | trace_rcu_dyntick(TPS("Start"), rdtp->dynticks_nesting, 0); | 766 | WRITE_ONCE(rdtp->dynticks_nmi_nesting, 0); |
778 | if (IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && | 767 | WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && |
779 | !user && !is_idle_task(current)) { | 768 | rdtp->dynticks_nesting == 0); |
780 | struct task_struct *idle __maybe_unused = | 769 | if (rdtp->dynticks_nesting != 1) { |
781 | idle_task(smp_processor_id()); | 770 | rdtp->dynticks_nesting--; |
782 | 771 | return; | |
783 | trace_rcu_dyntick(TPS("Error on entry: not idle task"), rdtp->dynticks_nesting, 0); | ||
784 | rcu_ftrace_dump(DUMP_ORIG); | ||
785 | WARN_ONCE(1, "Current pid: %d comm: %s / Idle pid: %d comm: %s", | ||
786 | current->pid, current->comm, | ||
787 | idle->pid, idle->comm); /* must be idle task! */ | ||
788 | } | 772 | } |
773 | |||
774 | lockdep_assert_irqs_disabled(); | ||
775 | trace_rcu_dyntick(TPS("Start"), rdtp->dynticks_nesting, 0, rdtp->dynticks); | ||
776 | WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && !user && !is_idle_task(current)); | ||
789 | for_each_rcu_flavor(rsp) { | 777 | for_each_rcu_flavor(rsp) { |
790 | rdp = this_cpu_ptr(rsp->rda); | 778 | rdp = this_cpu_ptr(rsp->rda); |
791 | do_nocb_deferred_wakeup(rdp); | 779 | do_nocb_deferred_wakeup(rdp); |
792 | } | 780 | } |
793 | rcu_prepare_for_idle(); | 781 | rcu_prepare_for_idle(); |
794 | __this_cpu_inc(disable_rcu_irq_enter); | 782 | WRITE_ONCE(rdtp->dynticks_nesting, 0); /* Avoid irq-access tearing. */ |
795 | rdtp->dynticks_nesting = 0; /* Breaks tracing momentarily. */ | 783 | rcu_dynticks_eqs_enter(); |
796 | rcu_dynticks_eqs_enter(); /* After this, tracing works again. */ | ||
797 | __this_cpu_dec(disable_rcu_irq_enter); | ||
798 | rcu_dynticks_task_enter(); | 784 | rcu_dynticks_task_enter(); |
799 | |||
800 | /* | ||
801 | * It is illegal to enter an extended quiescent state while | ||
802 | * in an RCU read-side critical section. | ||
803 | */ | ||
804 | RCU_LOCKDEP_WARN(lock_is_held(&rcu_lock_map), | ||
805 | "Illegal idle entry in RCU read-side critical section."); | ||
806 | RCU_LOCKDEP_WARN(lock_is_held(&rcu_bh_lock_map), | ||
807 | "Illegal idle entry in RCU-bh read-side critical section."); | ||
808 | RCU_LOCKDEP_WARN(lock_is_held(&rcu_sched_lock_map), | ||
809 | "Illegal idle entry in RCU-sched read-side critical section."); | ||
810 | } | ||
811 | |||
812 | /* | ||
813 | * Enter an RCU extended quiescent state, which can be either the | ||
814 | * idle loop or adaptive-tickless usermode execution. | ||
815 | */ | ||
816 | static void rcu_eqs_enter(bool user) | ||
817 | { | ||
818 | struct rcu_dynticks *rdtp; | ||
819 | |||
820 | rdtp = this_cpu_ptr(&rcu_dynticks); | ||
821 | WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && | ||
822 | (rdtp->dynticks_nesting & DYNTICK_TASK_NEST_MASK) == 0); | ||
823 | if ((rdtp->dynticks_nesting & DYNTICK_TASK_NEST_MASK) == DYNTICK_TASK_NEST_VALUE) | ||
824 | rcu_eqs_enter_common(user); | ||
825 | else | ||
826 | rdtp->dynticks_nesting -= DYNTICK_TASK_NEST_VALUE; | ||
827 | } | 785 | } |
828 | 786 | ||
829 | /** | 787 | /** |
@@ -834,10 +792,6 @@ static void rcu_eqs_enter(bool user) | |||
834 | * critical sections can occur in irq handlers in idle, a possibility | 792 | * critical sections can occur in irq handlers in idle, a possibility |
835 | * handled by irq_enter() and irq_exit().) | 793 | * handled by irq_enter() and irq_exit().) |
836 | * | 794 | * |
837 | * We crowbar the ->dynticks_nesting field to zero to allow for | ||
838 | * the possibility of usermode upcalls having messed up our count | ||
839 | * of interrupt nesting level during the prior busy period. | ||
840 | * | ||
841 | * If you add or remove a call to rcu_idle_enter(), be sure to test with | 795 | * If you add or remove a call to rcu_idle_enter(), be sure to test with |
842 | * CONFIG_RCU_EQS_DEBUG=y. | 796 | * CONFIG_RCU_EQS_DEBUG=y. |
843 | */ | 797 | */ |
@@ -867,6 +821,46 @@ void rcu_user_enter(void) | |||
867 | #endif /* CONFIG_NO_HZ_FULL */ | 821 | #endif /* CONFIG_NO_HZ_FULL */ |
868 | 822 | ||
869 | /** | 823 | /** |
824 | * rcu_nmi_exit - inform RCU of exit from NMI context | ||
825 | * | ||
826 | * If we are returning from the outermost NMI handler that interrupted an | ||
827 | * RCU-idle period, update rdtp->dynticks and rdtp->dynticks_nmi_nesting | ||
828 | * to let the RCU grace-period handling know that the CPU is back to | ||
829 | * being RCU-idle. | ||
830 | * | ||
831 | * If you add or remove a call to rcu_nmi_exit(), be sure to test | ||
832 | * with CONFIG_RCU_EQS_DEBUG=y. | ||
833 | */ | ||
834 | void rcu_nmi_exit(void) | ||
835 | { | ||
836 | struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks); | ||
837 | |||
838 | /* | ||
839 | * Check for ->dynticks_nmi_nesting underflow and bad ->dynticks. | ||
840 | * (We are exiting an NMI handler, so RCU better be paying attention | ||
841 | * to us!) | ||
842 | */ | ||
843 | WARN_ON_ONCE(rdtp->dynticks_nmi_nesting <= 0); | ||
844 | WARN_ON_ONCE(rcu_dynticks_curr_cpu_in_eqs()); | ||
845 | |||
846 | /* | ||
847 | * If the nesting level is not 1, the CPU wasn't RCU-idle, so | ||
848 | * leave it in non-RCU-idle state. | ||
849 | */ | ||
850 | if (rdtp->dynticks_nmi_nesting != 1) { | ||
851 | trace_rcu_dyntick(TPS("--="), rdtp->dynticks_nmi_nesting, rdtp->dynticks_nmi_nesting - 2, rdtp->dynticks); | ||
852 | WRITE_ONCE(rdtp->dynticks_nmi_nesting, /* No store tearing. */ | ||
853 | rdtp->dynticks_nmi_nesting - 2); | ||
854 | return; | ||
855 | } | ||
856 | |||
857 | /* This NMI interrupted an RCU-idle CPU, restore RCU-idleness. */ | ||
858 | trace_rcu_dyntick(TPS("Startirq"), rdtp->dynticks_nmi_nesting, 0, rdtp->dynticks); | ||
859 | WRITE_ONCE(rdtp->dynticks_nmi_nesting, 0); /* Avoid store tearing. */ | ||
860 | rcu_dynticks_eqs_enter(); | ||
861 | } | ||
862 | |||
863 | /** | ||
870 | * rcu_irq_exit - inform RCU that current CPU is exiting irq towards idle | 864 | * rcu_irq_exit - inform RCU that current CPU is exiting irq towards idle |
871 | * | 865 | * |
872 | * Exit from an interrupt handler, which might possibly result in entering | 866 | * Exit from an interrupt handler, which might possibly result in entering |
@@ -875,8 +869,8 @@ void rcu_user_enter(void) | |||
875 | * | 869 | * |
876 | * This code assumes that the idle loop never does anything that might | 870 | * This code assumes that the idle loop never does anything that might |
877 | * result in unbalanced calls to irq_enter() and irq_exit(). If your | 871 | * result in unbalanced calls to irq_enter() and irq_exit(). If your |
878 | * architecture violates this assumption, RCU will give you what you | 872 | * architecture's idle loop violates this assumption, RCU will give you what |
879 | * deserve, good and hard. But very infrequently and irreproducibly. | 873 | * you deserve, good and hard. But very infrequently and irreproducibly. |
880 | * | 874 | * |
881 | * Use things like work queues to work around this limitation. | 875 | * Use things like work queues to work around this limitation. |
882 | * | 876 | * |
@@ -887,23 +881,14 @@ void rcu_user_enter(void) | |||
887 | */ | 881 | */ |
888 | void rcu_irq_exit(void) | 882 | void rcu_irq_exit(void) |
889 | { | 883 | { |
890 | struct rcu_dynticks *rdtp; | 884 | struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks); |
891 | 885 | ||
892 | lockdep_assert_irqs_disabled(); | 886 | lockdep_assert_irqs_disabled(); |
893 | rdtp = this_cpu_ptr(&rcu_dynticks); | 887 | if (rdtp->dynticks_nmi_nesting == 1) |
894 | 888 | rcu_prepare_for_idle(); | |
895 | /* Page faults can happen in NMI handlers, so check... */ | 889 | rcu_nmi_exit(); |
896 | if (rdtp->dynticks_nmi_nesting) | 890 | if (rdtp->dynticks_nmi_nesting == 0) |
897 | return; | 891 | rcu_dynticks_task_enter(); |
898 | |||
899 | WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && | ||
900 | rdtp->dynticks_nesting < 1); | ||
901 | if (rdtp->dynticks_nesting <= 1) { | ||
902 | rcu_eqs_enter_common(true); | ||
903 | } else { | ||
904 | trace_rcu_dyntick(TPS("--="), rdtp->dynticks_nesting, rdtp->dynticks_nesting - 1); | ||
905 | rdtp->dynticks_nesting--; | ||
906 | } | ||
907 | } | 892 | } |
908 | 893 | ||
909 | /* | 894 | /* |
@@ -922,55 +907,33 @@ void rcu_irq_exit_irqson(void) | |||
922 | } | 907 | } |
923 | 908 | ||
924 | /* | 909 | /* |
925 | * rcu_eqs_exit_common - current CPU moving away from extended quiescent state | ||
926 | * | ||
927 | * If the new value of the ->dynticks_nesting counter was previously zero, | ||
928 | * we really have exited idle, and must do the appropriate accounting. | ||
929 | * The caller must have disabled interrupts. | ||
930 | */ | ||
931 | static void rcu_eqs_exit_common(long long oldval, int user) | ||
932 | { | ||
933 | RCU_TRACE(struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);) | ||
934 | |||
935 | rcu_dynticks_task_exit(); | ||
936 | rcu_dynticks_eqs_exit(); | ||
937 | rcu_cleanup_after_idle(); | ||
938 | trace_rcu_dyntick(TPS("End"), oldval, rdtp->dynticks_nesting); | ||
939 | if (IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && | ||
940 | !user && !is_idle_task(current)) { | ||
941 | struct task_struct *idle __maybe_unused = | ||
942 | idle_task(smp_processor_id()); | ||
943 | |||
944 | trace_rcu_dyntick(TPS("Error on exit: not idle task"), | ||
945 | oldval, rdtp->dynticks_nesting); | ||
946 | rcu_ftrace_dump(DUMP_ORIG); | ||
947 | WARN_ONCE(1, "Current pid: %d comm: %s / Idle pid: %d comm: %s", | ||
948 | current->pid, current->comm, | ||
949 | idle->pid, idle->comm); /* must be idle task! */ | ||
950 | } | ||
951 | } | ||
952 | |||
953 | /* | ||
954 | * Exit an RCU extended quiescent state, which can be either the | 910 | * Exit an RCU extended quiescent state, which can be either the |
955 | * idle loop or adaptive-tickless usermode execution. | 911 | * idle loop or adaptive-tickless usermode execution. |
912 | * | ||
913 | * We crowbar the ->dynticks_nmi_nesting field to DYNTICK_IRQ_NONIDLE to | ||
914 | * allow for the possibility of usermode upcalls messing up our count of | ||
915 | * interrupt nesting level during the busy period that is just now starting. | ||
956 | */ | 916 | */ |
957 | static void rcu_eqs_exit(bool user) | 917 | static void rcu_eqs_exit(bool user) |
958 | { | 918 | { |
959 | struct rcu_dynticks *rdtp; | 919 | struct rcu_dynticks *rdtp; |
960 | long long oldval; | 920 | long oldval; |
961 | 921 | ||
962 | lockdep_assert_irqs_disabled(); | 922 | lockdep_assert_irqs_disabled(); |
963 | rdtp = this_cpu_ptr(&rcu_dynticks); | 923 | rdtp = this_cpu_ptr(&rcu_dynticks); |
964 | oldval = rdtp->dynticks_nesting; | 924 | oldval = rdtp->dynticks_nesting; |
965 | WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && oldval < 0); | 925 | WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && oldval < 0); |
966 | if (oldval & DYNTICK_TASK_NEST_MASK) { | 926 | if (oldval) { |
967 | rdtp->dynticks_nesting += DYNTICK_TASK_NEST_VALUE; | 927 | rdtp->dynticks_nesting++; |
968 | } else { | 928 | return; |
969 | __this_cpu_inc(disable_rcu_irq_enter); | ||
970 | rdtp->dynticks_nesting = DYNTICK_TASK_EXIT_IDLE; | ||
971 | rcu_eqs_exit_common(oldval, user); | ||
972 | __this_cpu_dec(disable_rcu_irq_enter); | ||
973 | } | 929 | } |
930 | rcu_dynticks_task_exit(); | ||
931 | rcu_dynticks_eqs_exit(); | ||
932 | rcu_cleanup_after_idle(); | ||
933 | trace_rcu_dyntick(TPS("End"), rdtp->dynticks_nesting, 1, rdtp->dynticks); | ||
934 | WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && !user && !is_idle_task(current)); | ||
935 | WRITE_ONCE(rdtp->dynticks_nesting, 1); | ||
936 | WRITE_ONCE(rdtp->dynticks_nmi_nesting, DYNTICK_IRQ_NONIDLE); | ||
974 | } | 937 | } |
975 | 938 | ||
976 | /** | 939 | /** |
@@ -979,11 +942,6 @@ static void rcu_eqs_exit(bool user) | |||
979 | * Exit idle mode, in other words, -enter- the mode in which RCU | 942 | * Exit idle mode, in other words, -enter- the mode in which RCU |
980 | * read-side critical sections can occur. | 943 | * read-side critical sections can occur. |
981 | * | 944 | * |
982 | * We crowbar the ->dynticks_nesting field to DYNTICK_TASK_NEST to | ||
983 | * allow for the possibility of usermode upcalls messing up our count | ||
984 | * of interrupt nesting level during the busy period that is just | ||
985 | * now starting. | ||
986 | * | ||
987 | * If you add or remove a call to rcu_idle_exit(), be sure to test with | 945 | * If you add or remove a call to rcu_idle_exit(), be sure to test with |
988 | * CONFIG_RCU_EQS_DEBUG=y. | 946 | * CONFIG_RCU_EQS_DEBUG=y. |
989 | */ | 947 | */ |
@@ -1013,65 +971,6 @@ void rcu_user_exit(void) | |||
1013 | #endif /* CONFIG_NO_HZ_FULL */ | 971 | #endif /* CONFIG_NO_HZ_FULL */ |
1014 | 972 | ||
1015 | /** | 973 | /** |
1016 | * rcu_irq_enter - inform RCU that current CPU is entering irq away from idle | ||
1017 | * | ||
1018 | * Enter an interrupt handler, which might possibly result in exiting | ||
1019 | * idle mode, in other words, entering the mode in which read-side critical | ||
1020 | * sections can occur. The caller must have disabled interrupts. | ||
1021 | * | ||
1022 | * Note that the Linux kernel is fully capable of entering an interrupt | ||
1023 | * handler that it never exits, for example when doing upcalls to | ||
1024 | * user mode! This code assumes that the idle loop never does upcalls to | ||
1025 | * user mode. If your architecture does do upcalls from the idle loop (or | ||
1026 | * does anything else that results in unbalanced calls to the irq_enter() | ||
1027 | * and irq_exit() functions), RCU will give you what you deserve, good | ||
1028 | * and hard. But very infrequently and irreproducibly. | ||
1029 | * | ||
1030 | * Use things like work queues to work around this limitation. | ||
1031 | * | ||
1032 | * You have been warned. | ||
1033 | * | ||
1034 | * If you add or remove a call to rcu_irq_enter(), be sure to test with | ||
1035 | * CONFIG_RCU_EQS_DEBUG=y. | ||
1036 | */ | ||
1037 | void rcu_irq_enter(void) | ||
1038 | { | ||
1039 | struct rcu_dynticks *rdtp; | ||
1040 | long long oldval; | ||
1041 | |||
1042 | lockdep_assert_irqs_disabled(); | ||
1043 | rdtp = this_cpu_ptr(&rcu_dynticks); | ||
1044 | |||
1045 | /* Page faults can happen in NMI handlers, so check... */ | ||
1046 | if (rdtp->dynticks_nmi_nesting) | ||
1047 | return; | ||
1048 | |||
1049 | oldval = rdtp->dynticks_nesting; | ||
1050 | rdtp->dynticks_nesting++; | ||
1051 | WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && | ||
1052 | rdtp->dynticks_nesting == 0); | ||
1053 | if (oldval) | ||
1054 | trace_rcu_dyntick(TPS("++="), oldval, rdtp->dynticks_nesting); | ||
1055 | else | ||
1056 | rcu_eqs_exit_common(oldval, true); | ||
1057 | } | ||
1058 | |||
1059 | /* | ||
1060 | * Wrapper for rcu_irq_enter() where interrupts are enabled. | ||
1061 | * | ||
1062 | * If you add or remove a call to rcu_irq_enter_irqson(), be sure to test | ||
1063 | * with CONFIG_RCU_EQS_DEBUG=y. | ||
1064 | */ | ||
1065 | void rcu_irq_enter_irqson(void) | ||
1066 | { | ||
1067 | unsigned long flags; | ||
1068 | |||
1069 | local_irq_save(flags); | ||
1070 | rcu_irq_enter(); | ||
1071 | local_irq_restore(flags); | ||
1072 | } | ||
1073 | |||
1074 | /** | ||
1075 | * rcu_nmi_enter - inform RCU of entry to NMI context | 974 | * rcu_nmi_enter - inform RCU of entry to NMI context |
1076 | * | 975 | * |
1077 | * If the CPU was idle from RCU's viewpoint, update rdtp->dynticks and | 976 | * If the CPU was idle from RCU's viewpoint, update rdtp->dynticks and |
@@ -1086,7 +985,7 @@ void rcu_irq_enter_irqson(void) | |||
1086 | void rcu_nmi_enter(void) | 985 | void rcu_nmi_enter(void) |
1087 | { | 986 | { |
1088 | struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks); | 987 | struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks); |
1089 | int incby = 2; | 988 | long incby = 2; |
1090 | 989 | ||
1091 | /* Complain about underflow. */ | 990 | /* Complain about underflow. */ |
1092 | WARN_ON_ONCE(rdtp->dynticks_nmi_nesting < 0); | 991 | WARN_ON_ONCE(rdtp->dynticks_nmi_nesting < 0); |
@@ -1103,45 +1002,61 @@ void rcu_nmi_enter(void) | |||
1103 | rcu_dynticks_eqs_exit(); | 1002 | rcu_dynticks_eqs_exit(); |
1104 | incby = 1; | 1003 | incby = 1; |
1105 | } | 1004 | } |
1106 | rdtp->dynticks_nmi_nesting += incby; | 1005 | trace_rcu_dyntick(incby == 1 ? TPS("Endirq") : TPS("++="), |
1006 | rdtp->dynticks_nmi_nesting, | ||
1007 | rdtp->dynticks_nmi_nesting + incby, rdtp->dynticks); | ||
1008 | WRITE_ONCE(rdtp->dynticks_nmi_nesting, /* Prevent store tearing. */ | ||
1009 | rdtp->dynticks_nmi_nesting + incby); | ||
1107 | barrier(); | 1010 | barrier(); |
1108 | } | 1011 | } |
1109 | 1012 | ||
1110 | /** | 1013 | /** |
1111 | * rcu_nmi_exit - inform RCU of exit from NMI context | 1014 | * rcu_irq_enter - inform RCU that current CPU is entering irq away from idle |
1112 | * | 1015 | * |
1113 | * If we are returning from the outermost NMI handler that interrupted an | 1016 | * Enter an interrupt handler, which might possibly result in exiting |
1114 | * RCU-idle period, update rdtp->dynticks and rdtp->dynticks_nmi_nesting | 1017 | * idle mode, in other words, entering the mode in which read-side critical |
1115 | * to let the RCU grace-period handling know that the CPU is back to | 1018 | * sections can occur. The caller must have disabled interrupts. |
1116 | * being RCU-idle. | ||
1117 | * | 1019 | * |
1118 | * If you add or remove a call to rcu_nmi_exit(), be sure to test | 1020 | * Note that the Linux kernel is fully capable of entering an interrupt |
1119 | * with CONFIG_RCU_EQS_DEBUG=y. | 1021 | * handler that it never exits, for example when doing upcalls to user mode! |
1022 | * This code assumes that the idle loop never does upcalls to user mode. | ||
1023 | * If your architecture's idle loop does do upcalls to user mode (or does | ||
1024 | * anything else that results in unbalanced calls to the irq_enter() and | ||
1025 | * irq_exit() functions), RCU will give you what you deserve, good and hard. | ||
1026 | * But very infrequently and irreproducibly. | ||
1027 | * | ||
1028 | * Use things like work queues to work around this limitation. | ||
1029 | * | ||
1030 | * You have been warned. | ||
1031 | * | ||
1032 | * If you add or remove a call to rcu_irq_enter(), be sure to test with | ||
1033 | * CONFIG_RCU_EQS_DEBUG=y. | ||
1120 | */ | 1034 | */ |
1121 | void rcu_nmi_exit(void) | 1035 | void rcu_irq_enter(void) |
1122 | { | 1036 | { |
1123 | struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks); | 1037 | struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks); |
1124 | 1038 | ||
1125 | /* | 1039 | lockdep_assert_irqs_disabled(); |
1126 | * Check for ->dynticks_nmi_nesting underflow and bad ->dynticks. | 1040 | if (rdtp->dynticks_nmi_nesting == 0) |
1127 | * (We are exiting an NMI handler, so RCU better be paying attention | 1041 | rcu_dynticks_task_exit(); |
1128 | * to us!) | 1042 | rcu_nmi_enter(); |
1129 | */ | 1043 | if (rdtp->dynticks_nmi_nesting == 1) |
1130 | WARN_ON_ONCE(rdtp->dynticks_nmi_nesting <= 0); | 1044 | rcu_cleanup_after_idle(); |
1131 | WARN_ON_ONCE(rcu_dynticks_curr_cpu_in_eqs()); | 1045 | } |
1132 | 1046 | ||
1133 | /* | 1047 | /* |
1134 | * If the nesting level is not 1, the CPU wasn't RCU-idle, so | 1048 | * Wrapper for rcu_irq_enter() where interrupts are enabled. |
1135 | * leave it in non-RCU-idle state. | 1049 | * |
1136 | */ | 1050 | * If you add or remove a call to rcu_irq_enter_irqson(), be sure to test |
1137 | if (rdtp->dynticks_nmi_nesting != 1) { | 1051 | * with CONFIG_RCU_EQS_DEBUG=y. |
1138 | rdtp->dynticks_nmi_nesting -= 2; | 1052 | */ |
1139 | return; | 1053 | void rcu_irq_enter_irqson(void) |
1140 | } | 1054 | { |
1055 | unsigned long flags; | ||
1141 | 1056 | ||
1142 | /* This NMI interrupted an RCU-idle CPU, restore RCU-idleness. */ | 1057 | local_irq_save(flags); |
1143 | rdtp->dynticks_nmi_nesting = 0; | 1058 | rcu_irq_enter(); |
1144 | rcu_dynticks_eqs_enter(); | 1059 | local_irq_restore(flags); |
1145 | } | 1060 | } |
1146 | 1061 | ||
1147 | /** | 1062 | /** |
@@ -1233,7 +1148,8 @@ EXPORT_SYMBOL_GPL(rcu_lockdep_current_cpu_online); | |||
1233 | */ | 1148 | */ |
1234 | static int rcu_is_cpu_rrupt_from_idle(void) | 1149 | static int rcu_is_cpu_rrupt_from_idle(void) |
1235 | { | 1150 | { |
1236 | return __this_cpu_read(rcu_dynticks.dynticks_nesting) <= 1; | 1151 | return __this_cpu_read(rcu_dynticks.dynticks_nesting) <= 0 && |
1152 | __this_cpu_read(rcu_dynticks.dynticks_nmi_nesting) <= 1; | ||
1237 | } | 1153 | } |
1238 | 1154 | ||
1239 | /* | 1155 | /* |
@@ -2789,6 +2705,11 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp) | |||
2789 | rdp->n_force_qs_snap = rsp->n_force_qs; | 2705 | rdp->n_force_qs_snap = rsp->n_force_qs; |
2790 | } else if (count < rdp->qlen_last_fqs_check - qhimark) | 2706 | } else if (count < rdp->qlen_last_fqs_check - qhimark) |
2791 | rdp->qlen_last_fqs_check = count; | 2707 | rdp->qlen_last_fqs_check = count; |
2708 | |||
2709 | /* | ||
2710 | * The following usually indicates a double call_rcu(). To track | ||
2711 | * this down, try building with CONFIG_DEBUG_OBJECTS_RCU_HEAD=y. | ||
2712 | */ | ||
2792 | WARN_ON_ONCE(rcu_segcblist_empty(&rdp->cblist) != (count == 0)); | 2713 | WARN_ON_ONCE(rcu_segcblist_empty(&rdp->cblist) != (count == 0)); |
2793 | 2714 | ||
2794 | local_irq_restore(flags); | 2715 | local_irq_restore(flags); |
@@ -3723,7 +3644,7 @@ rcu_boot_init_percpu_data(int cpu, struct rcu_state *rsp) | |||
3723 | raw_spin_lock_irqsave_rcu_node(rnp, flags); | 3644 | raw_spin_lock_irqsave_rcu_node(rnp, flags); |
3724 | rdp->grpmask = leaf_node_cpu_bit(rdp->mynode, cpu); | 3645 | rdp->grpmask = leaf_node_cpu_bit(rdp->mynode, cpu); |
3725 | rdp->dynticks = &per_cpu(rcu_dynticks, cpu); | 3646 | rdp->dynticks = &per_cpu(rcu_dynticks, cpu); |
3726 | WARN_ON_ONCE(rdp->dynticks->dynticks_nesting != DYNTICK_TASK_EXIT_IDLE); | 3647 | WARN_ON_ONCE(rdp->dynticks->dynticks_nesting != 1); |
3727 | WARN_ON_ONCE(rcu_dynticks_in_eqs(rcu_dynticks_snap(rdp->dynticks))); | 3648 | WARN_ON_ONCE(rcu_dynticks_in_eqs(rcu_dynticks_snap(rdp->dynticks))); |
3728 | rdp->cpu = cpu; | 3649 | rdp->cpu = cpu; |
3729 | rdp->rsp = rsp; | 3650 | rdp->rsp = rsp; |
@@ -3752,7 +3673,7 @@ rcu_init_percpu_data(int cpu, struct rcu_state *rsp) | |||
3752 | if (rcu_segcblist_empty(&rdp->cblist) && /* No early-boot CBs? */ | 3673 | if (rcu_segcblist_empty(&rdp->cblist) && /* No early-boot CBs? */ |
3753 | !init_nocb_callback_list(rdp)) | 3674 | !init_nocb_callback_list(rdp)) |
3754 | rcu_segcblist_init(&rdp->cblist); /* Re-enable callbacks. */ | 3675 | rcu_segcblist_init(&rdp->cblist); /* Re-enable callbacks. */ |
3755 | rdp->dynticks->dynticks_nesting = DYNTICK_TASK_EXIT_IDLE; | 3676 | rdp->dynticks->dynticks_nesting = 1; /* CPU not up, no tearing. */ |
3756 | rcu_dynticks_eqs_online(); | 3677 | rcu_dynticks_eqs_online(); |
3757 | raw_spin_unlock_rcu_node(rnp); /* irqs remain disabled. */ | 3678 | raw_spin_unlock_rcu_node(rnp); /* irqs remain disabled. */ |
3758 | 3679 | ||
diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h index 46a5d1991450..6488a3b0e729 100644 --- a/kernel/rcu/tree.h +++ b/kernel/rcu/tree.h | |||
@@ -38,9 +38,8 @@ | |||
38 | * Dynticks per-CPU state. | 38 | * Dynticks per-CPU state. |
39 | */ | 39 | */ |
40 | struct rcu_dynticks { | 40 | struct rcu_dynticks { |
41 | long long dynticks_nesting; /* Track irq/process nesting level. */ | 41 | long dynticks_nesting; /* Track process nesting level. */ |
42 | /* Process level is worth LLONG_MAX/2. */ | 42 | long dynticks_nmi_nesting; /* Track irq/NMI nesting level. */ |
43 | int dynticks_nmi_nesting; /* Track NMI nesting level. */ | ||
44 | atomic_t dynticks; /* Even value for idle, else odd. */ | 43 | atomic_t dynticks; /* Even value for idle, else odd. */ |
45 | bool rcu_need_heavy_qs; /* GP old, need heavy quiescent state. */ | 44 | bool rcu_need_heavy_qs; /* GP old, need heavy quiescent state. */ |
46 | unsigned long rcu_qs_ctr; /* Light universal quiescent state ctr. */ | 45 | unsigned long rcu_qs_ctr; /* Light universal quiescent state ctr. */ |
diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h index db85ca3975f1..fb88a028deec 100644 --- a/kernel/rcu/tree_plugin.h +++ b/kernel/rcu/tree_plugin.h | |||
@@ -61,7 +61,6 @@ DEFINE_PER_CPU(char, rcu_cpu_has_work); | |||
61 | 61 | ||
62 | #ifdef CONFIG_RCU_NOCB_CPU | 62 | #ifdef CONFIG_RCU_NOCB_CPU |
63 | static cpumask_var_t rcu_nocb_mask; /* CPUs to have callbacks offloaded. */ | 63 | static cpumask_var_t rcu_nocb_mask; /* CPUs to have callbacks offloaded. */ |
64 | static bool have_rcu_nocb_mask; /* Was rcu_nocb_mask allocated? */ | ||
65 | static bool __read_mostly rcu_nocb_poll; /* Offload kthread are to poll. */ | 64 | static bool __read_mostly rcu_nocb_poll; /* Offload kthread are to poll. */ |
66 | #endif /* #ifdef CONFIG_RCU_NOCB_CPU */ | 65 | #endif /* #ifdef CONFIG_RCU_NOCB_CPU */ |
67 | 66 | ||
@@ -1687,7 +1686,7 @@ static void print_cpu_stall_info(struct rcu_state *rsp, int cpu) | |||
1687 | } | 1686 | } |
1688 | print_cpu_stall_fast_no_hz(fast_no_hz, cpu); | 1687 | print_cpu_stall_fast_no_hz(fast_no_hz, cpu); |
1689 | delta = rdp->mynode->gpnum - rdp->rcu_iw_gpnum; | 1688 | delta = rdp->mynode->gpnum - rdp->rcu_iw_gpnum; |
1690 | pr_err("\t%d-%c%c%c%c: (%lu %s) idle=%03x/%llx/%d softirq=%u/%u fqs=%ld %s\n", | 1689 | pr_err("\t%d-%c%c%c%c: (%lu %s) idle=%03x/%ld/%ld softirq=%u/%u fqs=%ld %s\n", |
1691 | cpu, | 1690 | cpu, |
1692 | "O."[!!cpu_online(cpu)], | 1691 | "O."[!!cpu_online(cpu)], |
1693 | "o."[!!(rdp->grpmask & rdp->mynode->qsmaskinit)], | 1692 | "o."[!!(rdp->grpmask & rdp->mynode->qsmaskinit)], |
@@ -1752,7 +1751,6 @@ static void increment_cpu_stall_ticks(void) | |||
1752 | static int __init rcu_nocb_setup(char *str) | 1751 | static int __init rcu_nocb_setup(char *str) |
1753 | { | 1752 | { |
1754 | alloc_bootmem_cpumask_var(&rcu_nocb_mask); | 1753 | alloc_bootmem_cpumask_var(&rcu_nocb_mask); |
1755 | have_rcu_nocb_mask = true; | ||
1756 | cpulist_parse(str, rcu_nocb_mask); | 1754 | cpulist_parse(str, rcu_nocb_mask); |
1757 | return 1; | 1755 | return 1; |
1758 | } | 1756 | } |
@@ -1801,7 +1799,7 @@ static void rcu_init_one_nocb(struct rcu_node *rnp) | |||
1801 | /* Is the specified CPU a no-CBs CPU? */ | 1799 | /* Is the specified CPU a no-CBs CPU? */ |
1802 | bool rcu_is_nocb_cpu(int cpu) | 1800 | bool rcu_is_nocb_cpu(int cpu) |
1803 | { | 1801 | { |
1804 | if (have_rcu_nocb_mask) | 1802 | if (cpumask_available(rcu_nocb_mask)) |
1805 | return cpumask_test_cpu(cpu, rcu_nocb_mask); | 1803 | return cpumask_test_cpu(cpu, rcu_nocb_mask); |
1806 | return false; | 1804 | return false; |
1807 | } | 1805 | } |
@@ -2295,14 +2293,13 @@ void __init rcu_init_nohz(void) | |||
2295 | need_rcu_nocb_mask = true; | 2293 | need_rcu_nocb_mask = true; |
2296 | #endif /* #if defined(CONFIG_NO_HZ_FULL) */ | 2294 | #endif /* #if defined(CONFIG_NO_HZ_FULL) */ |
2297 | 2295 | ||
2298 | if (!have_rcu_nocb_mask && need_rcu_nocb_mask) { | 2296 | if (!cpumask_available(rcu_nocb_mask) && need_rcu_nocb_mask) { |
2299 | if (!zalloc_cpumask_var(&rcu_nocb_mask, GFP_KERNEL)) { | 2297 | if (!zalloc_cpumask_var(&rcu_nocb_mask, GFP_KERNEL)) { |
2300 | pr_info("rcu_nocb_mask allocation failed, callback offloading disabled.\n"); | 2298 | pr_info("rcu_nocb_mask allocation failed, callback offloading disabled.\n"); |
2301 | return; | 2299 | return; |
2302 | } | 2300 | } |
2303 | have_rcu_nocb_mask = true; | ||
2304 | } | 2301 | } |
2305 | if (!have_rcu_nocb_mask) | 2302 | if (!cpumask_available(rcu_nocb_mask)) |
2306 | return; | 2303 | return; |
2307 | 2304 | ||
2308 | #if defined(CONFIG_NO_HZ_FULL) | 2305 | #if defined(CONFIG_NO_HZ_FULL) |
@@ -2428,7 +2425,7 @@ static void __init rcu_organize_nocb_kthreads(struct rcu_state *rsp) | |||
2428 | struct rcu_data *rdp_leader = NULL; /* Suppress misguided gcc warn. */ | 2425 | struct rcu_data *rdp_leader = NULL; /* Suppress misguided gcc warn. */ |
2429 | struct rcu_data *rdp_prev = NULL; | 2426 | struct rcu_data *rdp_prev = NULL; |
2430 | 2427 | ||
2431 | if (!have_rcu_nocb_mask) | 2428 | if (!cpumask_available(rcu_nocb_mask)) |
2432 | return; | 2429 | return; |
2433 | if (ls == -1) { | 2430 | if (ls == -1) { |
2434 | ls = int_sqrt(nr_cpu_ids); | 2431 | ls = int_sqrt(nr_cpu_ids); |
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 644fa2e3d993..729b4fff93b8 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
@@ -508,7 +508,8 @@ void resched_cpu(int cpu) | |||
508 | unsigned long flags; | 508 | unsigned long flags; |
509 | 509 | ||
510 | raw_spin_lock_irqsave(&rq->lock, flags); | 510 | raw_spin_lock_irqsave(&rq->lock, flags); |
511 | resched_curr(rq); | 511 | if (cpu_online(cpu) || cpu == smp_processor_id()) |
512 | resched_curr(rq); | ||
512 | raw_spin_unlock_irqrestore(&rq->lock, flags); | 513 | raw_spin_unlock_irqrestore(&rq->lock, flags); |
513 | } | 514 | } |
514 | 515 | ||
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index 665ace2fc558..862a513adca3 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c | |||
@@ -2212,7 +2212,7 @@ static void switched_to_rt(struct rq *rq, struct task_struct *p) | |||
2212 | if (p->nr_cpus_allowed > 1 && rq->rt.overloaded) | 2212 | if (p->nr_cpus_allowed > 1 && rq->rt.overloaded) |
2213 | queue_push_tasks(rq); | 2213 | queue_push_tasks(rq); |
2214 | #endif /* CONFIG_SMP */ | 2214 | #endif /* CONFIG_SMP */ |
2215 | if (p->prio < rq->curr->prio) | 2215 | if (p->prio < rq->curr->prio && cpu_online(cpu_of(rq))) |
2216 | resched_curr(rq); | 2216 | resched_curr(rq); |
2217 | } | 2217 | } |
2218 | } | 2218 | } |
diff --git a/kernel/softirq.c b/kernel/softirq.c index 2f5e87f1bae2..24d243ef8e71 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c | |||
@@ -665,7 +665,7 @@ static void run_ksoftirqd(unsigned int cpu) | |||
665 | */ | 665 | */ |
666 | __do_softirq(); | 666 | __do_softirq(); |
667 | local_irq_enable(); | 667 | local_irq_enable(); |
668 | cond_resched_rcu_qs(); | 668 | cond_resched(); |
669 | return; | 669 | return; |
670 | } | 670 | } |
671 | local_irq_enable(); | 671 | local_irq_enable(); |
diff --git a/kernel/torture.c b/kernel/torture.c index 637e172835d8..37b94012a3f8 100644 --- a/kernel/torture.c +++ b/kernel/torture.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include <linux/ktime.h> | 47 | #include <linux/ktime.h> |
48 | #include <asm/byteorder.h> | 48 | #include <asm/byteorder.h> |
49 | #include <linux/torture.h> | 49 | #include <linux/torture.h> |
50 | #include "rcu/rcu.h" | ||
50 | 51 | ||
51 | MODULE_LICENSE("GPL"); | 52 | MODULE_LICENSE("GPL"); |
52 | MODULE_AUTHOR("Paul E. McKenney <paulmck@us.ibm.com>"); | 53 | MODULE_AUTHOR("Paul E. McKenney <paulmck@us.ibm.com>"); |
@@ -60,7 +61,6 @@ static bool verbose; | |||
60 | #define FULLSTOP_RMMOD 2 /* Normal rmmod of torture. */ | 61 | #define FULLSTOP_RMMOD 2 /* Normal rmmod of torture. */ |
61 | static int fullstop = FULLSTOP_RMMOD; | 62 | static int fullstop = FULLSTOP_RMMOD; |
62 | static DEFINE_MUTEX(fullstop_mutex); | 63 | static DEFINE_MUTEX(fullstop_mutex); |
63 | static int *torture_runnable; | ||
64 | 64 | ||
65 | #ifdef CONFIG_HOTPLUG_CPU | 65 | #ifdef CONFIG_HOTPLUG_CPU |
66 | 66 | ||
@@ -500,7 +500,7 @@ static int torture_shutdown(void *arg) | |||
500 | torture_shutdown_hook(); | 500 | torture_shutdown_hook(); |
501 | else | 501 | else |
502 | VERBOSE_TOROUT_STRING("No torture_shutdown_hook(), skipping."); | 502 | VERBOSE_TOROUT_STRING("No torture_shutdown_hook(), skipping."); |
503 | ftrace_dump(DUMP_ALL); | 503 | rcu_ftrace_dump(DUMP_ALL); |
504 | kernel_power_off(); /* Shut down the system. */ | 504 | kernel_power_off(); /* Shut down the system. */ |
505 | return 0; | 505 | return 0; |
506 | } | 506 | } |
@@ -572,17 +572,19 @@ static int stutter; | |||
572 | */ | 572 | */ |
573 | void stutter_wait(const char *title) | 573 | void stutter_wait(const char *title) |
574 | { | 574 | { |
575 | int spt; | ||
576 | |||
575 | cond_resched_rcu_qs(); | 577 | cond_resched_rcu_qs(); |
576 | while (READ_ONCE(stutter_pause_test) || | 578 | spt = READ_ONCE(stutter_pause_test); |
577 | (torture_runnable && !READ_ONCE(*torture_runnable))) { | 579 | for (; spt; spt = READ_ONCE(stutter_pause_test)) { |
578 | if (stutter_pause_test) | 580 | if (spt == 1) { |
579 | if (READ_ONCE(stutter_pause_test) == 1) | 581 | schedule_timeout_interruptible(1); |
580 | schedule_timeout_interruptible(1); | 582 | } else if (spt == 2) { |
581 | else | 583 | while (READ_ONCE(stutter_pause_test)) |
582 | while (READ_ONCE(stutter_pause_test)) | 584 | cond_resched(); |
583 | cond_resched(); | 585 | } else { |
584 | else | ||
585 | schedule_timeout_interruptible(round_jiffies_relative(HZ)); | 586 | schedule_timeout_interruptible(round_jiffies_relative(HZ)); |
587 | } | ||
586 | torture_shutdown_absorb(title); | 588 | torture_shutdown_absorb(title); |
587 | } | 589 | } |
588 | } | 590 | } |
@@ -596,17 +598,15 @@ static int torture_stutter(void *arg) | |||
596 | { | 598 | { |
597 | VERBOSE_TOROUT_STRING("torture_stutter task started"); | 599 | VERBOSE_TOROUT_STRING("torture_stutter task started"); |
598 | do { | 600 | do { |
599 | if (!torture_must_stop()) { | 601 | if (!torture_must_stop() && stutter > 1) { |
600 | if (stutter > 1) { | ||
601 | schedule_timeout_interruptible(stutter - 1); | ||
602 | WRITE_ONCE(stutter_pause_test, 2); | ||
603 | } | ||
604 | schedule_timeout_interruptible(1); | ||
605 | WRITE_ONCE(stutter_pause_test, 1); | 602 | WRITE_ONCE(stutter_pause_test, 1); |
603 | schedule_timeout_interruptible(stutter - 1); | ||
604 | WRITE_ONCE(stutter_pause_test, 2); | ||
605 | schedule_timeout_interruptible(1); | ||
606 | } | 606 | } |
607 | WRITE_ONCE(stutter_pause_test, 0); | ||
607 | if (!torture_must_stop()) | 608 | if (!torture_must_stop()) |
608 | schedule_timeout_interruptible(stutter); | 609 | schedule_timeout_interruptible(stutter); |
609 | WRITE_ONCE(stutter_pause_test, 0); | ||
610 | torture_shutdown_absorb("torture_stutter"); | 610 | torture_shutdown_absorb("torture_stutter"); |
611 | } while (!torture_must_stop()); | 611 | } while (!torture_must_stop()); |
612 | torture_kthread_stopping("torture_stutter"); | 612 | torture_kthread_stopping("torture_stutter"); |
@@ -647,7 +647,7 @@ static void torture_stutter_cleanup(void) | |||
647 | * The runnable parameter points to a flag that controls whether or not | 647 | * The runnable parameter points to a flag that controls whether or not |
648 | * the test is currently runnable. If there is no such flag, pass in NULL. | 648 | * the test is currently runnable. If there is no such flag, pass in NULL. |
649 | */ | 649 | */ |
650 | bool torture_init_begin(char *ttype, bool v, int *runnable) | 650 | bool torture_init_begin(char *ttype, bool v) |
651 | { | 651 | { |
652 | mutex_lock(&fullstop_mutex); | 652 | mutex_lock(&fullstop_mutex); |
653 | if (torture_type != NULL) { | 653 | if (torture_type != NULL) { |
@@ -659,7 +659,6 @@ bool torture_init_begin(char *ttype, bool v, int *runnable) | |||
659 | } | 659 | } |
660 | torture_type = ttype; | 660 | torture_type = ttype; |
661 | verbose = v; | 661 | verbose = v; |
662 | torture_runnable = runnable; | ||
663 | fullstop = FULLSTOP_DONTSTOP; | 662 | fullstop = FULLSTOP_DONTSTOP; |
664 | return true; | 663 | return true; |
665 | } | 664 | } |
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 2a8d8a294345..aaf882a8bf1f 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -2682,17 +2682,6 @@ void __trace_stack(struct trace_array *tr, unsigned long flags, int skip, | |||
2682 | if (unlikely(in_nmi())) | 2682 | if (unlikely(in_nmi())) |
2683 | return; | 2683 | return; |
2684 | 2684 | ||
2685 | /* | ||
2686 | * It is possible that a function is being traced in a | ||
2687 | * location that RCU is not watching. A call to | ||
2688 | * rcu_irq_enter() will make sure that it is, but there's | ||
2689 | * a few internal rcu functions that could be traced | ||
2690 | * where that wont work either. In those cases, we just | ||
2691 | * do nothing. | ||
2692 | */ | ||
2693 | if (unlikely(rcu_irq_enter_disabled())) | ||
2694 | return; | ||
2695 | |||
2696 | rcu_irq_enter_irqson(); | 2685 | rcu_irq_enter_irqson(); |
2697 | __ftrace_trace_stack(buffer, flags, skip, pc, NULL); | 2686 | __ftrace_trace_stack(buffer, flags, skip, pc, NULL); |
2698 | rcu_irq_exit_irqson(); | 2687 | rcu_irq_exit_irqson(); |
diff --git a/kernel/trace/trace_benchmark.c b/kernel/trace/trace_benchmark.c index 79f838a75077..22fee766081b 100644 --- a/kernel/trace/trace_benchmark.c +++ b/kernel/trace/trace_benchmark.c | |||
@@ -165,7 +165,7 @@ static int benchmark_event_kthread(void *arg) | |||
165 | * this thread will never voluntarily schedule which would | 165 | * this thread will never voluntarily schedule which would |
166 | * block synchronize_rcu_tasks() indefinitely. | 166 | * block synchronize_rcu_tasks() indefinitely. |
167 | */ | 167 | */ |
168 | cond_resched_rcu_qs(); | 168 | cond_resched(); |
169 | } | 169 | } |
170 | 170 | ||
171 | return 0; | 171 | return 0; |
diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c index 685c50ae6300..671b13457387 100644 --- a/kernel/tracepoint.c +++ b/kernel/tracepoint.c | |||
@@ -212,11 +212,10 @@ static int tracepoint_add_func(struct tracepoint *tp, | |||
212 | } | 212 | } |
213 | 213 | ||
214 | /* | 214 | /* |
215 | * rcu_assign_pointer has a smp_wmb() which makes sure that the new | 215 | * rcu_assign_pointer has as smp_store_release() which makes sure |
216 | * probe callbacks array is consistent before setting a pointer to it. | 216 | * that the new probe callbacks array is consistent before setting |
217 | * This array is referenced by __DO_TRACE from | 217 | * a pointer to it. This array is referenced by __DO_TRACE from |
218 | * include/linux/tracepoints.h. A matching smp_read_barrier_depends() | 218 | * include/linux/tracepoint.h using rcu_dereference_sched(). |
219 | * is used. | ||
220 | */ | 219 | */ |
221 | rcu_assign_pointer(tp->funcs, tp_funcs); | 220 | rcu_assign_pointer(tp->funcs, tp_funcs); |
222 | if (!static_key_enabled(&tp->key)) | 221 | if (!static_key_enabled(&tp->key)) |
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 43d18cb46308..acf485eada1b 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -2135,7 +2135,7 @@ __acquires(&pool->lock) | |||
2135 | * stop_machine. At the same time, report a quiescent RCU state so | 2135 | * stop_machine. At the same time, report a quiescent RCU state so |
2136 | * the same condition doesn't freeze RCU. | 2136 | * the same condition doesn't freeze RCU. |
2137 | */ | 2137 | */ |
2138 | cond_resched_rcu_qs(); | 2138 | cond_resched(); |
2139 | 2139 | ||
2140 | spin_lock_irq(&pool->lock); | 2140 | spin_lock_irq(&pool->lock); |
2141 | 2141 | ||
diff --git a/lib/assoc_array.c b/lib/assoc_array.c index b77d51da8c73..c6659cb37033 100644 --- a/lib/assoc_array.c +++ b/lib/assoc_array.c | |||
@@ -38,12 +38,10 @@ begin_node: | |||
38 | if (assoc_array_ptr_is_shortcut(cursor)) { | 38 | if (assoc_array_ptr_is_shortcut(cursor)) { |
39 | /* Descend through a shortcut */ | 39 | /* Descend through a shortcut */ |
40 | shortcut = assoc_array_ptr_to_shortcut(cursor); | 40 | shortcut = assoc_array_ptr_to_shortcut(cursor); |
41 | smp_read_barrier_depends(); | 41 | cursor = READ_ONCE(shortcut->next_node); /* Address dependency. */ |
42 | cursor = READ_ONCE(shortcut->next_node); | ||
43 | } | 42 | } |
44 | 43 | ||
45 | node = assoc_array_ptr_to_node(cursor); | 44 | node = assoc_array_ptr_to_node(cursor); |
46 | smp_read_barrier_depends(); | ||
47 | slot = 0; | 45 | slot = 0; |
48 | 46 | ||
49 | /* We perform two passes of each node. | 47 | /* We perform two passes of each node. |
@@ -55,15 +53,12 @@ begin_node: | |||
55 | */ | 53 | */ |
56 | has_meta = 0; | 54 | has_meta = 0; |
57 | for (; slot < ASSOC_ARRAY_FAN_OUT; slot++) { | 55 | for (; slot < ASSOC_ARRAY_FAN_OUT; slot++) { |
58 | ptr = READ_ONCE(node->slots[slot]); | 56 | ptr = READ_ONCE(node->slots[slot]); /* Address dependency. */ |
59 | has_meta |= (unsigned long)ptr; | 57 | has_meta |= (unsigned long)ptr; |
60 | if (ptr && assoc_array_ptr_is_leaf(ptr)) { | 58 | if (ptr && assoc_array_ptr_is_leaf(ptr)) { |
61 | /* We need a barrier between the read of the pointer | 59 | /* We need a barrier between the read of the pointer, |
62 | * and dereferencing the pointer - but only if we are | 60 | * which is supplied by the above READ_ONCE(). |
63 | * actually going to dereference it. | ||
64 | */ | 61 | */ |
65 | smp_read_barrier_depends(); | ||
66 | |||
67 | /* Invoke the callback */ | 62 | /* Invoke the callback */ |
68 | ret = iterator(assoc_array_ptr_to_leaf(ptr), | 63 | ret = iterator(assoc_array_ptr_to_leaf(ptr), |
69 | iterator_data); | 64 | iterator_data); |
@@ -86,10 +81,8 @@ begin_node: | |||
86 | 81 | ||
87 | continue_node: | 82 | continue_node: |
88 | node = assoc_array_ptr_to_node(cursor); | 83 | node = assoc_array_ptr_to_node(cursor); |
89 | smp_read_barrier_depends(); | ||
90 | |||
91 | for (; slot < ASSOC_ARRAY_FAN_OUT; slot++) { | 84 | for (; slot < ASSOC_ARRAY_FAN_OUT; slot++) { |
92 | ptr = READ_ONCE(node->slots[slot]); | 85 | ptr = READ_ONCE(node->slots[slot]); /* Address dependency. */ |
93 | if (assoc_array_ptr_is_meta(ptr)) { | 86 | if (assoc_array_ptr_is_meta(ptr)) { |
94 | cursor = ptr; | 87 | cursor = ptr; |
95 | goto begin_node; | 88 | goto begin_node; |
@@ -98,16 +91,15 @@ continue_node: | |||
98 | 91 | ||
99 | finished_node: | 92 | finished_node: |
100 | /* Move up to the parent (may need to skip back over a shortcut) */ | 93 | /* Move up to the parent (may need to skip back over a shortcut) */ |
101 | parent = READ_ONCE(node->back_pointer); | 94 | parent = READ_ONCE(node->back_pointer); /* Address dependency. */ |
102 | slot = node->parent_slot; | 95 | slot = node->parent_slot; |
103 | if (parent == stop) | 96 | if (parent == stop) |
104 | return 0; | 97 | return 0; |
105 | 98 | ||
106 | if (assoc_array_ptr_is_shortcut(parent)) { | 99 | if (assoc_array_ptr_is_shortcut(parent)) { |
107 | shortcut = assoc_array_ptr_to_shortcut(parent); | 100 | shortcut = assoc_array_ptr_to_shortcut(parent); |
108 | smp_read_barrier_depends(); | ||
109 | cursor = parent; | 101 | cursor = parent; |
110 | parent = READ_ONCE(shortcut->back_pointer); | 102 | parent = READ_ONCE(shortcut->back_pointer); /* Address dependency. */ |
111 | slot = shortcut->parent_slot; | 103 | slot = shortcut->parent_slot; |
112 | if (parent == stop) | 104 | if (parent == stop) |
113 | return 0; | 105 | return 0; |
@@ -147,7 +139,7 @@ int assoc_array_iterate(const struct assoc_array *array, | |||
147 | void *iterator_data), | 139 | void *iterator_data), |
148 | void *iterator_data) | 140 | void *iterator_data) |
149 | { | 141 | { |
150 | struct assoc_array_ptr *root = READ_ONCE(array->root); | 142 | struct assoc_array_ptr *root = READ_ONCE(array->root); /* Address dependency. */ |
151 | 143 | ||
152 | if (!root) | 144 | if (!root) |
153 | return 0; | 145 | return 0; |
@@ -194,7 +186,7 @@ assoc_array_walk(const struct assoc_array *array, | |||
194 | 186 | ||
195 | pr_devel("-->%s()\n", __func__); | 187 | pr_devel("-->%s()\n", __func__); |
196 | 188 | ||
197 | cursor = READ_ONCE(array->root); | 189 | cursor = READ_ONCE(array->root); /* Address dependency. */ |
198 | if (!cursor) | 190 | if (!cursor) |
199 | return assoc_array_walk_tree_empty; | 191 | return assoc_array_walk_tree_empty; |
200 | 192 | ||
@@ -216,11 +208,9 @@ jumped: | |||
216 | 208 | ||
217 | consider_node: | 209 | consider_node: |
218 | node = assoc_array_ptr_to_node(cursor); | 210 | node = assoc_array_ptr_to_node(cursor); |
219 | smp_read_barrier_depends(); | ||
220 | |||
221 | slot = segments >> (level & ASSOC_ARRAY_KEY_CHUNK_MASK); | 211 | slot = segments >> (level & ASSOC_ARRAY_KEY_CHUNK_MASK); |
222 | slot &= ASSOC_ARRAY_FAN_MASK; | 212 | slot &= ASSOC_ARRAY_FAN_MASK; |
223 | ptr = READ_ONCE(node->slots[slot]); | 213 | ptr = READ_ONCE(node->slots[slot]); /* Address dependency. */ |
224 | 214 | ||
225 | pr_devel("consider slot %x [ix=%d type=%lu]\n", | 215 | pr_devel("consider slot %x [ix=%d type=%lu]\n", |
226 | slot, level, (unsigned long)ptr & 3); | 216 | slot, level, (unsigned long)ptr & 3); |
@@ -254,7 +244,6 @@ consider_node: | |||
254 | cursor = ptr; | 244 | cursor = ptr; |
255 | follow_shortcut: | 245 | follow_shortcut: |
256 | shortcut = assoc_array_ptr_to_shortcut(cursor); | 246 | shortcut = assoc_array_ptr_to_shortcut(cursor); |
257 | smp_read_barrier_depends(); | ||
258 | pr_devel("shortcut to %d\n", shortcut->skip_to_level); | 247 | pr_devel("shortcut to %d\n", shortcut->skip_to_level); |
259 | sc_level = level + ASSOC_ARRAY_LEVEL_STEP; | 248 | sc_level = level + ASSOC_ARRAY_LEVEL_STEP; |
260 | BUG_ON(sc_level > shortcut->skip_to_level); | 249 | BUG_ON(sc_level > shortcut->skip_to_level); |
@@ -294,7 +283,7 @@ follow_shortcut: | |||
294 | } while (sc_level < shortcut->skip_to_level); | 283 | } while (sc_level < shortcut->skip_to_level); |
295 | 284 | ||
296 | /* The shortcut matches the leaf's index to this point. */ | 285 | /* The shortcut matches the leaf's index to this point. */ |
297 | cursor = READ_ONCE(shortcut->next_node); | 286 | cursor = READ_ONCE(shortcut->next_node); /* Address dependency. */ |
298 | if (((level ^ sc_level) & ~ASSOC_ARRAY_KEY_CHUNK_MASK) != 0) { | 287 | if (((level ^ sc_level) & ~ASSOC_ARRAY_KEY_CHUNK_MASK) != 0) { |
299 | level = sc_level; | 288 | level = sc_level; |
300 | goto jumped; | 289 | goto jumped; |
@@ -331,20 +320,18 @@ void *assoc_array_find(const struct assoc_array *array, | |||
331 | return NULL; | 320 | return NULL; |
332 | 321 | ||
333 | node = result.terminal_node.node; | 322 | node = result.terminal_node.node; |
334 | smp_read_barrier_depends(); | ||
335 | 323 | ||
336 | /* If the target key is available to us, it's has to be pointed to by | 324 | /* If the target key is available to us, it's has to be pointed to by |
337 | * the terminal node. | 325 | * the terminal node. |
338 | */ | 326 | */ |
339 | for (slot = 0; slot < ASSOC_ARRAY_FAN_OUT; slot++) { | 327 | for (slot = 0; slot < ASSOC_ARRAY_FAN_OUT; slot++) { |
340 | ptr = READ_ONCE(node->slots[slot]); | 328 | ptr = READ_ONCE(node->slots[slot]); /* Address dependency. */ |
341 | if (ptr && assoc_array_ptr_is_leaf(ptr)) { | 329 | if (ptr && assoc_array_ptr_is_leaf(ptr)) { |
342 | /* We need a barrier between the read of the pointer | 330 | /* We need a barrier between the read of the pointer |
343 | * and dereferencing the pointer - but only if we are | 331 | * and dereferencing the pointer - but only if we are |
344 | * actually going to dereference it. | 332 | * actually going to dereference it. |
345 | */ | 333 | */ |
346 | leaf = assoc_array_ptr_to_leaf(ptr); | 334 | leaf = assoc_array_ptr_to_leaf(ptr); |
347 | smp_read_barrier_depends(); | ||
348 | if (ops->compare_object(leaf, index_key)) | 335 | if (ops->compare_object(leaf, index_key)) |
349 | return (void *)leaf; | 336 | return (void *)leaf; |
350 | } | 337 | } |
diff --git a/lib/percpu-refcount.c b/lib/percpu-refcount.c index fe03c6d52761..30e7dd88148b 100644 --- a/lib/percpu-refcount.c +++ b/lib/percpu-refcount.c | |||
@@ -197,10 +197,10 @@ static void __percpu_ref_switch_to_percpu(struct percpu_ref *ref) | |||
197 | atomic_long_add(PERCPU_COUNT_BIAS, &ref->count); | 197 | atomic_long_add(PERCPU_COUNT_BIAS, &ref->count); |
198 | 198 | ||
199 | /* | 199 | /* |
200 | * Restore per-cpu operation. smp_store_release() is paired with | 200 | * Restore per-cpu operation. smp_store_release() is paired |
201 | * smp_read_barrier_depends() in __ref_is_percpu() and guarantees | 201 | * with READ_ONCE() in __ref_is_percpu() and guarantees that the |
202 | * that the zeroing is visible to all percpu accesses which can see | 202 | * zeroing is visible to all percpu accesses which can see the |
203 | * the following __PERCPU_REF_ATOMIC clearing. | 203 | * following __PERCPU_REF_ATOMIC clearing. |
204 | */ | 204 | */ |
205 | for_each_possible_cpu(cpu) | 205 | for_each_possible_cpu(cpu) |
206 | *per_cpu_ptr(percpu_count, cpu) = 0; | 206 | *per_cpu_ptr(percpu_count, cpu) = 0; |
@@ -675,15 +675,8 @@ static struct page *get_ksm_page(struct stable_node *stable_node, bool lock_it) | |||
675 | expected_mapping = (void *)((unsigned long)stable_node | | 675 | expected_mapping = (void *)((unsigned long)stable_node | |
676 | PAGE_MAPPING_KSM); | 676 | PAGE_MAPPING_KSM); |
677 | again: | 677 | again: |
678 | kpfn = READ_ONCE(stable_node->kpfn); | 678 | kpfn = READ_ONCE(stable_node->kpfn); /* Address dependency. */ |
679 | page = pfn_to_page(kpfn); | 679 | page = pfn_to_page(kpfn); |
680 | |||
681 | /* | ||
682 | * page is computed from kpfn, so on most architectures reading | ||
683 | * page->mapping is naturally ordered after reading node->kpfn, | ||
684 | * but on Alpha we need to be more careful. | ||
685 | */ | ||
686 | smp_read_barrier_depends(); | ||
687 | if (READ_ONCE(page->mapping) != expected_mapping) | 680 | if (READ_ONCE(page->mapping) != expected_mapping) |
688 | goto stale; | 681 | goto stale; |
689 | 682 | ||
diff --git a/mm/mlock.c b/mm/mlock.c index 30472d438794..f7f54fd2e13f 100644 --- a/mm/mlock.c +++ b/mm/mlock.c | |||
@@ -779,7 +779,7 @@ static int apply_mlockall_flags(int flags) | |||
779 | 779 | ||
780 | /* Ignore errors */ | 780 | /* Ignore errors */ |
781 | mlock_fixup(vma, &prev, vma->vm_start, vma->vm_end, newflags); | 781 | mlock_fixup(vma, &prev, vma->vm_start, vma->vm_end, newflags); |
782 | cond_resched_rcu_qs(); | 782 | cond_resched(); |
783 | } | 783 | } |
784 | out: | 784 | out: |
785 | return 0; | 785 | return 0; |
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 0c3c944a7b72..eb8246c39de0 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -202,13 +202,8 @@ unsigned int arpt_do_table(struct sk_buff *skb, | |||
202 | 202 | ||
203 | local_bh_disable(); | 203 | local_bh_disable(); |
204 | addend = xt_write_recseq_begin(); | 204 | addend = xt_write_recseq_begin(); |
205 | private = table->private; | 205 | private = READ_ONCE(table->private); /* Address dependency. */ |
206 | cpu = smp_processor_id(); | 206 | cpu = smp_processor_id(); |
207 | /* | ||
208 | * Ensure we load private-> members after we've fetched the base | ||
209 | * pointer. | ||
210 | */ | ||
211 | smp_read_barrier_depends(); | ||
212 | table_base = private->entries; | 207 | table_base = private->entries; |
213 | jumpstack = (struct arpt_entry **)private->jumpstack[cpu]; | 208 | jumpstack = (struct arpt_entry **)private->jumpstack[cpu]; |
214 | 209 | ||
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 2e0d339028bb..cc984d0e0c69 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -260,13 +260,8 @@ ipt_do_table(struct sk_buff *skb, | |||
260 | WARN_ON(!(table->valid_hooks & (1 << hook))); | 260 | WARN_ON(!(table->valid_hooks & (1 << hook))); |
261 | local_bh_disable(); | 261 | local_bh_disable(); |
262 | addend = xt_write_recseq_begin(); | 262 | addend = xt_write_recseq_begin(); |
263 | private = table->private; | 263 | private = READ_ONCE(table->private); /* Address dependency. */ |
264 | cpu = smp_processor_id(); | 264 | cpu = smp_processor_id(); |
265 | /* | ||
266 | * Ensure we load private-> members after we've fetched the base | ||
267 | * pointer. | ||
268 | */ | ||
269 | smp_read_barrier_depends(); | ||
270 | table_base = private->entries; | 265 | table_base = private->entries; |
271 | jumpstack = (struct ipt_entry **)private->jumpstack[cpu]; | 266 | jumpstack = (struct ipt_entry **)private->jumpstack[cpu]; |
272 | 267 | ||
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 1d7ae9366335..66a8c69a3db4 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -282,12 +282,7 @@ ip6t_do_table(struct sk_buff *skb, | |||
282 | 282 | ||
283 | local_bh_disable(); | 283 | local_bh_disable(); |
284 | addend = xt_write_recseq_begin(); | 284 | addend = xt_write_recseq_begin(); |
285 | private = table->private; | 285 | private = READ_ONCE(table->private); /* Address dependency. */ |
286 | /* | ||
287 | * Ensure we load private-> members after we've fetched the base | ||
288 | * pointer. | ||
289 | */ | ||
290 | smp_read_barrier_depends(); | ||
291 | cpu = smp_processor_id(); | 286 | cpu = smp_processor_id(); |
292 | table_base = private->entries; | 287 | table_base = private->entries; |
293 | jumpstack = (struct ip6t_entry **)private->jumpstack[cpu]; | 288 | jumpstack = (struct ip6t_entry **)private->jumpstack[cpu]; |
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 85f643c1e227..4efaa3066c78 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
@@ -1044,7 +1044,7 @@ static void gc_worker(struct work_struct *work) | |||
1044 | * we will just continue with next hash slot. | 1044 | * we will just continue with next hash slot. |
1045 | */ | 1045 | */ |
1046 | rcu_read_unlock(); | 1046 | rcu_read_unlock(); |
1047 | cond_resched_rcu_qs(); | 1047 | cond_resched(); |
1048 | } while (++buckets < goal); | 1048 | } while (++buckets < goal); |
1049 | 1049 | ||
1050 | if (gc_work->exiting) | 1050 | if (gc_work->exiting) |
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 31031f10fe56..ba03f17ff662 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl | |||
@@ -5586,6 +5586,12 @@ sub process { | |||
5586 | } | 5586 | } |
5587 | } | 5587 | } |
5588 | 5588 | ||
5589 | # check for smp_read_barrier_depends and read_barrier_depends | ||
5590 | if (!$file && $line =~ /\b(smp_|)read_barrier_depends\s*\(/) { | ||
5591 | WARN("READ_BARRIER_DEPENDS", | ||
5592 | "$1read_barrier_depends should only be used in READ_ONCE or DEC Alpha code\n" . $herecurr); | ||
5593 | } | ||
5594 | |||
5589 | # check of hardware specific defines | 5595 | # check of hardware specific defines |
5590 | if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { | 5596 | if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { |
5591 | CHK("ARCH_DEFINES", | 5597 | CHK("ARCH_DEFINES", |
diff --git a/security/keys/keyring.c b/security/keys/keyring.c index d0bccebbd3b5..41bcf57e96f2 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c | |||
@@ -713,7 +713,6 @@ descend_to_keyring: | |||
713 | * doesn't contain any keyring pointers. | 713 | * doesn't contain any keyring pointers. |
714 | */ | 714 | */ |
715 | shortcut = assoc_array_ptr_to_shortcut(ptr); | 715 | shortcut = assoc_array_ptr_to_shortcut(ptr); |
716 | smp_read_barrier_depends(); | ||
717 | if ((shortcut->index_key[0] & ASSOC_ARRAY_FAN_MASK) != 0) | 716 | if ((shortcut->index_key[0] & ASSOC_ARRAY_FAN_MASK) != 0) |
718 | goto not_this_keyring; | 717 | goto not_this_keyring; |
719 | 718 | ||
@@ -723,8 +722,6 @@ descend_to_keyring: | |||
723 | } | 722 | } |
724 | 723 | ||
725 | node = assoc_array_ptr_to_node(ptr); | 724 | node = assoc_array_ptr_to_node(ptr); |
726 | smp_read_barrier_depends(); | ||
727 | |||
728 | ptr = node->slots[0]; | 725 | ptr = node->slots[0]; |
729 | if (!assoc_array_ptr_is_meta(ptr)) | 726 | if (!assoc_array_ptr_is_meta(ptr)) |
730 | goto begin_node; | 727 | goto begin_node; |
@@ -736,7 +733,6 @@ descend_to_node: | |||
736 | kdebug("descend"); | 733 | kdebug("descend"); |
737 | if (assoc_array_ptr_is_shortcut(ptr)) { | 734 | if (assoc_array_ptr_is_shortcut(ptr)) { |
738 | shortcut = assoc_array_ptr_to_shortcut(ptr); | 735 | shortcut = assoc_array_ptr_to_shortcut(ptr); |
739 | smp_read_barrier_depends(); | ||
740 | ptr = READ_ONCE(shortcut->next_node); | 736 | ptr = READ_ONCE(shortcut->next_node); |
741 | BUG_ON(!assoc_array_ptr_is_node(ptr)); | 737 | BUG_ON(!assoc_array_ptr_is_node(ptr)); |
742 | } | 738 | } |
@@ -744,7 +740,6 @@ descend_to_node: | |||
744 | 740 | ||
745 | begin_node: | 741 | begin_node: |
746 | kdebug("begin_node"); | 742 | kdebug("begin_node"); |
747 | smp_read_barrier_depends(); | ||
748 | slot = 0; | 743 | slot = 0; |
749 | ascend_to_node: | 744 | ascend_to_node: |
750 | /* Go through the slots in a node */ | 745 | /* Go through the slots in a node */ |
@@ -792,14 +787,12 @@ ascend_to_node: | |||
792 | 787 | ||
793 | if (ptr && assoc_array_ptr_is_shortcut(ptr)) { | 788 | if (ptr && assoc_array_ptr_is_shortcut(ptr)) { |
794 | shortcut = assoc_array_ptr_to_shortcut(ptr); | 789 | shortcut = assoc_array_ptr_to_shortcut(ptr); |
795 | smp_read_barrier_depends(); | ||
796 | ptr = READ_ONCE(shortcut->back_pointer); | 790 | ptr = READ_ONCE(shortcut->back_pointer); |
797 | slot = shortcut->parent_slot; | 791 | slot = shortcut->parent_slot; |
798 | } | 792 | } |
799 | if (!ptr) | 793 | if (!ptr) |
800 | goto not_this_keyring; | 794 | goto not_this_keyring; |
801 | node = assoc_array_ptr_to_node(ptr); | 795 | node = assoc_array_ptr_to_node(ptr); |
802 | smp_read_barrier_depends(); | ||
803 | slot++; | 796 | slot++; |
804 | 797 | ||
805 | /* If we've ascended to the root (zero backpointer), we must have just | 798 | /* If we've ascended to the root (zero backpointer), we must have just |
diff --git a/tools/testing/selftests/rcutorture/bin/config2frag.sh b/tools/testing/selftests/rcutorture/bin/config2frag.sh deleted file mode 100755 index 56f51ae13d73..000000000000 --- a/tools/testing/selftests/rcutorture/bin/config2frag.sh +++ /dev/null | |||
@@ -1,25 +0,0 @@ | |||
1 | #!/bin/bash | ||
2 | # Usage: config2frag.sh < .config > configfrag | ||
3 | # | ||
4 | # Converts the "# CONFIG_XXX is not set" to "CONFIG_XXX=n" so that the | ||
5 | # resulting file becomes a legitimate Kconfig fragment. | ||
6 | # | ||
7 | # This program is free software; you can redistribute it and/or modify | ||
8 | # it under the terms of the GNU General Public License as published by | ||
9 | # the Free Software Foundation; either version 2 of the License, or | ||
10 | # (at your option) any later version. | ||
11 | # | ||
12 | # This program is distributed in the hope that it will be useful, | ||
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | # GNU General Public License for more details. | ||
16 | # | ||
17 | # You should have received a copy of the GNU General Public License | ||
18 | # along with this program; if not, you can access it online at | ||
19 | # http://www.gnu.org/licenses/gpl-2.0.html. | ||
20 | # | ||
21 | # Copyright (C) IBM Corporation, 2013 | ||
22 | # | ||
23 | # Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com> | ||
24 | |||
25 | LANG=C sed -e 's/^# CONFIG_\([a-zA-Z0-9_]*\) is not set$/CONFIG_\1=n/' | ||
diff --git a/tools/testing/selftests/rcutorture/bin/configinit.sh b/tools/testing/selftests/rcutorture/bin/configinit.sh index 51f66a7ce876..c15f270e121d 100755 --- a/tools/testing/selftests/rcutorture/bin/configinit.sh +++ b/tools/testing/selftests/rcutorture/bin/configinit.sh | |||
@@ -51,7 +51,7 @@ then | |||
51 | mkdir $builddir | 51 | mkdir $builddir |
52 | fi | 52 | fi |
53 | else | 53 | else |
54 | echo Bad build directory: \"$builddir\" | 54 | echo Bad build directory: \"$buildloc\" |
55 | exit 2 | 55 | exit 2 |
56 | fi | 56 | fi |
57 | fi | 57 | fi |
diff --git a/tools/testing/selftests/rcutorture/bin/kvm-build.sh b/tools/testing/selftests/rcutorture/bin/kvm-build.sh index fb66d0173638..34d126734cde 100755 --- a/tools/testing/selftests/rcutorture/bin/kvm-build.sh +++ b/tools/testing/selftests/rcutorture/bin/kvm-build.sh | |||
@@ -29,11 +29,6 @@ then | |||
29 | exit 1 | 29 | exit 1 |
30 | fi | 30 | fi |
31 | builddir=${2} | 31 | builddir=${2} |
32 | if test -z "$builddir" -o ! -d "$builddir" -o ! -w "$builddir" | ||
33 | then | ||
34 | echo "kvm-build.sh :$builddir: Not a writable directory, cannot build into it" | ||
35 | exit 1 | ||
36 | fi | ||
37 | 32 | ||
38 | T=${TMPDIR-/tmp}/test-linux.sh.$$ | 33 | T=${TMPDIR-/tmp}/test-linux.sh.$$ |
39 | trap 'rm -rf $T' 0 | 34 | trap 'rm -rf $T' 0 |
diff --git a/tools/testing/selftests/rcutorture/bin/kvm-recheck-lock.sh b/tools/testing/selftests/rcutorture/bin/kvm-recheck-lock.sh index 43f764098e50..2de92f43ee8c 100755 --- a/tools/testing/selftests/rcutorture/bin/kvm-recheck-lock.sh +++ b/tools/testing/selftests/rcutorture/bin/kvm-recheck-lock.sh | |||
@@ -23,7 +23,7 @@ | |||
23 | # Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 23 | # Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com> |
24 | 24 | ||
25 | i="$1" | 25 | i="$1" |
26 | if test -d $i | 26 | if test -d "$i" -a -r "$i" |
27 | then | 27 | then |
28 | : | 28 | : |
29 | else | 29 | else |
diff --git a/tools/testing/selftests/rcutorture/bin/kvm-recheck-rcu.sh b/tools/testing/selftests/rcutorture/bin/kvm-recheck-rcu.sh index 559e01ac86be..c2e1bb6d0cba 100755 --- a/tools/testing/selftests/rcutorture/bin/kvm-recheck-rcu.sh +++ b/tools/testing/selftests/rcutorture/bin/kvm-recheck-rcu.sh | |||
@@ -23,14 +23,14 @@ | |||
23 | # Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 23 | # Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com> |
24 | 24 | ||
25 | i="$1" | 25 | i="$1" |
26 | if test -d $i | 26 | if test -d "$i" -a -r "$i" |
27 | then | 27 | then |
28 | : | 28 | : |
29 | else | 29 | else |
30 | echo Unreadable results directory: $i | 30 | echo Unreadable results directory: $i |
31 | exit 1 | 31 | exit 1 |
32 | fi | 32 | fi |
33 | . tools/testing/selftests/rcutorture/bin/functions.sh | 33 | . functions.sh |
34 | 34 | ||
35 | configfile=`echo $i | sed -e 's/^.*\///'` | 35 | configfile=`echo $i | sed -e 's/^.*\///'` |
36 | ngps=`grep ver: $i/console.log 2> /dev/null | tail -1 | sed -e 's/^.* ver: //' -e 's/ .*$//'` | 36 | ngps=`grep ver: $i/console.log 2> /dev/null | tail -1 | sed -e 's/^.* ver: //' -e 's/ .*$//'` |
diff --git a/tools/testing/selftests/rcutorture/bin/kvm-recheck-rcuperf-ftrace.sh b/tools/testing/selftests/rcutorture/bin/kvm-recheck-rcuperf-ftrace.sh index f79b0e9e84fc..963f71289d22 100755 --- a/tools/testing/selftests/rcutorture/bin/kvm-recheck-rcuperf-ftrace.sh +++ b/tools/testing/selftests/rcutorture/bin/kvm-recheck-rcuperf-ftrace.sh | |||
@@ -26,7 +26,7 @@ | |||
26 | # Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 26 | # Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com> |
27 | 27 | ||
28 | i="$1" | 28 | i="$1" |
29 | . tools/testing/selftests/rcutorture/bin/functions.sh | 29 | . functions.sh |
30 | 30 | ||
31 | if test "`grep -c 'rcu_exp_grace_period.*start' < $i/console.log`" -lt 100 | 31 | if test "`grep -c 'rcu_exp_grace_period.*start' < $i/console.log`" -lt 100 |
32 | then | 32 | then |
diff --git a/tools/testing/selftests/rcutorture/bin/kvm-recheck-rcuperf.sh b/tools/testing/selftests/rcutorture/bin/kvm-recheck-rcuperf.sh index 8f3121afc716..ccebf772fa1e 100755 --- a/tools/testing/selftests/rcutorture/bin/kvm-recheck-rcuperf.sh +++ b/tools/testing/selftests/rcutorture/bin/kvm-recheck-rcuperf.sh | |||
@@ -23,7 +23,7 @@ | |||
23 | # Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 23 | # Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com> |
24 | 24 | ||
25 | i="$1" | 25 | i="$1" |
26 | if test -d $i | 26 | if test -d "$i" -a -r "$i" |
27 | then | 27 | then |
28 | : | 28 | : |
29 | else | 29 | else |
@@ -31,7 +31,7 @@ else | |||
31 | exit 1 | 31 | exit 1 |
32 | fi | 32 | fi |
33 | PATH=`pwd`/tools/testing/selftests/rcutorture/bin:$PATH; export PATH | 33 | PATH=`pwd`/tools/testing/selftests/rcutorture/bin:$PATH; export PATH |
34 | . tools/testing/selftests/rcutorture/bin/functions.sh | 34 | . functions.sh |
35 | 35 | ||
36 | if kvm-recheck-rcuperf-ftrace.sh $i | 36 | if kvm-recheck-rcuperf-ftrace.sh $i |
37 | then | 37 | then |
diff --git a/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh b/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh index f659346d3358..f7e988f369dd 100755 --- a/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh +++ b/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh | |||
@@ -25,7 +25,7 @@ | |||
25 | # Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 25 | # Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com> |
26 | 26 | ||
27 | PATH=`pwd`/tools/testing/selftests/rcutorture/bin:$PATH; export PATH | 27 | PATH=`pwd`/tools/testing/selftests/rcutorture/bin:$PATH; export PATH |
28 | . tools/testing/selftests/rcutorture/bin/functions.sh | 28 | . functions.sh |
29 | for rd in "$@" | 29 | for rd in "$@" |
30 | do | 30 | do |
31 | firsttime=1 | 31 | firsttime=1 |
diff --git a/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh b/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh index ab14b97c942c..1b78a12740e5 100755 --- a/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh +++ b/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh | |||
@@ -42,7 +42,7 @@ T=${TMPDIR-/tmp}/kvm-test-1-run.sh.$$ | |||
42 | trap 'rm -rf $T' 0 | 42 | trap 'rm -rf $T' 0 |
43 | mkdir $T | 43 | mkdir $T |
44 | 44 | ||
45 | . $KVM/bin/functions.sh | 45 | . functions.sh |
46 | . $CONFIGFRAG/ver_functions.sh | 46 | . $CONFIGFRAG/ver_functions.sh |
47 | 47 | ||
48 | config_template=${1} | 48 | config_template=${1} |
@@ -154,9 +154,7 @@ cpu_count=`configfrag_boot_cpus "$boot_args" "$config_template" "$cpu_count"` | |||
154 | vcpus=`identify_qemu_vcpus` | 154 | vcpus=`identify_qemu_vcpus` |
155 | if test $cpu_count -gt $vcpus | 155 | if test $cpu_count -gt $vcpus |
156 | then | 156 | then |
157 | echo CPU count limited from $cpu_count to $vcpus | 157 | echo CPU count limited from $cpu_count to $vcpus | tee -a $resdir/Warnings |
158 | touch $resdir/Warnings | ||
159 | echo CPU count limited from $cpu_count to $vcpus >> $resdir/Warnings | ||
160 | cpu_count=$vcpus | 158 | cpu_count=$vcpus |
161 | fi | 159 | fi |
162 | qemu_args="`specify_qemu_cpus "$QEMU" "$qemu_args" "$cpu_count"`" | 160 | qemu_args="`specify_qemu_cpus "$QEMU" "$qemu_args" "$cpu_count"`" |
diff --git a/tools/testing/selftests/rcutorture/bin/kvm.sh b/tools/testing/selftests/rcutorture/bin/kvm.sh index ccd49e958fd2..7d1f607f0f76 100755 --- a/tools/testing/selftests/rcutorture/bin/kvm.sh +++ b/tools/testing/selftests/rcutorture/bin/kvm.sh | |||
@@ -1,8 +1,7 @@ | |||
1 | #!/bin/bash | 1 | #!/bin/bash |
2 | # | 2 | # |
3 | # Run a series of 14 tests under KVM. These are not particularly | 3 | # Run a series of 14 tests under KVM. These are not particularly |
4 | # well-selected or well-tuned, but are the current set. Run from the | 4 | # well-selected or well-tuned, but are the current set. |
5 | # top level of the source tree. | ||
6 | # | 5 | # |
7 | # Edit the definitions below to set the locations of the various directories, | 6 | # Edit the definitions below to set the locations of the various directories, |
8 | # as well as the test duration. | 7 | # as well as the test duration. |
@@ -34,6 +33,8 @@ T=${TMPDIR-/tmp}/kvm.sh.$$ | |||
34 | trap 'rm -rf $T' 0 | 33 | trap 'rm -rf $T' 0 |
35 | mkdir $T | 34 | mkdir $T |
36 | 35 | ||
36 | cd `dirname $scriptname`/../../../../../ | ||
37 | |||
37 | dur=$((30*60)) | 38 | dur=$((30*60)) |
38 | dryrun="" | 39 | dryrun="" |
39 | KVM="`pwd`/tools/testing/selftests/rcutorture"; export KVM | 40 | KVM="`pwd`/tools/testing/selftests/rcutorture"; export KVM |
@@ -70,7 +71,7 @@ usage () { | |||
70 | echo " --kmake-arg kernel-make-arguments" | 71 | echo " --kmake-arg kernel-make-arguments" |
71 | echo " --mac nn:nn:nn:nn:nn:nn" | 72 | echo " --mac nn:nn:nn:nn:nn:nn" |
72 | echo " --no-initrd" | 73 | echo " --no-initrd" |
73 | echo " --qemu-args qemu-system-..." | 74 | echo " --qemu-args qemu-arguments" |
74 | echo " --qemu-cmd qemu-system-..." | 75 | echo " --qemu-cmd qemu-system-..." |
75 | echo " --results absolute-pathname" | 76 | echo " --results absolute-pathname" |
76 | echo " --torture rcu" | 77 | echo " --torture rcu" |
@@ -150,7 +151,7 @@ do | |||
150 | TORTURE_INITRD=""; export TORTURE_INITRD | 151 | TORTURE_INITRD=""; export TORTURE_INITRD |
151 | ;; | 152 | ;; |
152 | --qemu-args|--qemu-arg) | 153 | --qemu-args|--qemu-arg) |
153 | checkarg --qemu-args "-qemu args" $# "$2" '^-' '^error' | 154 | checkarg --qemu-args "(qemu arguments)" $# "$2" '^-' '^error' |
154 | TORTURE_QEMU_ARG="$2" | 155 | TORTURE_QEMU_ARG="$2" |
155 | shift | 156 | shift |
156 | ;; | 157 | ;; |
@@ -238,7 +239,6 @@ BEGIN { | |||
238 | } | 239 | } |
239 | 240 | ||
240 | END { | 241 | END { |
241 | alldone = 0; | ||
242 | batch = 0; | 242 | batch = 0; |
243 | nc = -1; | 243 | nc = -1; |
244 | 244 | ||
@@ -331,8 +331,7 @@ awk < $T/cfgcpu.pack \ | |||
331 | # Dump out the scripting required to run one test batch. | 331 | # Dump out the scripting required to run one test batch. |
332 | function dump(first, pastlast, batchnum) | 332 | function dump(first, pastlast, batchnum) |
333 | { | 333 | { |
334 | print "echo ----Start batch " batchnum ": `date`"; | 334 | print "echo ----Start batch " batchnum ": `date` | tee -a " rd "log"; |
335 | print "echo ----Start batch " batchnum ": `date` >> " rd "/log"; | ||
336 | print "needqemurun=" | 335 | print "needqemurun=" |
337 | jn=1 | 336 | jn=1 |
338 | for (j = first; j < pastlast; j++) { | 337 | for (j = first; j < pastlast; j++) { |
@@ -349,21 +348,18 @@ function dump(first, pastlast, batchnum) | |||
349 | ovf = "-ovf"; | 348 | ovf = "-ovf"; |
350 | else | 349 | else |
351 | ovf = ""; | 350 | ovf = ""; |
352 | print "echo ", cfr[jn], cpusr[jn] ovf ": Starting build. `date`"; | 351 | print "echo ", cfr[jn], cpusr[jn] ovf ": Starting build. `date` | tee -a " rd "log"; |
353 | print "echo ", cfr[jn], cpusr[jn] ovf ": Starting build. `date` >> " rd "/log"; | ||
354 | print "rm -f " builddir ".*"; | 352 | print "rm -f " builddir ".*"; |
355 | print "touch " builddir ".wait"; | 353 | print "touch " builddir ".wait"; |
356 | print "mkdir " builddir " > /dev/null 2>&1 || :"; | 354 | print "mkdir " builddir " > /dev/null 2>&1 || :"; |
357 | print "mkdir " rd cfr[jn] " || :"; | 355 | print "mkdir " rd cfr[jn] " || :"; |
358 | print "kvm-test-1-run.sh " CONFIGDIR cf[j], builddir, rd cfr[jn], dur " \"" TORTURE_QEMU_ARG "\" \"" TORTURE_BOOTARGS "\" > " rd cfr[jn] "/kvm-test-1-run.sh.out 2>&1 &" | 356 | print "kvm-test-1-run.sh " CONFIGDIR cf[j], builddir, rd cfr[jn], dur " \"" TORTURE_QEMU_ARG "\" \"" TORTURE_BOOTARGS "\" > " rd cfr[jn] "/kvm-test-1-run.sh.out 2>&1 &" |
359 | print "echo ", cfr[jn], cpusr[jn] ovf ": Waiting for build to complete. `date`"; | 357 | print "echo ", cfr[jn], cpusr[jn] ovf ": Waiting for build to complete. `date` | tee -a " rd "log"; |
360 | print "echo ", cfr[jn], cpusr[jn] ovf ": Waiting for build to complete. `date` >> " rd "/log"; | ||
361 | print "while test -f " builddir ".wait" | 358 | print "while test -f " builddir ".wait" |
362 | print "do" | 359 | print "do" |
363 | print "\tsleep 1" | 360 | print "\tsleep 1" |
364 | print "done" | 361 | print "done" |
365 | print "echo ", cfr[jn], cpusr[jn] ovf ": Build complete. `date`"; | 362 | print "echo ", cfr[jn], cpusr[jn] ovf ": Build complete. `date` | tee -a " rd "log"; |
366 | print "echo ", cfr[jn], cpusr[jn] ovf ": Build complete. `date` >> " rd "/log"; | ||
367 | jn++; | 363 | jn++; |
368 | } | 364 | } |
369 | for (j = 1; j < jn; j++) { | 365 | for (j = 1; j < jn; j++) { |
@@ -371,8 +367,7 @@ function dump(first, pastlast, batchnum) | |||
371 | print "rm -f " builddir ".ready" | 367 | print "rm -f " builddir ".ready" |
372 | print "if test -f \"" rd cfr[j] "/builtkernel\"" | 368 | print "if test -f \"" rd cfr[j] "/builtkernel\"" |
373 | print "then" | 369 | print "then" |
374 | print "\techo ----", cfr[j], cpusr[j] ovf ": Kernel present. `date`"; | 370 | print "\techo ----", cfr[j], cpusr[j] ovf ": Kernel present. `date` | tee -a " rd "log"; |
375 | print "\techo ----", cfr[j], cpusr[j] ovf ": Kernel present. `date` >> " rd "/log"; | ||
376 | print "\tneedqemurun=1" | 371 | print "\tneedqemurun=1" |
377 | print "fi" | 372 | print "fi" |
378 | } | 373 | } |
@@ -386,31 +381,26 @@ function dump(first, pastlast, batchnum) | |||
386 | njitter = ja[1]; | 381 | njitter = ja[1]; |
387 | if (TORTURE_BUILDONLY && njitter != 0) { | 382 | if (TORTURE_BUILDONLY && njitter != 0) { |
388 | njitter = 0; | 383 | njitter = 0; |
389 | print "echo Build-only run, so suppressing jitter >> " rd "/log" | 384 | print "echo Build-only run, so suppressing jitter | tee -a " rd "log" |
390 | } | 385 | } |
391 | if (TORTURE_BUILDONLY) { | 386 | if (TORTURE_BUILDONLY) { |
392 | print "needqemurun=" | 387 | print "needqemurun=" |
393 | } | 388 | } |
394 | print "if test -n \"$needqemurun\"" | 389 | print "if test -n \"$needqemurun\"" |
395 | print "then" | 390 | print "then" |
396 | print "\techo ---- Starting kernels. `date`"; | 391 | print "\techo ---- Starting kernels. `date` | tee -a " rd "log"; |
397 | print "\techo ---- Starting kernels. `date` >> " rd "/log"; | ||
398 | for (j = 0; j < njitter; j++) | 392 | for (j = 0; j < njitter; j++) |
399 | print "\tjitter.sh " j " " dur " " ja[2] " " ja[3] "&" | 393 | print "\tjitter.sh " j " " dur " " ja[2] " " ja[3] "&" |
400 | print "\twait" | 394 | print "\twait" |
401 | print "\techo ---- All kernel runs complete. `date`"; | 395 | print "\techo ---- All kernel runs complete. `date` | tee -a " rd "log"; |
402 | print "\techo ---- All kernel runs complete. `date` >> " rd "/log"; | ||
403 | print "else" | 396 | print "else" |
404 | print "\twait" | 397 | print "\twait" |
405 | print "\techo ---- No kernel runs. `date`"; | 398 | print "\techo ---- No kernel runs. `date` | tee -a " rd "log"; |
406 | print "\techo ---- No kernel runs. `date` >> " rd "/log"; | ||
407 | print "fi" | 399 | print "fi" |
408 | for (j = 1; j < jn; j++) { | 400 | for (j = 1; j < jn; j++) { |
409 | builddir=KVM "/b" j | 401 | builddir=KVM "/b" j |
410 | print "echo ----", cfr[j], cpusr[j] ovf ": Build/run results:"; | 402 | print "echo ----", cfr[j], cpusr[j] ovf ": Build/run results: | tee -a " rd "log"; |
411 | print "echo ----", cfr[j], cpusr[j] ovf ": Build/run results: >> " rd "/log"; | 403 | print "cat " rd cfr[j] "/kvm-test-1-run.sh.out | tee -a " rd "log"; |
412 | print "cat " rd cfr[j] "/kvm-test-1-run.sh.out"; | ||
413 | print "cat " rd cfr[j] "/kvm-test-1-run.sh.out >> " rd "/log"; | ||
414 | } | 404 | } |
415 | } | 405 | } |
416 | 406 | ||
diff --git a/tools/testing/selftests/rcutorture/bin/parse-torture.sh b/tools/testing/selftests/rcutorture/bin/parse-torture.sh index f12c38909b00..5987e50cfeb4 100755 --- a/tools/testing/selftests/rcutorture/bin/parse-torture.sh +++ b/tools/testing/selftests/rcutorture/bin/parse-torture.sh | |||
@@ -55,7 +55,7 @@ then | |||
55 | exit | 55 | exit |
56 | fi | 56 | fi |
57 | 57 | ||
58 | grep --binary-files=text 'torture:.*ver:' $file | grep --binary-files=text -v '(null)' | sed -e 's/^(initramfs)[^]]*] //' -e 's/^\[[^]]*] //' | | 58 | grep --binary-files=text 'torture:.*ver:' $file | egrep --binary-files=text -v '\(null\)|rtc: 000000000* ' | sed -e 's/^(initramfs)[^]]*] //' -e 's/^\[[^]]*] //' | |
59 | awk ' | 59 | awk ' |
60 | BEGIN { | 60 | BEGIN { |
61 | ver = 0; | 61 | ver = 0; |
diff --git a/tools/testing/selftests/rcutorture/configs/lock/ver_functions.sh b/tools/testing/selftests/rcutorture/configs/lock/ver_functions.sh index 252aae618984..80eb646e1319 100644 --- a/tools/testing/selftests/rcutorture/configs/lock/ver_functions.sh +++ b/tools/testing/selftests/rcutorture/configs/lock/ver_functions.sh | |||
@@ -38,6 +38,5 @@ per_version_boot_params () { | |||
38 | echo $1 `locktorture_param_onoff "$1" "$2"` \ | 38 | echo $1 `locktorture_param_onoff "$1" "$2"` \ |
39 | locktorture.stat_interval=15 \ | 39 | locktorture.stat_interval=15 \ |
40 | locktorture.shutdown_secs=$3 \ | 40 | locktorture.shutdown_secs=$3 \ |
41 | locktorture.torture_runnable=1 \ | ||
42 | locktorture.verbose=1 | 41 | locktorture.verbose=1 |
43 | } | 42 | } |
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/ver_functions.sh b/tools/testing/selftests/rcutorture/configs/rcu/ver_functions.sh index ffb85ed786fa..24ec91041957 100644 --- a/tools/testing/selftests/rcutorture/configs/rcu/ver_functions.sh +++ b/tools/testing/selftests/rcutorture/configs/rcu/ver_functions.sh | |||
@@ -51,7 +51,6 @@ per_version_boot_params () { | |||
51 | `rcutorture_param_n_barrier_cbs "$1"` \ | 51 | `rcutorture_param_n_barrier_cbs "$1"` \ |
52 | rcutorture.stat_interval=15 \ | 52 | rcutorture.stat_interval=15 \ |
53 | rcutorture.shutdown_secs=$3 \ | 53 | rcutorture.shutdown_secs=$3 \ |
54 | rcutorture.torture_runnable=1 \ | ||
55 | rcutorture.test_no_idle_hz=1 \ | 54 | rcutorture.test_no_idle_hz=1 \ |
56 | rcutorture.verbose=1 | 55 | rcutorture.verbose=1 |
57 | } | 56 | } |
diff --git a/tools/testing/selftests/rcutorture/configs/rcuperf/ver_functions.sh b/tools/testing/selftests/rcutorture/configs/rcuperf/ver_functions.sh index 34f2a1b35ee5..b9603115d7c7 100644 --- a/tools/testing/selftests/rcutorture/configs/rcuperf/ver_functions.sh +++ b/tools/testing/selftests/rcutorture/configs/rcuperf/ver_functions.sh | |||
@@ -46,7 +46,6 @@ rcuperf_param_nwriters () { | |||
46 | per_version_boot_params () { | 46 | per_version_boot_params () { |
47 | echo $1 `rcuperf_param_nreaders "$1"` \ | 47 | echo $1 `rcuperf_param_nreaders "$1"` \ |
48 | `rcuperf_param_nwriters "$1"` \ | 48 | `rcuperf_param_nwriters "$1"` \ |
49 | rcuperf.perf_runnable=1 \ | ||
50 | rcuperf.shutdown=1 \ | 49 | rcuperf.shutdown=1 \ |
51 | rcuperf.verbose=1 | 50 | rcuperf.verbose=1 |
52 | } | 51 | } |