root/include/linux/rcu_segcblist.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


   1 /* SPDX-License-Identifier: GPL-2.0+ */
   2 /*
   3  * RCU segmented callback lists
   4  *
   5  * This seemingly RCU-private file must be available to SRCU users
   6  * because the size of the TREE SRCU srcu_struct structure depends
   7  * on these definitions.
   8  *
   9  * Copyright IBM Corporation, 2017
  10  *
  11  * Authors: Paul E. McKenney <paulmck@linux.net.ibm.com>
  12  */
  13 
  14 #ifndef __INCLUDE_LINUX_RCU_SEGCBLIST_H
  15 #define __INCLUDE_LINUX_RCU_SEGCBLIST_H
  16 
  17 #include <linux/types.h>
  18 #include <linux/atomic.h>
  19 
  20 /* Simple unsegmented callback lists. */
  21 struct rcu_cblist {
  22         struct rcu_head *head;
  23         struct rcu_head **tail;
  24         long len;
  25         long len_lazy;
  26 };
  27 
  28 #define RCU_CBLIST_INITIALIZER(n) { .head = NULL, .tail = &n.head }
  29 
  30 /* Complicated segmented callback lists.  ;-) */
  31 
  32 /*
  33  * Index values for segments in rcu_segcblist structure.
  34  *
  35  * The segments are as follows:
  36  *
  37  * [head, *tails[RCU_DONE_TAIL]):
  38  *      Callbacks whose grace period has elapsed, and thus can be invoked.
  39  * [*tails[RCU_DONE_TAIL], *tails[RCU_WAIT_TAIL]):
  40  *      Callbacks waiting for the current GP from the current CPU's viewpoint.
  41  * [*tails[RCU_WAIT_TAIL], *tails[RCU_NEXT_READY_TAIL]):
  42  *      Callbacks that arrived before the next GP started, again from
  43  *      the current CPU's viewpoint.  These can be handled by the next GP.
  44  * [*tails[RCU_NEXT_READY_TAIL], *tails[RCU_NEXT_TAIL]):
  45  *      Callbacks that might have arrived after the next GP started.
  46  *      There is some uncertainty as to when a given GP starts and
  47  *      ends, but a CPU knows the exact times if it is the one starting
  48  *      or ending the GP.  Other CPUs know that the previous GP ends
  49  *      before the next one starts.
  50  *
  51  * Note that RCU_WAIT_TAIL cannot be empty unless RCU_NEXT_READY_TAIL is also
  52  * empty.
  53  *
  54  * The ->gp_seq[] array contains the grace-period number at which the
  55  * corresponding segment of callbacks will be ready to invoke.  A given
  56  * element of this array is meaningful only when the corresponding segment
  57  * is non-empty, and it is never valid for RCU_DONE_TAIL (whose callbacks
  58  * are already ready to invoke) or for RCU_NEXT_TAIL (whose callbacks have
  59  * not yet been assigned a grace-period number).
  60  */
  61 #define RCU_DONE_TAIL           0       /* Also RCU_WAIT head. */
  62 #define RCU_WAIT_TAIL           1       /* Also RCU_NEXT_READY head. */
  63 #define RCU_NEXT_READY_TAIL     2       /* Also RCU_NEXT head. */
  64 #define RCU_NEXT_TAIL           3
  65 #define RCU_CBLIST_NSEGS        4
  66 
  67 struct rcu_segcblist {
  68         struct rcu_head *head;
  69         struct rcu_head **tails[RCU_CBLIST_NSEGS];
  70         unsigned long gp_seq[RCU_CBLIST_NSEGS];
  71 #ifdef CONFIG_RCU_NOCB_CPU
  72         atomic_long_t len;
  73 #else
  74         long len;
  75 #endif
  76         long len_lazy;
  77         u8 enabled;
  78         u8 offloaded;
  79 };
  80 
  81 #define RCU_SEGCBLIST_INITIALIZER(n) \
  82 { \
  83         .head = NULL, \
  84         .tails[RCU_DONE_TAIL] = &n.head, \
  85         .tails[RCU_WAIT_TAIL] = &n.head, \
  86         .tails[RCU_NEXT_READY_TAIL] = &n.head, \
  87         .tails[RCU_NEXT_TAIL] = &n.head, \
  88 }
  89 
  90 #endif /* __INCLUDE_LINUX_RCU_SEGCBLIST_H */

/* [<][>][^][v][top][bottom][index][help] */