]> www.infradead.org Git - linux.git/commitdiff
rcu: Avoid ->dynticks_nmi_nesting store tearing
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Mon, 2 Oct 2017 23:54:49 +0000 (16:54 -0700)
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Mon, 27 Nov 2017 16:40:09 +0000 (08:40 -0800)
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 <paulmck@linux.vnet.ibm.com>
kernel/rcu/tree.c

index f9c0ca2ccf0ca530ab8bb53ad54039c62c858a87..c5d960f86cf86bd5e47007ea12e1a1c97e8c794d 100644 (file)
@@ -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();
 }