cregit-Linux how code gets into the kernel

Release 4.15 kernel/rcu/rcutorture.c

Directory: kernel/rcu
/*
 * Read-Copy Update module-based torture test facility
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, you can access it online at
 * http://www.gnu.org/licenses/gpl-2.0.html.
 *
 * Copyright (C) IBM Corporation, 2005, 2006
 *
 * Authors: Paul E. McKenney <paulmck@us.ibm.com>
 *        Josh Triplett <josh@joshtriplett.org>
 *
 * See also:  Documentation/RCU/torture.txt
 */
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kthread.h>
#include <linux/err.h>
#include <linux/spinlock.h>
#include <linux/smp.h>
#include <linux/rcupdate.h>
#include <linux/interrupt.h>
#include <linux/sched/signal.h>
#include <uapi/linux/sched/types.h>
#include <linux/atomic.h>
#include <linux/bitops.h>
#include <linux/completion.h>
#include <linux/moduleparam.h>
#include <linux/percpu.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/freezer.h>
#include <linux/cpu.h>
#include <linux/delay.h>
#include <linux/stat.h>
#include <linux/srcu.h>
#include <linux/slab.h>
#include <linux/trace_clock.h>
#include <asm/byteorder.h>
#include <linux/torture.h>
#include <linux/vmalloc.h>
#include <linux/sched/debug.h>

#include "rcu.h"

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Paul E. McKenney <paulmck@us.ibm.com> and Josh Triplett <josh@joshtriplett.org>");


torture_param(int, cbflood_inter_holdoff, HZ,
	      "Holdoff between floods (jiffies)");
torture_param(int, cbflood_intra_holdoff, 1,
	      "Holdoff between bursts (jiffies)");
torture_param(int, cbflood_n_burst, 3, "# bursts in flood, zero to disable");
torture_param(int, cbflood_n_per_burst, 20000,
	      "# callbacks per burst in flood");
torture_param(int, fqs_duration, 0,
	      "Duration of fqs bursts (us), 0 to disable");
torture_param(int, fqs_holdoff, 0, "Holdoff time within fqs bursts (us)");
torture_param(int, fqs_stutter, 3, "Wait time between fqs bursts (s)");
torture_param(bool, gp_cond, false, "Use conditional/async GP wait primitives");
torture_param(bool, gp_exp, false, "Use expedited GP wait primitives");
torture_param(bool, gp_normal, false,
	     "Use normal (non-expedited) GP wait primitives");
torture_param(bool, gp_sync, false, "Use synchronous GP wait primitives");
torture_param(int, irqreader, 1, "Allow RCU readers from irq handlers");
torture_param(int, n_barrier_cbs, 0,
	     "# of callbacks/kthreads for barrier testing");
torture_param(int, nfakewriters, 4, "Number of RCU fake writer threads");
torture_param(int, nreaders, -1, "Number of RCU reader threads");
torture_param(int, object_debug, 0,
	     "Enable debug-object double call_rcu() testing");
torture_param(int, onoff_holdoff, 0, "Time after boot before CPU hotplugs (s)");
torture_param(int, onoff_interval, 0,
	     "Time between CPU hotplugs (s), 0=disable");
torture_param(int, shuffle_interval, 3, "Number of seconds between shuffles");
torture_param(int, shutdown_secs, 0, "Shutdown time (s), <= zero to disable.");
torture_param(int, stall_cpu, 0, "Stall duration (s), zero to disable.");
torture_param(int, stall_cpu_holdoff, 10,
	     "Time to wait before starting stall (s).");
torture_param(int, stall_cpu_irqsoff, 0, "Disable interrupts while stalling.");
torture_param(int, stat_interval, 60,
	     "Number of seconds between stats printk()s");
torture_param(int, stutter, 5, "Number of seconds to run/halt test");
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(bool, test_no_idle_hz, true,
	     "Test support for tickless idle CPUs");
torture_param(bool, verbose, true,
	     "Enable verbose debugging printk()s");


static char *torture_type = "rcu";
module_param(torture_type, charp, 0444);
MODULE_PARM_DESC(torture_type, "Type of RCU to torture (rcu, rcu_bh, ...)");


