NMIs can nest, and store tearing could in theory happen on carries
from one byte to the next.  This commit therefore adds the WRITE_ONCE()
macros preventing this.

Signed-off-by: Paul E. McKenney <[email protected]>
---
 kernel/rcu/tree.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index f9c0ca2ccf0c..c5d960f86cf8 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -1103,7 +1103,8 @@ void rcu_nmi_enter(void)
                rcu_dynticks_eqs_exit();
                incby = 1;
        }
-       rdtp->dynticks_nmi_nesting += incby;
+       WRITE_ONCE(rdtp->dynticks_nmi_nesting, /* Prevent store tearing. */
+                  rdtp->dynticks_nmi_nesting + incby);
        barrier();
 }
 
@@ -1135,12 +1136,13 @@ void rcu_nmi_exit(void)
         * leave it in non-RCU-idle state.
         */
        if (rdtp->dynticks_nmi_nesting != 1) {
-               rdtp->dynticks_nmi_nesting -= 2;
+               WRITE_ONCE(rdtp->dynticks_nmi_nesting, /* No store tearing. */
+                          rdtp->dynticks_nmi_nesting - 2);
                return;
        }
 
        /* This NMI interrupted an RCU-idle CPU, restore RCU-idleness. */
-       rdtp->dynticks_nmi_nesting = 0;
+       WRITE_ONCE(rdtp->dynticks_nmi_nesting, 0); /* Avoid store tearing. */
        rcu_dynticks_eqs_enter();
 }
 
-- 
2.5.2

Reply via email to