unsigned long reschedule_jiffies;
unsigned long reschedule_count;
struct delayed_work work;
+++ ++ struct srcu_struct *srcu_ssp;
+++ ++};
+++ ++
+++ ++/*
+++ ++ * Per-SRCU-domain structure, similar in function to rcu_state.
+++ ++ */
+++ ++struct srcu_struct {
+++ ++ unsigned int srcu_idx; /* Current rdr array element. */
+++ ++ struct srcu_data __percpu *sda; /* Per-CPU srcu_data array. */
struct lockdep_map dep_map;
+++ ++ struct srcu_usage *srcu_sup; /* Update-side data. */
};
- ----/* Values for size state variable (->srcu_size_state). */
- ----#define SRCU_SIZE_SMALL 0
- ----#define SRCU_SIZE_ALLOC 1
- ----#define SRCU_SIZE_WAIT_BARRIER 2
- ----#define SRCU_SIZE_WAIT_CALL 3
- ----#define SRCU_SIZE_WAIT_CBS1 4
- ----#define SRCU_SIZE_WAIT_CBS2 5
- ----#define SRCU_SIZE_WAIT_CBS3 6
- ----#define SRCU_SIZE_WAIT_CBS4 7
- ----#define SRCU_SIZE_BIG 8
+ ++++// Values for size state variable (->srcu_size_state). Once the state
+ ++++// has been set to SRCU_SIZE_ALLOC, the grace-period code advances through
+ ++++// this state machine one step per grace period until the SRCU_SIZE_BIG state
+ ++++// is reached. Otherwise, the state machine remains in the SRCU_SIZE_SMALL
+ ++++// state indefinitely.
+ ++++#define SRCU_SIZE_SMALL 0 // No srcu_node combining tree, ->node == NULL
+ ++++#define SRCU_SIZE_ALLOC 1 // An srcu_node tree is being allocated, initialized,
+ ++++ // and then referenced by ->node. It will not be used.
+ ++++#define SRCU_SIZE_WAIT_BARRIER 2 // The srcu_node tree starts being used by everything
+ ++++ // except call_srcu(), especially by srcu_barrier().
+ ++++ // By the end of this state, all CPUs and threads
+ ++++ // are aware of this tree's existence.
+ ++++#define SRCU_SIZE_WAIT_CALL 3 // The srcu_node tree starts being used by call_srcu().
+ ++++ // By the end of this state, all of the call_srcu()
+ ++++ // invocations that were running on a non-boot CPU
+ ++++ // and using the boot CPU's callback queue will have
+ ++++ // completed.
+ ++++#define SRCU_SIZE_WAIT_CBS1 4 // Don't trust the ->srcu_have_cbs[] grace-period
+ ++++#define SRCU_SIZE_WAIT_CBS2 5 // sequence elements or the ->srcu_data_have_cbs[]
+ ++++#define SRCU_SIZE_WAIT_CBS3 6 // CPU-bitmask elements until all four elements of
+ ++++#define SRCU_SIZE_WAIT_CBS4 7 // each array have been initialized.
+ ++++#define SRCU_SIZE_BIG 8 // The srcu_node combining tree is fully initialized
+ ++++ // and all aspects of it are being put to use.
/* Values for state variable (bottom bits of ->srcu_gp_seq). */
#define SRCU_STATE_IDLE 0
torture_param(int, test_boost, 1, "Test RCU prio boost: 0=no, 1=maybe, 2=yes.");
torture_param(int, test_boost_duration, 4, "Duration of each boost test, seconds.");
torture_param(int, test_boost_interval, 7, "Interval between boost tests, seconds.");
+++++ torture_param(int, test_nmis, 0, "End-test NMI tests, 0 to disable.");
torture_param(bool, test_no_idle_hz, true, "Test support for tickless idle CPUs");
++++ +torture_param(int, test_srcu_lockdep, 0, "Test specified SRCU deadlock scenario.");
torture_param(int, verbose, 1, "Enable verbose debugging printk()s");
static char *torture_type = "rcu";
.kname = #rt_name, \
}
+++ ++#ifdef CONFIG_TASKS_RCU
/* Track exiting tasks in order to allow them to be waited for. */
DEFINE_STATIC_SRCU(tasks_rcu_exit_srcu);
+++ ++#endif
++ ++
+++++#ifdef CONFIG_TASKS_RCU
+++++/* Report delay in synchronize_srcu() completion in rcu_tasks_postscan(). */
+++++static void tasks_rcu_exit_srcu_stall(struct timer_list *unused);
+++++static DEFINE_TIMER(tasks_rcu_exit_srcu_stall_timer, tasks_rcu_exit_srcu_stall);
+++++#endif
+
/* Avoid IPIing CPUs early in the grace period. */
#define RCU_TASK_IPI_DELAY (IS_ENABLED(CONFIG_TASKS_TRACE_RCU_READ_MB) ? HZ / 2 : 0)
static int rcu_task_ipi_delay __read_mostly = RCU_TASK_IPI_DELAY;