static int nrealreaders;

static int ncbflooders;

static struct task_struct *writer_task;

static struct task_struct **fakewriter_tasks;

static struct task_struct **reader_tasks;

static struct task_struct *stats_task;

static struct task_struct **cbflood_task;

static struct task_struct *fqs_task;

static struct task_struct *boost_tasks[NR_CPUS];

static struct task_struct *stall_task;

static struct task_struct **barrier_cbs_tasks;

static struct task_struct *barrier_task;


#define RCU_TORTURE_PIPE_LEN 10


struct rcu_torture {
	
struct rcu_head rtort_rcu;
	
int rtort_pipe_count;
	
struct list_head rtort_free;
	
int rtort_mbtest;
};

static LIST_HEAD(rcu_torture_freelist);

static struct rcu_torture __rcu *rcu_torture_current;

static unsigned long rcu_torture_current_version;

static struct rcu_torture rcu_tortures[10 * RCU_TORTURE_PIPE_LEN];
static DEFINE_SPINLOCK(rcu_torture_lock);
static DEFINE_PER_CPU(long [RCU_TORTURE_PIPE_LEN + 1], rcu_torture_count);
static DEFINE_PER_CPU(long [RCU_TORTURE_PIPE_LEN + 1], rcu_torture_batch);

static atomic_t rcu_torture_wcount[RCU_TORTURE_PIPE_LEN + 1];

static atomic_t n_rcu_torture_alloc;

static atomic_t n_rcu_torture_alloc_fail;

static atomic_t n_rcu_torture_free;

static atomic_t n_rcu_torture_mberror;

static atomic_t n_rcu_torture_error;

static long n_rcu_torture_barrier_error;

static long n_rcu_torture_boost_ktrerror;

static long n_rcu_torture_boost_rterror;

static long n_rcu_torture_boost_failure;

static long n_rcu_torture_boosts;

static long n_rcu_torture_timers;

static long n_barrier_attempts;

static long n_barrier_successes;

static atomic_long_t n_cbfloods;

static struct list_head rcu_torture_removed;


static int rcu_torture_writer_state;

#define RTWS_FIXED_DELAY	0

#define RTWS_DELAY		1

#define RTWS_REPLACE		2

#define RTWS_DEF_FREE		3

#define RTWS_EXP_SYNC		4

#define RTWS_COND_GET		5

#define RTWS_COND_SYNC		6

#define RTWS_SYNC		7

#define RTWS_STUTTER		8

#define RTWS_STOPPING		9

static const char * const rcu_torture_writer_state_names[] = {
	"RTWS_FIXED_DELAY",
	"RTWS_DELAY",
	"RTWS_REPLACE",
	"RTWS_DEF_FREE",
	"RTWS_EXP_SYNC",
	"RTWS_COND_GET",
	"RTWS_COND_SYNC",
	"RTWS_SYNC",
	"RTWS_STUTTER",
	"RTWS_STOPPING",
};


static const char *rcu_torture_writer_state_getname(void) { unsigned int i = READ_ONCE(rcu_torture_writer_state); if (i >= ARRAY_SIZE(rcu_torture_writer_state_names)) return "???"; return rcu_torture_writer_state_names[i]; }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney37100.00%1100.00%
Total37100.00%1100.00%

static int torture_runnable = IS_ENABLED(MODULE); module_param(torture_runnable, int, 0444); MODULE_PARM_DESC(torture_runnable, "Start rcutorture at boot"); #if defined(CONFIG_RCU_BOOST) && !defined(CONFIG_HOTPLUG_CPU) #define rcu_can_boost() 1 #else /* #if defined(CONFIG_RCU_BOOST) && !defined(CONFIG_HOTPLUG_CPU) */ #define rcu_can_boost() 0 #endif /* #else #if defined(CONFIG_RCU_BOOST) && !defined(CONFIG_HOTPLUG_CPU) */ #ifdef CONFIG_RCU_TRACE
static u64 notrace rcu_trace_clock_local(void) { u64 ts = trace_clock_local(); (void)do_div(ts, NSEC_PER_USEC); return ts; }

Contributors

