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