linux/include/linux/rcu_segcblist.h
<<
>>
Prefs
   1/*
   2 * RCU segmented callback lists
   3 *
   4 * This seemingly RCU-private file must be available to SRCU users
   5 * because the size of the TREE SRCU srcu_struct structure depends
   6 * on these definitions.
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation; either version 2 of the License, or
  11 * (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, you can access it online at
  20 * http://www.gnu.org/licenses/gpl-2.0.html.
  21 *
  22 * Copyright IBM Corporation, 2017
  23 *
  24 * Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
  25 */
  26
  27#ifndef __INCLUDE_LINUX_RCU_SEGCBLIST_H
  28#define __INCLUDE_LINUX_RCU_SEGCBLIST_H
  29
  30/* Simple unsegmented callback lists. */
  31struct rcu_cblist {
  32        struct rcu_head *head;
  33        struct rcu_head **tail;
  34        long len;
  35        long len_lazy;
  36};
  37
  38#define RCU_CBLIST_INITIALIZER(n) { .head = NULL, .tail = &n.head }
  39
  40/* Complicated segmented callback lists.  ;-) */
  41
  42/*
  43 * Index values for segments in rcu_segcblist structure.
  44 *
  45 * The segments are as follows:
  46 *
  47 * [head, *tails[RCU_DONE_TAIL]):
  48 *      Callbacks whose grace period has elapsed, and thus can be invoked.
  49 * [*tails[RCU_DONE_TAIL], *tails[RCU_WAIT_TAIL]):
  50 *      Callbacks waiting for the current GP from the current CPU's viewpoint.
  51 * [*tails[RCU_WAIT_TAIL], *tails[RCU_NEXT_READY_TAIL]):
  52 *      Callbacks that arrived before the next GP started, again from
  53 *      the current CPU's viewpoint.  These can be handled by the next GP.
  54 * [*tails[RCU_NEXT_READY_TAIL], *tails[RCU_NEXT_TAIL]):
  55 *      Callbacks that might have arrived after the next GP started.
  56 *      There is some uncertainty as to when a given GP starts and
  57 *      ends, but a CPU knows the exact times if it is the one starting
  58 *      or ending the GP.  Other CPUs know that the previous GP ends
  59 *      before the next one starts.
  60 *
  61 * Note that RCU_WAIT_TAIL cannot be empty unless RCU_NEXT_READY_TAIL is also
  62 * empty.
  63 *
  64 * The ->gp_seq[] array contains the grace-period number at which the
  65 * corresponding segment of callbacks will be ready to invoke.  A given
  66 * element of this array is meaningful only when the corresponding segment
  67 * is non-empty, and it is never valid for RCU_DONE_TAIL (whose callbacks
  68 * are already ready to invoke) or for RCU_NEXT_TAIL (whose callbacks have
  69 * not yet been assigned a grace-period number).
  70 */
  71#define RCU_DONE_TAIL           0       /* Also RCU_WAIT head. */
  72#define RCU_WAIT_TAIL           1       /* Also RCU_NEXT_READY head. */
  73#define RCU_NEXT_READY_TAIL     2       /* Also RCU_NEXT head. */
  74#define RCU_NEXT_TAIL           3
  75#define RCU_CBLIST_NSEGS        4
  76
  77struct rcu_segcblist {
  78        struct rcu_head *head;
  79        struct rcu_head **tails[RCU_CBLIST_NSEGS];
  80        unsigned long gp_seq[RCU_CBLIST_NSEGS];
  81        long len;
  82        long len_lazy;
  83};
  84
  85#define RCU_SEGCBLIST_INITIALIZER(n) \
  86{ \
  87        .head = NULL, \
  88        .tails[RCU_DONE_TAIL] = &n.head, \
  89        .tails[RCU_WAIT_TAIL] = &n.head, \
  90        .tails[RCU_NEXT_READY_TAIL] = &n.head, \
  91        .tails[RCU_NEXT_TAIL] = &n.head, \
  92}
  93
  94#endif /* __INCLUDE_LINUX_RCU_SEGCBLIST_H */
  95