PersonTokensPropCommitsCommitProp
Steven Rostedt2175.00%133.33%
Paul E. McKenney725.00%266.67%
Total28100.00%3100.00%

#else /* #ifdef CONFIG_RCU_TRACE */
static u64 notrace rcu_trace_clock_local(void) { return 0ULL; }

Contributors

PersonTokensPropCommitsCommitProp
Steven Rostedt1191.67%150.00%
Paul E. McKenney18.33%150.00%
Total12100.00%2100.00%

#endif /* #else #ifdef CONFIG_RCU_TRACE */ static unsigned long boost_starttime; /* jiffies of next boost test start. */ static DEFINE_MUTEX(boost_mutex); /* protect setting boost_starttime */ /* and boost task create/destroy. */ static atomic_t barrier_cbs_count; /* Barrier callbacks registered. */ static bool barrier_phase; /* Test phase. */ static atomic_t barrier_cbs_invoked; /* Barrier callbacks invoked. */ static wait_queue_head_t *barrier_cbs_wq; /* Coordinate barrier testing. */ static DECLARE_WAIT_QUEUE_HEAD(barrier_wq); /* * Allocate an element from the rcu_tortures pool. */
static struct rcu_torture * rcu_torture_alloc(void) { struct list_head *p; spin_lock_bh(&rcu_torture_lock); if (list_empty(&rcu_torture_freelist)) { atomic_inc(&n_rcu_torture_alloc_fail); spin_unlock_bh(&rcu_torture_lock); return NULL; } atomic_inc(&n_rcu_torture_alloc); p = rcu_torture_freelist.next; list_del_init(p); spin_unlock_bh(&rcu_torture_lock); return container_of(p, struct rcu_torture, rtort_free); }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney7492.50%571.43%
Ingo Molnar33.75%114.29%
Josh Triplett33.75%114.29%
Total80100.00%7100.00%

/* * Free an element to the rcu_tortures pool. */
static void rcu_torture_free(struct rcu_torture *p) { atomic_inc(&n_rcu_torture_free); spin_lock_bh(&rcu_torture_lock); list_add_tail(&p->rtort_free, &rcu_torture_freelist); spin_unlock_bh(&rcu_torture_lock); }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney3075.00%133.33%
Steven Rostedt820.00%133.33%
Ingo Molnar25.00%133.33%
Total40100.00%3100.00%

