• Andrew Morton's avatar
    [PATCH] rcu lock update: Add per-cpu batch counter · 5c60169a
    Andrew Morton authored
    From: Manfred Spraul <manfred@colorfullife.com>
    
    Below is the one of my patches from my rcu lock update.  Jack Steiner tested
    the first one on a 512p and it resolved the rcu cache line trashing.  All were
    tested on osdl with STP.
    
    Step one for reducing cacheline trashing within rcupdate.c:
    
    The current code uses the rcu_cpu_mask bitmap both for keeping track of the
    cpus that haven't gone through a quiescent state and for checking if a cpu
    should look for quiescent states.  The bitmap is frequently changed and the
    check is done by polling - together this causes cache line trashing.
    
    If it's cheaper to access a (mostly) read-only cacheline than a cacheline that
    is frequently dirtied, then it's possible to reduce the trashing by splitting
    the rcu_cpu_mask bitmap into two cachelines:
    
    The patch adds a generation counter and moves it into a separate cacheline.
    This allows to removes all accesses to rcu_cpumask (in the read-write
    cacheline) from rcu_pending and at least 50% of the accesses from
    rcu_check_quiescent_state.  rcu_pending and all but one call per cpu to
    rcu_check_quiescent_state access the read-only cacheline.  Probably not enough
    for 512p, but it's a start, just for 128 byte more memory use, without slowing
    down rcu grace periods.  Obviously the read-only cacheline is not really
    read-only: it's written once per grace period to indicate that a new grace
    period is running.
    
    Tests on an 8-way Pentium III with reaim showed some improvement:
    
    oprofile hits:
    Reference: http://khack.osdl.org/stp/293075/
    Hits	   %
    23741     0.0994  rcu_pending
    19057     0.0798  rcu_check_quiescent_state
    6530      0.0273  rcu_check_callbacks
    
    Patched: http://khack.osdl.org/stp/293076/
    8291      0.0579  rcu_pending
    5475      0.0382  rcu_check_quiescent_state
    3604      0.0252  rcu_check_callbacks
    
    The total runtime differs between both runs, thus the % number must
    be compared: Around 50% faster. I've uninlined rcu_pending for the
    test.
    
    Tested with reaim and kernbench.
    
    Description:
    
    - per-cpu quiescbatch and qs_pending fields introduced: quiescbatch contains
      the number of the last quiescent period that the cpu has seen and qs_pending
      is set if the cpu has not yet reported the quiescent state for the current
      period.  With these two fields a cpu can test if it should report a
      quiescent state without having to look at the frequently written
      rcu_cpu_mask bitmap.
    
    - curbatch split into two fields: rcu_ctrlblk.batch.completed and
      rcu_ctrlblk.batch.cur.  This makes it possible to figure out if a grace
      period is running (completed != cur) without accessing the rcu_cpu_mask
      bitmap.
    
    - rcu_ctrlblk.maxbatch removed and replaced with a true/false next_pending
      flag: next_pending=1 means that another grace period should be started
      immediately after the end of the current period.  Previously, this was
      achieved by maxbatch: curbatch==maxbatch means don't start, curbatch!=
      maxbatch means start.  A flag improves the readability: The only possible
      values for maxbatch were curbatch and curbatch+1.
    
    - rcu_ctrlblk split into two cachelines for better performance.
    
    - common code from rcu_offline_cpu and rcu_check_quiescent_state merged into
      cpu_quiet.
    
    - rcu_offline_cpu: replace spin_lock_irq with spin_lock_bh, there are no
      accesses from irq context (and there are accesses to the spinlock with
      enabled interrupts from tasklet context).
    
    - rcu_restart_cpu introduced, s390 should call it after changing nohz:
      Theoretically the global batch counter could wrap around and end up at
      RCU_quiescbatch(cpu).  Then the cpu would not look for a quiescent state and
      rcu would lock up.
    Signed-off-by: default avatarManfred Spraul <manfred@colorfullife.com>
    Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
    5c60169a
rcupdate.c 10.3 KB