linux/include/linux/rcu_segcblist.h
<<
>>
Prefs
   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/* Simple unsegmented callback lists. */
  18struct rcu_cblist {
  19        struct rcu_head *head;
  20        struct rcu_head **tail;
  21        long len;
  22        long len_lazy;
  23};
  24
  25#define RCU_CBLIST_INITIALIZER(n) { .head = NULL, .tail = &n.head }
  26
  27/* Complicated segmented callback lists.  ;-) */
  28
  29/*
  30 * Index values for segments in rcu_segcblist structure.
  31 *
  32 * The segments are as follows:
  33 *
  34 * [head, *tails[RCU_DONE_TAIL]):
  35 *      Callbacks whose grace period has elapsed, and thus can be invoked.
  36 * [*tails[RCU_DONE_TAIL], *tails[RCU_WAIT_TAIL]):
  37 *      Callbacks waiting for the current GP from the current CPU's viewpoint.
  38 * [*tails[RCU_WAIT_TAIL], *tails[RCU_NEXT_READY_TAIL]):
  39 *      Callbacks that arrived before the next GP started, again from
  40 *      the current CPU's viewpoint.  These can be handled by the next GP.
  41 * [*tails[RCU_NEXT_READY_TAIL], *tails[RCU_NEXT_TAIL]):
  42 *      Callbacks that might have arrived after the next GP started.
  43 *      There is some uncertainty as to when a given GP starts and
  44 *      ends, but a CPU knows the exact times if it is the one starting
  45 *      or ending the GP.  Other CPUs know that the previous GP ends
  46 *      before the next one starts.
  47 *
  48 * Note that RCU_WAIT_TAIL cannot be empty unless RCU_NEXT_READY_TAIL is also
  49 * empty.
  50 *
  51 * The ->gp_seq[] array contains the grace-period number at which the
  52 * corresponding segment of callbacks will be ready to invoke.  A given
  53 * element of this array is meaningful only when the corresponding segment
  54 * is non-empty, and it is never valid for RCU_DONE_TAIL (whose callbacks
  55 * are already ready to invoke) or for RCU_NEXT_TAIL (whose callbacks have
  56 * not yet been assigned a grace-period number).
  57 */
  58#define RCU_DONE_TAIL           0       /* Also RCU_WAIT head. */
  59#define RCU_WAIT_TAIL           1       /* Also RCU_NEXT_READY head. */
  60#define RCU_NEXT_READY_TAIL     2       /* Also RCU_NEXT head. */
  61#define RCU_NEXT_TAIL           3
  62#define RCU_CBLIST_NSEGS        4
  63
  64struct rcu_segcblist {
  65        struct rcu_head *head;
  66        struct rcu_head **tails[RCU_CBLIST_NSEGS];
  67        unsigned long gp_seq[RCU_CBLIST_NSEGS];
  68        long len;
  69        long len_lazy;
  70};
  71
  72#define RCU_SEGCBLIST_INITIALIZER(n) \
  73{ \
  74        .head = NULL, \
  75        .tails[RCU_DONE_TAIL] = &n.head, \
  76        .tails[RCU_WAIT_TAIL] = &n.head, \
  77        .tails[RCU_NEXT_READY_TAIL] = &n.head, \
  78        .tails[RCU_NEXT_TAIL] = &n.head, \
  79}
  80
  81#endif /* __INCLUDE_LINUX_RCU_SEGCBLIST_H */
  82