/* * Operations vector for selecting different types of tests. */ struct rcu_torture_ops { int ttype; void (*init)(void); void (*cleanup)(void); int (*readlock)(void); void (*read_delay)(struct torture_random_state *rrsp); void (*readunlock)(int idx); unsigned long (*started)(void); unsigned long (*completed)(void); void (*deferred_free)(struct rcu_torture *p); void (*sync)(void); void (*exp_sync)(void); unsigned long (*get_state)(void); void (*cond_sync)(unsigned long oldstate); call_rcu_func_t call; void (*cb_barrier)(void); void (*fqs)(void); void (*stats)(void); int irq_capable; int can_boost; const char *name; }; static struct rcu_torture_ops *cur_ops; /* * Definitions for rcu torture testing. */
static int rcu_torture_read_lock(void) __acquires(RCU) { rcu_read_lock(); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney1583.33%266.67%
Josh Triplett316.67%133.33%
Total18100.00%3100.00%


static void rcu_read_delay(struct torture_random_state *rrsp) { unsigned long started; unsigned long completed; const unsigned long shortdelay_us = 200; const unsigned long longdelay_ms = 50; unsigned long long ts; /* We want a short delay sometimes to make a reader delay the grace * period, and we want a long delay occasionally to trigger * force_quiescent_state. */ if (!(torture_random(rrsp) % (nrealreaders * 2000 * longdelay_ms))) { started = cur_ops->completed(); ts = rcu_trace_clock_local(); mdelay(longdelay_ms); completed = cur_ops->completed(); do_trace_rcu_torture_read(cur_ops->name, NULL, ts, started, completed); } if (!(torture_random(rrsp) % (nrealreaders * 2 * shortdelay_us))) udelay(shortdelay_us); #ifdef CONFIG_PREEMPT if (!preempt_count() && !(torture_random(rrsp) % (nrealreaders * 20000))) preempt_schedule(); /* No QS if preempt_disable() in effect */ #endif }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney9261.33%466.67%
Josh Triplett3020.00%116.67%
Lai Jiangshan2818.67%116.67%
Total150100.00%6100.00%


static void rcu_torture_read_unlock(int idx) __releases(RCU) { rcu_read_unlock(); }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney1275.00%150.00%
Josh Triplett425.00%150.00%
Total16100.00%2100.00%

/* * Update callback in the pipe. This should be invoked after a grace period. */
static bool rcu_torture_pipe_update_one(struct rcu_torture *rp) { int i; i = rp->rtort_pipe_count; if (i > RCU_TORTURE_PIPE_LEN) i = RCU_TORTURE_PIPE_LEN; atomic_inc(&rcu_torture_wcount[i]); if (++rp->rtort_pipe_count >= RCU_TORTURE_PIPE_LEN) { rp->rtort_mbtest = 0; return true; } return false; }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney62100.00%3100.00%
Total62100.00%3100.00%

/* * Update all callbacks in the pipe. Suitable for synchronous grace-period * primitives. */
static void rcu_torture_pipe_update(struct rcu_torture *old_rp) { struct rcu_torture *rp; struct rcu_torture *rp1; if (old_rp) list_add(&old_rp->rtort_free, &rcu_torture_removed); list_for_each_entry_safe(rp, rp1, &rcu_torture_removed, rtort_free) { if (rcu_torture_pipe_update_one(rp)) { list_del(&rp->rtort_free); rcu_torture_free(rp); } } }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney70100.00%3100.00%
Total70100.00%3100.00%


static void rcu_torture_cb(struct rcu_head *p) { struct rcu_torture *rp = container_of(p, struct rcu_torture, rtort_rcu); if (torture_must_stop_irq()) { /* Test is ending, just drop callbacks on the floor. */ /* The next initialization will pick up the pieces. */ return; } if (rcu_torture_pipe_update_one(rp)) rcu_torture_free(rp); else cur_ops->deferred_free(rp); }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney56100.00%5100.00%
Total56100.00%5100.00%


static unsigned long rcu_no_completed(void) { return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney12100.00%3100.00%
Total12100.00%3100.00%


static void rcu_torture_deferred_free(struct rcu_torture *p) { call_rcu(&p->rtort_rcu, rcu_torture_cb); }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney21100.00%2100.00%
Total21100.00%2100.00%


static void rcu_sync_torture_init(void) { INIT_LIST_HEAD(&rcu_torture_removed); }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney14100.00%2100.00%
Total14100.00%2100.00%

static struct rcu_torture_ops rcu_ops = { .ttype = RCU_FLAVOR, .init = rcu_sync_torture_init, .readlock = rcu_torture_read_lock, .read_delay = rcu_read_delay, .readunlock = rcu_torture_read_unlock, .started = rcu_batches_started, .completed = rcu_batches_completed, .deferred_free = rcu_torture_deferred_free, .sync = synchronize_rcu, .exp_sync = synchronize_rcu_expedited, .get_state = get_state_synchronize_rcu, .cond_sync = cond_synchronize_rcu, .call = call_rcu, .cb_barrier = rcu_barrier, .fqs = rcu_force_quiescent_state, .stats = NULL, .irq_capable = 1, .can_boost = rcu_can_boost(), .name = "rcu" }; /* * Definitions for rcu_bh torture testing. */
static int rcu_bh_torture_read_lock(void) __acquires(RCU_BH) { rcu_read_lock_bh(); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney1372.22%266.67%
Josh Triplett527.78%133.33%
Total18100.00%3100.00%


static void rcu_bh_torture_read_unlock(int idx) __releases(RCU_BH) { rcu_read_unlock_bh(); }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney16100.00%3100.00%
Total16100.00%3100.00%


static void rcu_bh_torture_deferred_free(struct rcu_torture *p) { call_rcu_bh(&p->rtort_rcu, rcu_torture_cb); }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney2095.24%375.00%
Josh Triplett14.76%125.00%
Total21100.00%4100.00%

static struct rcu_torture_ops rcu_bh_ops = { .ttype = RCU_BH_FLAVOR, .init = rcu_sync_torture_init, .readlock = rcu_bh_torture_read_lock, .read_delay = rcu_read_delay, /* just reuse rcu's version. */ .readunlock = rcu_bh_torture_read_unlock, .started = rcu_batches_started_bh, .completed = rcu_batches_completed_bh, .deferred_free = rcu_bh_torture_deferred_free, .sync = synchronize_rcu_bh, .exp_sync = synchronize_rcu_bh_expedited, .call = call_rcu_bh, .cb_barrier = rcu_barrier_bh, .fqs = rcu_bh_force_quiescent_state, .stats = NULL, .irq_capable = 1, .name = "rcu_bh" }; /* * Don't even think about trying any of these in real life!!! * The names includes "busted", and they really means it! * The only purpose of these functions is to provide a buggy RCU * implementation to make sure that rcutorture correctly emits * buggy-RCU error messages. */
static void rcu_busted_torture_deferred_free(struct rcu_torture *p) { /* This is a deliberate bug for testing purposes only! */ rcu_torture_cb(&p->rtort_rcu); }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney20100.00%2100.00%
Total20100.00%2100.00%


static void synchronize_rcu_busted(void) { /* This is a deliberate bug for testing purposes only! */ }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney9100.00%2100.00%
Total9100.00%2100.00%


static void call_rcu_busted(struct rcu_head *head, rcu_callback_t func) { /* This is a deliberate bug for testing purposes only! */ func(head); }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney1995.00%375.00%
Boqun Feng15.00%125.00%
Total20100.00%4100.00%

static struct rcu_torture_ops rcu_busted_ops = { .ttype = INVALID_RCU_FLAVOR, .init = rcu_sync_torture_init, .readlock = rcu_torture_read_lock, .read_delay = rcu_read_delay, /* just reuse rcu's version. */ .readunlock = rcu_torture_read_unlock, .started = rcu_no_completed, .completed = rcu_no_completed, .deferred_free = rcu_busted_torture_deferred_free, .sync = synchronize_rcu_busted, .exp_sync = synchronize_rcu_busted, .call = call_rcu_busted, .cb_barrier = NULL, .fqs = NULL, .stats = NULL, .irq_capable = 1, .name = "busted" }; /* * Definitions for srcu torture testing. */ DEFINE_STATIC_SRCU(srcu_ctl); static struct srcu_struct srcu_ctld; static struct srcu_struct *srcu_ctlp = &srcu_ctl;
static int srcu_torture_read_lock(void) __acquires(srcu_ctlp) { return srcu_read_lock(srcu_ctlp); }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney1688.89%480.00%
Josh Triplett211.11%120.00%
Total18100.00%5100.00%


static void srcu_read_delay(struct torture_random_state *rrsp) { long delay; const long uspertick = 1000000 / HZ; const long longdelay = 10; /* We want there to be long-running readers, but not all the time. */ delay = torture_random(rrsp) % (nrealreaders * 2 * longdelay * uspertick); if (!delay && in_task()) schedule_timeout_interruptible(longdelay); else rcu_read_delay(rrsp); }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney5889.23%466.67%
Lai Jiangshan46.15%116.67%
Josh Triplett34.62%116.67%
Total65100.00%6100.00%


static void srcu_torture_read_unlock(int idx) __releases(srcu_ctlp) { srcu_read_unlock(srcu_ctlp, idx); }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney1890.00%375.00%
Josh Triplett210.00%125.00%
Total20100.00%4100.00%


static unsigned long srcu_torture_completed(void) { return srcu_batches_completed(srcu_ctlp); }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney15100.00%4100.00%
Total15100.00%4100.00%


static void srcu_torture_deferred_free(struct rcu_torture *rp) { call_srcu(srcu_ctlp, &rp->rtort_rcu, rcu_torture_cb); }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney23100.00%4100.00%
Total23100.00%4100.00%


static void srcu_torture_synchronize(void) { synchronize_srcu(srcu_ctlp); }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney1292.31%480.00%
Josh Triplett17.69%120.00%
Total13100.00%5100.00%


static void srcu_torture_call(struct rcu_head *head, rcu_callback_t func) { call_srcu(srcu_ctlp, head, func); }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney2295.65%583.33%
Boqun Feng14.35%116.67%
Total23100.00%6100.00%


static void srcu_torture_barrier(void) { srcu_barrier(srcu_ctlp); }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney1292.31%375.00%
Josh Triplett17.69%125.00%
Total13100.00%4100.00%


static void srcu_torture_stats(void) { srcu_torture_stats_print(srcu_ctlp, torture_type, TORTURE_FLAG); }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney1694.12%583.33%
Joe Perches15.88%116.67%
Total17100.00%6100.00%


static void srcu_torture_synchronize_expedited(void) { synchronize_srcu_expedited(srcu_ctlp); }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney13100.00%2100.00%
Total13100.00%2100.00%

static struct rcu_torture_ops srcu_ops = { .ttype = SRCU_FLAVOR, .init = rcu_sync_torture_init, .readlock = srcu_torture_read_lock, .read_delay = srcu_read_delay, .readunlock = srcu_torture_read_unlock, .started = NULL, .completed = srcu_torture_completed, .deferred_free = srcu_torture_deferred_free, .sync = srcu_torture_synchronize, .exp_sync = srcu_torture_synchronize_expedited, .call = srcu_torture_call, .cb_barrier = srcu_torture_barrier, .stats = srcu_torture_stats, .irq_capable = 1, .name = "srcu" };
static void srcu_torture_init(void) { rcu_sync_torture_init(); WARN_ON(init_srcu_struct(&srcu_ctld)); srcu_ctlp = &srcu_ctld; }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney25100.00%1100.00%
Total25100.00%1100.00%


static void srcu_torture_cleanup(void) { cleanup_srcu_struct(&srcu_ctld); srcu_ctlp = &srcu_ctl; /* In case of a later rcutorture run. */ }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney20100.00%1100.00%
Total20100.00%1100.00%

/* As above, but dynamically allocated. */ static struct rcu_torture_ops srcud_ops = { .ttype = SRCU_FLAVOR, .init = srcu_torture_init, .cleanup = srcu_torture_cleanup, .readlock = srcu_torture_read_lock, .read_delay = srcu_read_delay, .readunlock = srcu_torture_read_unlock, .started = NULL, .completed = srcu_torture_completed, .deferred_free = srcu_torture_deferred_free, .sync = srcu_torture_synchronize, .exp_sync = srcu_torture_synchronize_expedited, .call = srcu_torture_call, .cb_barrier = srcu_torture_barrier, .stats = srcu_torture_stats, .irq_capable = 1, .name = "srcud" }; /* * Definitions for sched torture testing. */
static int sched_torture_read_lock(void) { preempt_disable(); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Josh Triplett750.00%150.00%
Paul E. McKenney750.00%150.00%
Total14100.00%2100.00%


static void sched_torture_read_unlock(int idx) { preempt_enable(); }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney1191.67%150.00%
Josh Triplett18.33%150.00%
Total12100.00%2100.00%


static void rcu_sched_torture_deferred_free(struct rcu_torture *p) { call_rcu_sched(&p->rtort_rcu, rcu_torture_cb); }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney1152.38%150.00%
Josh Triplett1047.62%150.00%
Total21100.00%2100.00%

static struct rcu_torture_ops sched_ops = { .ttype = RCU_SCHED_FLAVOR, .init = rcu_sync_torture_init, .readlock = sched_torture_read_lock, .read_delay = rcu_read_delay, /* just reuse rcu's version. */ .readunlock = sched_torture_read_unlock, .started = rcu_batches_started_sched, .completed = rcu_batches_completed_sched, .deferred_free = rcu_sched_torture_deferred_free, .sync = synchronize_sched, .exp_sync = synchronize_sched_expedited, .get_state = get_state_synchronize_sched, .cond_sync = cond_synchronize_sched, .call = call_rcu_sched, .cb_barrier = rcu_barrier_sched, .fqs = rcu_sched_force_quiescent_state, .stats = NULL, .irq_capable = 1, .name = "sched" }; /* * Definitions for RCU-tasks torture testing. */
static int tasks_torture_read_lock(void