25 Jan, 2020

1 commit

  • This commit removes kfree_rcu() special-casing and the lazy-callback
    handling from Tree RCU. It moves some of this special casing to Tiny RCU,
    the removal of which will be the subject of later commits.

    This results in a nice negative delta.

    Suggested-by: Paul E. McKenney
    Signed-off-by: Joel Fernandes (Google)
    [ paulmck: Add slab.h #include, thanks to kbuild test robot . ]
    Signed-off-by: Paul E. McKenney

    Joel Fernandes (Google)
     

14 Aug, 2019

8 commits

  • Use of the rcu_data structure's segmented ->cblist for no-CBs CPUs
    takes advantage of unrelated grace periods, thus reducing the memory
    footprint in the face of floods of call_rcu() invocations. However,
    the ->cblist field is a more-complex rcu_segcblist structure which must
    be protected via locking. Even though there are only three entities
    which can acquire this lock (the CPU invoking call_rcu(), the no-CBs
    grace-period kthread, and the no-CBs callbacks kthread), the contention
    on this lock is excessive under heavy stress.

    This commit therefore greatly reduces contention by provisioning
    an rcu_cblist structure field named ->nocb_bypass within the
    rcu_data structure. Each no-CBs CPU is permitted only a limited
    number of enqueues onto the ->cblist per jiffy, controlled by a new
    nocb_nobypass_lim_per_jiffy kernel boot parameter that defaults to
    about 16 enqueues per millisecond (16 * 1000 / HZ). When that limit is
    exceeded, the CPU instead enqueues onto the new ->nocb_bypass.

    The ->nocb_bypass is flushed into the ->cblist every jiffy or when
    the number of callbacks on ->nocb_bypass exceeds qhimark, whichever
    happens first. During call_rcu() floods, this flushing is carried out
    by the CPU during the course of its call_rcu() invocations. However,
    a CPU could simply stop invoking call_rcu() at any time. The no-CBs
    grace-period kthread therefore carries out less-aggressive flushing
    (every few jiffies or when the number of callbacks on ->nocb_bypass
    exceeds (2 * qhimark), whichever comes first). This means that the
    no-CBs grace-period kthread cannot be permitted to do unbounded waits
    while there are callbacks on ->nocb_bypass. A ->nocb_bypass_timer is
    used to provide the needed wakeups.

    [ paulmck: Apply Coverity feedback reported by Colin Ian King. ]
    Signed-off-by: Paul E. McKenney

    Paul E. McKenney
     
  • Upcoming ->nocb_lock contention-reduction work requires that the
    rcu_segcblist structure's ->len field be concurrently manipulated,
    but only if there are no-CBs CPUs in the kernel. This commit
    therefore makes this ->len field be an atomic_long_t, but only
    in CONFIG_RCU_NOCB_CPU=y kernels.

    Signed-off-by: Paul E. McKenney

    Paul E. McKenney
     
  • Currently the RCU callbacks for no-CBs CPUs are queued on a series of
    ad-hoc linked lists, which means that these callbacks cannot benefit
    from "drive-by" grace periods, thus suffering needless delays prior
    to invocation. In addition, the no-CBs grace-period kthreads first
    wait for callbacks to appear and later wait for a new grace period,
    which means that callbacks appearing during a grace-period wait can
    be delayed. These delays increase memory footprint, and could even
    result in an out-of-memory condition.

    This commit therefore enqueues RCU callbacks from no-CBs CPUs on the
    rcu_segcblist structure that is already used by non-no-CBs CPUs. It also
    restructures the no-CBs grace-period kthread to be checking for incoming
    callbacks while waiting for grace periods. Also, instead of waiting
    for a new grace period, it waits for the closest grace period that will
    cause some of the callbacks to be safe to invoke. All of these changes
    reduce callback latency and thus the number of outstanding callbacks,
    in turn reducing the probability of an out-of-memory condition.

    Signed-off-by: Paul E. McKenney

    Paul E. McKenney
     
  • As a first step towards making no-CBs CPUs use the ->cblist, this commit
    leaves the ->cblist enabled for these CPUs. The main reason to make
    no-CBs CPUs use ->cblist is to take advantage of callback numbering,
    which will reduce the effects of missed grace periods which in turn will
    reduce forward-progress problems for no-CBs CPUs.

    Signed-off-by: Paul E. McKenney

    Paul E. McKenney
     
  • Currently, rcu_segcblist_empty() assumes that the callback list is not
    being changed by other CPUs, but upcoming changes will require it to
    operate locklessly. This commit therefore adds the needed READ_ONCE()
    call, along with the WRITE_ONCE() calls when updating the callback list's
    ->head field.

    Signed-off-by: Paul E. McKenney

    Paul E. McKenney
     
  • Currently, rcu_segcblist_restempty() assumes that the callback list
    is not being changed by other CPUs, but upcoming changes will require
    it to operate locklessly. This commit therefore adds the needed
    READ_ONCE() calls, along with the WRITE_ONCE() calls when updating
    the callback list.

    Signed-off-by: Paul E. McKenney

    Paul E. McKenney
     
  • RCU callback processing currently uses rcu_is_nocb_cpu() to determine
    whether or not the current CPU's callbacks are to be offloaded.
    This works, but it is not so good for cache locality. Plus use of
    ->cblist for offloaded callbacks will greatly increase the frequency
    of these checks. This commit therefore adds a ->offloaded flag to the
    rcu_segcblist structure to provide a more flexible and cache-friendly
    means of checking for callback offloading.

    Signed-off-by: Paul E. McKenney

    Paul E. McKenney
     
  • NULLing the RCU_NEXT_TAIL pointer was a clever way to save a byte, but
    forward-progress considerations would require that this pointer be both
    NULL and non-NULL, which, absent a quantum-computer port of the Linux
    kernel, simply won't happen. This commit therefore creates as separate
    ->enabled flag to replace the current NULL checks.

    [ paulmck: Add include files per 0day test robot and -next. ]
    Signed-off-by: Paul E. McKenney

    Paul E. McKenney
     

02 Aug, 2019

1 commit

  • Because pointer output is now obfuscated, and because what you really
    want to know is whether or not the callback lists are empty, this commit
    replaces the srcu_data structure's head callback pointer printout with
    a single character that is "." is the callback list is empty or "C"
    otherwise.

    This is the only remaining user of rcu_segcblist_head(), so this
    commit also removes this function's definition. It also turns out that
    rcu_segcblist_tail() no longer has any callers, so this commit removes
    that function's definition while in the area. They were both marked
    "Interim", and their end has come.

    Signed-off-by: Paul E. McKenney

    Paul E. McKenney
     

10 Feb, 2019

1 commit


16 May, 2018

1 commit

  • Now that RCU no longer relies on failsafe checks, cpu_needs_another_gp()
    can be greatly simplified. This simplification eliminates the last
    call to rcu_future_needs_gp() and to rcu_segcblist_future_gp_needed(),
    both of which which can then be eliminated. And then, because
    cpu_needs_another_gp() is called only from __rcu_pending(), it can be
    inlined and eliminated.

    This commit carries out the simplification, inlining, and elimination
    called out above.

    Signed-off-by: Paul E. McKenney
    Tested-by: Nicholas Piggin

    Paul E. McKenney
     

26 Jul, 2017

2 commits

  • Given changes to callback migration, rcu_cblist_head(),
    rcu_cblist_tail(), rcu_cblist_count_cbs(), rcu_segcblist_segempty(),
    rcu_segcblist_dequeued_lazy(), and rcu_segcblist_new_cbs() are
    no longer used. This commit therefore removes them.

    Signed-off-by: Paul E. McKenney

    Paul E. McKenney
     
  • Given that the rcu_state structure's >orphan_pend and ->orphan_done
    fields are used only during migration of callbacks from the recently
    offlined CPU to a surviving CPU, if rcu_send_cbs_to_orphanage() and
    rcu_adopt_orphan_cbs() are combined, these fields can become local
    variables in the combined function. This commit therefore combines
    rcu_send_cbs_to_orphanage() and rcu_adopt_orphan_cbs() into a new
    rcu_segcblist_merge() function and removes the ->orphan_pend and
    ->orphan_done fields.

    Signed-off-by: Paul E. McKenney

    Paul E. McKenney
     

03 May, 2017

2 commits

  • Because the rcu_cblist_n_lazy_cbs() just samples the ->len_lazy counter,
    and because the rcu_cblist structure is quite straightforward, it makes
    sense to open-code rcu_cblist_n_lazy_cbs(p) as p->len_lazy, cutting out
    a level of indirection. This commit makes this change.

    Reported-by: Ingo Molnar
    Signed-off-by: Paul E. McKenney
    Cc: Peter Zijlstra
    Cc: Thomas Gleixner
    Cc: Linus Torvalds

    Paul E. McKenney
     
  • Because the rcu_cblist_n_cbs() just samples the ->len counter, and
    because the rcu_cblist structure is quite straightforward, it makes
    sense to open-code rcu_cblist_n_cbs(p) as p->len, cutting out a level
    of indirection. This commit makes this change.

    Reported-by: Ingo Molnar
    Signed-off-by: Paul E. McKenney
    Cc: Peter Zijlstra
    Cc: Thomas Gleixner
    Cc: Linus Torvalds

    Paul E. McKenney
     

02 May, 2017

3 commits

  • Because the rcu_cblist_empty() just samples the ->head pointer, and
    because the rcu_cblist structure is quite straightforward, it makes
    sense to open-code rcu_cblist_empty(p) as !p->head, cutting out a
    level of indirection. This commit makes this change.

    Reported-by: Ingo Molnar
    Signed-off-by: Paul E. McKenney
    Cc: Peter Zijlstra
    Cc: Thomas Gleixner
    Cc: Linus Torvalds

    Paul E. McKenney
     
  • This commit creates a new kernel/rcu/rcu_segcblist.c file that
    contains non-trivial segcblist functions. Trivial functions
    remain as static inline functions in kernel/rcu/rcu_segcblist.h

    Reported-by: Linus Torvalds
    Signed-off-by: Paul E. McKenney
    Cc: Peter Zijlstra
    Cc: Thomas Gleixner

    Paul E. McKenney
     
  • Linus noticed that the has huge inline functions
    which should not be inline at all.

    As a first step in cleaning this up, move them all to kernel/rcu/ and
    only keep an absolute minimum of data type defines in the header:

    before: -rw-r--r-- 1 mingo mingo 22284 May 2 10:25 include/linux/rcu_segcblist.h
    after: -rw-r--r-- 1 mingo mingo 3180 May 2 10:22 include/linux/rcu_segcblist.h

    More can be done, such as uninlining the large functions, which inlining
    is unjustified even if it's an RCU internal matter.

    Reported-by: Linus Torvalds
    Cc: Paul E. McKenney
    Cc: Peter Zijlstra
    Cc: Thomas Gleixner
    Signed-off-by: Ingo Molnar
    Signed-off-by: Paul E. McKenney

    Ingo Molnar