• Paul E. McKenney's avatar
    srcu: Update comment after the index flip · dafc4d16
    Paul E. McKenney authored
    Because there is not guaranteed to be a full memory barrier between
    the ->srcu_unlock_count increment of an srcu_read_unlock() and the
    ->srcu_lock_count increment of the next srcu_read_lock(), this next
    srcu_read_lock() is not guaranteed to see the effect of the index flip
    just prior to this comment.  However, this next srcu_read_lock() will
    execute a full memory barrier, so the srcu_read_lock() after that is
    guaranteed to see that index flip.
    
    This guarantee is illustrated by the following diagram of events and
    the litmus test following that.
    
    ------------------------------------------------------------------------
    
    READER                  UPDATER
    -------------           ----------
                               // idx is initially 0.
    
                               srcu_flip() {
                                  smp_mb();
    // RSCS
    
    srcu_read_unlock() {
      smp_mb();
                                  idx++;    // P
                                  smp_mb(); // QQ
                               }
    
                               srcu_readers_unlock_idx(0) {
            ,--counted------------ count all unlock[0]; // Q
            |
      unlock[0]++;  // X
    
    }
                                   smp_mb();
    srcu_read_lock() {
      READ(idx) = 0;         ,---- count all lock[0]; // contributes imbalance of 1.
      lock[0]++;  ----counted              |
      smp_mb(); // PP          }           |
    }                                      |
                                           |
    // RSCS                             not going to effect above scan
                                           |
    srcu_read_unlock() {                   |
      smp_mb();                            |
      unlock[0]++;                         |
    }                                      |
                                          /
                                         /
    srcu_read_lock() {                  |
      READ(idx);  // Y  -----cannot be counted because of P (has to sample idx as 1)
      lock[1]++;
      ...
    }
    
    ------------------------------------------------------------------------
    
    This makes it similar to the store buffer pattern. Using X, Y, P and Q
    annotated above, we get:
    
    ------------------------------------------------------------------------
    
    READER                    UPDATER
    X (write)                 P (write)
    
    smp_mb(); //PP            smp_mb(); //QQ
    
    Y (read)                  Q (read)
    
    ------------------------------------------------------------------------
    
    ASCII art courtesy of Joel Fernandes.
    Reported-by: default avatarJoel Fernandes <joel@joelfernandes.org>
    Reported-by: default avatarBoqun Feng <boqun.feng@gmail.com>
    Reported-by: default avatarFrederic Weisbecker <frederic@kernel.org>
    Reported-by: default avatarNeeraj Upadhyay <quic_neeraju@quicinc.com>
    Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
    dafc4d16
srcutree.c 64.2 KB