linux/include/linux/rcu_sync.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0+ */
   2/*
   3 * RCU-based infrastructure for lightweight reader-writer locking
   4 *
   5 * Copyright (c) 2015, Red Hat, Inc.
   6 *
   7 * Author: Oleg Nesterov <oleg@redhat.com>
   8 */
   9
  10#ifndef _LINUX_RCU_SYNC_H_
  11#define _LINUX_RCU_SYNC_H_
  12
  13#include <linux/wait.h>
  14#include <linux/rcupdate.h>
  15
  16enum rcu_sync_type { RCU_SYNC, RCU_SCHED_SYNC, RCU_BH_SYNC };
  17
  18/* Structure to mediate between updaters and fastpath-using readers.  */
  19struct rcu_sync {
  20        int                     gp_state;
  21        int                     gp_count;
  22        wait_queue_head_t       gp_wait;
  23
  24        int                     cb_state;
  25        struct rcu_head         cb_head;
  26
  27        enum rcu_sync_type      gp_type;
  28};
  29
  30extern void rcu_sync_lockdep_assert(struct rcu_sync *);
  31
  32/**
  33 * rcu_sync_is_idle() - Are readers permitted to use their fastpaths?
  34 * @rsp: Pointer to rcu_sync structure to use for synchronization
  35 *
  36 * Returns true if readers are permitted to use their fastpaths.
  37 * Must be invoked within an RCU read-side critical section whose
  38 * flavor matches that of the rcu_sync struture.
  39 */
  40static inline bool rcu_sync_is_idle(struct rcu_sync *rsp)
  41{
  42#ifdef CONFIG_PROVE_RCU
  43        rcu_sync_lockdep_assert(rsp);
  44#endif
  45        return !rsp->gp_state; /* GP_IDLE */
  46}
  47
  48extern void rcu_sync_init(struct rcu_sync *, enum rcu_sync_type);
  49extern void rcu_sync_enter_start(struct rcu_sync *);
  50extern void rcu_sync_enter(struct rcu_sync *);
  51extern void rcu_sync_exit(struct rcu_sync *);
  52extern void rcu_sync_dtor(struct rcu_sync *);
  53
  54#define __RCU_SYNC_INITIALIZER(name, type) {                            \
  55                .gp_state = 0,                                          \
  56                .gp_count = 0,                                          \
  57                .gp_wait = __WAIT_QUEUE_HEAD_INITIALIZER(name.gp_wait), \
  58                .cb_state = 0,                                          \
  59                .gp_type = type,                                        \
  60        }
  61
  62#define __DEFINE_RCU_SYNC(name, type)   \
  63        struct rcu_sync_struct name = __RCU_SYNC_INITIALIZER(name, type)
  64
  65#define DEFINE_RCU_SYNC(name)           \
  66        __DEFINE_RCU_SYNC(name, RCU_SYNC)
  67
  68#define DEFINE_RCU_SCHED_SYNC(name)     \
  69        __DEFINE_RCU_SYNC(name, RCU_SCHED_SYNC)
  70
  71#define DEFINE_RCU_BH_SYNC(name)        \
  72        __DEFINE_RCU_SYNC(name, RCU_BH_SYNC)
  73
  74#endif /* _LINUX_RCU_SYNC_H_ */
  75