Commit f5d2a045 authored by Paul E. McKenney's avatar Paul E. McKenney

Merge branches 'doc.2014.04.29a', 'fixes.2014.04.29a' and 'torture.2014.05.14a' into HEAD

doc.2014.04.29a:  Documentation updates.
fixes.2014.04.29a:  Miscellaneous fixes.
torture.2014.05.14a:  RCU/Lock torture tests.
...@@ -639,7 +639,7 @@ do { \ ...@@ -639,7 +639,7 @@ do { \
# define raw_cpu_add_return_8(pcp, val) raw_cpu_generic_add_return(pcp, val) # define raw_cpu_add_return_8(pcp, val) raw_cpu_generic_add_return(pcp, val)
# endif # endif
# define raw_cpu_add_return(pcp, val) \ # define raw_cpu_add_return(pcp, val) \
__pcpu_size_call_return2(raw_add_return_, pcp, val) __pcpu_size_call_return2(raw_cpu_add_return_, pcp, val)
#endif #endif
#define raw_cpu_sub_return(pcp, val) raw_cpu_add_return(pcp, -(typeof(pcp))(val)) #define raw_cpu_sub_return(pcp, val) raw_cpu_add_return(pcp, -(typeof(pcp))(val))
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include <linux/debugobjects.h> #include <linux/debugobjects.h>
#include <linux/bug.h> #include <linux/bug.h>
#include <linux/compiler.h> #include <linux/compiler.h>
#include <linux/percpu.h>
#include <asm/barrier.h> #include <asm/barrier.h>
extern int rcu_expedited; /* for sysctl */ extern int rcu_expedited; /* for sysctl */
...@@ -51,7 +52,17 @@ extern int rcu_expedited; /* for sysctl */ ...@@ -51,7 +52,17 @@ extern int rcu_expedited; /* for sysctl */
extern int rcutorture_runnable; /* for sysctl */ extern int rcutorture_runnable; /* for sysctl */
#endif /* #ifdef CONFIG_RCU_TORTURE_TEST */ #endif /* #ifdef CONFIG_RCU_TORTURE_TEST */
enum rcutorture_type {
RCU_FLAVOR,
RCU_BH_FLAVOR,
RCU_SCHED_FLAVOR,
SRCU_FLAVOR,
INVALID_RCU_FLAVOR
};
#if defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU) #if defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU)
void rcutorture_get_gp_data(enum rcutorture_type test_type, int *flags,
unsigned long *gpnum, unsigned long *completed);
void rcutorture_record_test_transition(void); void rcutorture_record_test_transition(void);
void rcutorture_record_progress(unsigned long vernum); void rcutorture_record_progress(unsigned long vernum);
void do_trace_rcu_torture_read(const char *rcutorturename, void do_trace_rcu_torture_read(const char *rcutorturename,
...@@ -60,6 +71,15 @@ void do_trace_rcu_torture_read(const char *rcutorturename, ...@@ -60,6 +71,15 @@ void do_trace_rcu_torture_read(const char *rcutorturename,
unsigned long c_old, unsigned long c_old,
unsigned long c); unsigned long c);
#else #else
static inline void rcutorture_get_gp_data(enum rcutorture_type test_type,
int *flags,
unsigned long *gpnum,
unsigned long *completed)
{
*flags = 0;
*gpnum = 0;
*completed = 0;
}
static inline void rcutorture_record_test_transition(void) static inline void rcutorture_record_test_transition(void)
{ {
} }
...@@ -267,6 +287,41 @@ static inline void rcu_user_hooks_switch(struct task_struct *prev, ...@@ -267,6 +287,41 @@ static inline void rcu_user_hooks_switch(struct task_struct *prev,
bool __rcu_is_watching(void); bool __rcu_is_watching(void);
#endif /* #if defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_RCU_TRACE) || defined(CONFIG_SMP) */ #endif /* #if defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_RCU_TRACE) || defined(CONFIG_SMP) */
/*
* Hooks for cond_resched() and friends to avoid RCU CPU stall warnings.
*/
#define RCU_COND_RESCHED_LIM 256 /* ms vs. 100s of ms. */
DECLARE_PER_CPU(int, rcu_cond_resched_count);
void rcu_resched(void);
/*
* Is it time to report RCU quiescent states?
*
* Note unsynchronized access to rcu_cond_resched_count. Yes, we might
* increment some random CPU's count, and possibly also load the result from
* yet another CPU's count. We might even clobber some other CPU's attempt
* to zero its counter. This is all OK because the goal is not precision,
* but rather reasonable amortization of rcu_note_context_switch() overhead
* and extremely high probability of avoiding RCU CPU stall warnings.
* Note that this function has to be preempted in just the wrong place,
* many thousands of times in a row, for anything bad to happen.
*/
static inline bool rcu_should_resched(void)
{
return raw_cpu_inc_return(rcu_cond_resched_count) >=
RCU_COND_RESCHED_LIM;
}
/*
* Report quiscent states to RCU if it is time to do so.
*/
static inline void rcu_cond_resched(void)
{
if (unlikely(rcu_should_resched()))
rcu_resched();
}
/* /*
* Infrastructure to implement the synchronize_() primitives in * Infrastructure to implement the synchronize_() primitives in
* TREE_RCU and rcu_barrier_() primitives in TINY_RCU. * TREE_RCU and rcu_barrier_() primitives in TINY_RCU.
...@@ -328,7 +383,7 @@ extern struct lockdep_map rcu_lock_map; ...@@ -328,7 +383,7 @@ extern struct lockdep_map rcu_lock_map;
extern struct lockdep_map rcu_bh_lock_map; extern struct lockdep_map rcu_bh_lock_map;
extern struct lockdep_map rcu_sched_lock_map; extern struct lockdep_map rcu_sched_lock_map;
extern struct lockdep_map rcu_callback_map; extern struct lockdep_map rcu_callback_map;
extern int debug_lockdep_rcu_enabled(void); int debug_lockdep_rcu_enabled(void);
/** /**
* rcu_read_lock_held() - might we be in RCU read-side critical section? * rcu_read_lock_held() - might we be in RCU read-side critical section?
...@@ -949,6 +1004,9 @@ static inline notrace void rcu_read_unlock_sched_notrace(void) ...@@ -949,6 +1004,9 @@ static inline notrace void rcu_read_unlock_sched_notrace(void)
* pointers, but you must use rcu_assign_pointer() to initialize the * pointers, but you must use rcu_assign_pointer() to initialize the
* external-to-structure pointer -after- you have completely initialized * external-to-structure pointer -after- you have completely initialized
* the reader-accessible portions of the linked structure. * the reader-accessible portions of the linked structure.
*
* Note that unlike rcu_assign_pointer(), RCU_INIT_POINTER() provides no
* ordering guarantees for either the CPU or the compiler.
*/ */
#define RCU_INIT_POINTER(p, v) \ #define RCU_INIT_POINTER(p, v) \
do { \ do { \
......
...@@ -119,6 +119,10 @@ static inline void rcu_sched_force_quiescent_state(void) ...@@ -119,6 +119,10 @@ static inline void rcu_sched_force_quiescent_state(void)
{ {
} }
static inline void show_rcu_gp_kthreads(void)
{
}
static inline void rcu_cpu_stall_reset(void) static inline void rcu_cpu_stall_reset(void)
{ {
} }
......
...@@ -84,6 +84,7 @@ extern unsigned long rcutorture_vernum; ...@@ -84,6 +84,7 @@ extern unsigned long rcutorture_vernum;
long rcu_batches_completed(void); long rcu_batches_completed(void);
long rcu_batches_completed_bh(void); long rcu_batches_completed_bh(void);
long rcu_batches_completed_sched(void); long rcu_batches_completed_sched(void);
void show_rcu_gp_kthreads(void);
void rcu_force_quiescent_state(void); void rcu_force_quiescent_state(void);
void rcu_bh_force_quiescent_state(void); void rcu_bh_force_quiescent_state(void);
......
...@@ -49,12 +49,6 @@ ...@@ -49,12 +49,6 @@
#define VERBOSE_TOROUT_ERRSTRING(s) \ #define VERBOSE_TOROUT_ERRSTRING(s) \
do { if (verbose) pr_alert("%s" TORTURE_FLAG "!!! %s\n", torture_type, s); } while (0) do { if (verbose) pr_alert("%s" TORTURE_FLAG "!!! %s\n", torture_type, s); } while (0)
/* Definitions for a non-string torture-test module parameter. */
#define torture_parm(type, name, init, msg) \
static type name = init; \
module_param(name, type, 0444); \
MODULE_PARM_DESC(name, msg);
/* Definitions for online/offline exerciser. */ /* Definitions for online/offline exerciser. */
int torture_onoff_init(long ooholdoff, long oointerval); int torture_onoff_init(long ooholdoff, long oointerval);
char *torture_onoff_stats(char *page); char *torture_onoff_stats(char *page);
...@@ -81,7 +75,7 @@ void stutter_wait(const char *title); ...@@ -81,7 +75,7 @@ void stutter_wait(const char *title);
int torture_stutter_init(int s); int torture_stutter_init(int s);
/* Initialization and cleanup. */ /* Initialization and cleanup. */
void torture_init_begin(char *ttype, bool v, int *runnable); bool torture_init_begin(char *ttype, bool v, int *runnable);
void torture_init_end(void); void torture_init_end(void);
bool torture_cleanup(void); bool torture_cleanup(void);
bool torture_must_stop(void); bool torture_must_stop(void);
......
...@@ -82,14 +82,14 @@ struct lock_writer_stress_stats { ...@@ -82,14 +82,14 @@ struct lock_writer_stress_stats {
}; };
static struct lock_writer_stress_stats *lwsa; static struct lock_writer_stress_stats *lwsa;
#if defined(MODULE) || defined(CONFIG_LOCK_TORTURE_TEST_RUNNABLE) #if defined(MODULE)
#define LOCKTORTURE_RUNNABLE_INIT 1 #define LOCKTORTURE_RUNNABLE_INIT 1
#else #else
#define LOCKTORTURE_RUNNABLE_INIT 0 #define LOCKTORTURE_RUNNABLE_INIT 0
#endif #endif
int locktorture_runnable = LOCKTORTURE_RUNNABLE_INIT; int locktorture_runnable = LOCKTORTURE_RUNNABLE_INIT;
module_param(locktorture_runnable, int, 0444); module_param(locktorture_runnable, int, 0444);
MODULE_PARM_DESC(locktorture_runnable, "Start locktorture at boot"); MODULE_PARM_DESC(locktorture_runnable, "Start locktorture at module init");
/* Forward reference. */ /* Forward reference. */
static void lock_torture_cleanup(void); static void lock_torture_cleanup(void);
...@@ -219,7 +219,8 @@ static int lock_torture_writer(void *arg) ...@@ -219,7 +219,8 @@ static int lock_torture_writer(void *arg)
set_user_nice(current, 19); set_user_nice(current, 19);
do { do {
schedule_timeout_uninterruptible(1); if ((torture_random(&rand) & 0xfffff) == 0)
schedule_timeout_uninterruptible(1);
cur_ops->writelock(); cur_ops->writelock();
if (WARN_ON_ONCE(lock_is_write_held)) if (WARN_ON_ONCE(lock_is_write_held))
lwsp->n_write_lock_fail++; lwsp->n_write_lock_fail++;
...@@ -354,7 +355,8 @@ static int __init lock_torture_init(void) ...@@ -354,7 +355,8 @@ static int __init lock_torture_init(void)
&lock_busted_ops, &spin_lock_ops, &spin_lock_irq_ops, &lock_busted_ops, &spin_lock_ops, &spin_lock_irq_ops,
}; };
torture_init_begin(torture_type, verbose, &locktorture_runnable); if (!torture_init_begin(torture_type, verbose, &locktorture_runnable))
return -EBUSY;
/* Process args and tell the world that the torturer is on the job. */ /* Process args and tell the world that the torturer is on the job. */
for (i = 0; i < ARRAY_SIZE(torture_ops); i++) { for (i = 0; i < ARRAY_SIZE(torture_ops); i++) {
......
This diff is collapsed.
...@@ -144,7 +144,7 @@ static void check_cpu_stall(struct rcu_ctrlblk *rcp) ...@@ -144,7 +144,7 @@ static void check_cpu_stall(struct rcu_ctrlblk *rcp)
return; return;
rcp->ticks_this_gp++; rcp->ticks_this_gp++;
j = jiffies; j = jiffies;
js = rcp->jiffies_stall; js = ACCESS_ONCE(rcp->jiffies_stall);
if (*rcp->curtail && ULONG_CMP_GE(j, js)) { if (*rcp->curtail && ULONG_CMP_GE(j, js)) {
pr_err("INFO: %s stall on CPU (%lu ticks this GP) idle=%llx (t=%lu jiffies q=%ld)\n", pr_err("INFO: %s stall on CPU (%lu ticks this GP) idle=%llx (t=%lu jiffies q=%ld)\n",
rcp->name, rcp->ticks_this_gp, rcu_dynticks_nesting, rcp->name, rcp->ticks_this_gp, rcu_dynticks_nesting,
...@@ -152,17 +152,17 @@ static void check_cpu_stall(struct rcu_ctrlblk *rcp) ...@@ -152,17 +152,17 @@ static void check_cpu_stall(struct rcu_ctrlblk *rcp)
dump_stack(); dump_stack();
} }
if (*rcp->curtail && ULONG_CMP_GE(j, js)) if (*rcp->curtail && ULONG_CMP_GE(j, js))
rcp->jiffies_stall = jiffies + ACCESS_ONCE(rcp->jiffies_stall) = jiffies +
3 * rcu_jiffies_till_stall_check() + 3; 3 * rcu_jiffies_till_stall_check() + 3;
else if (ULONG_CMP_GE(j, js)) else if (ULONG_CMP_GE(j, js))
rcp->jiffies_stall = jiffies + rcu_jiffies_till_stall_check(); ACCESS_ONCE(rcp->jiffies_stall) = jiffies + rcu_jiffies_till_stall_check();
} }
static void reset_cpu_stall_ticks(struct rcu_ctrlblk *rcp) static void reset_cpu_stall_ticks(struct rcu_ctrlblk *rcp)
{ {
rcp->ticks_this_gp = 0; rcp->ticks_this_gp = 0;
rcp->gp_start = jiffies; rcp->gp_start = jiffies;
rcp->jiffies_stall = jiffies + rcu_jiffies_till_stall_check(); ACCESS_ONCE(rcp->jiffies_stall) = jiffies + rcu_jiffies_till_stall_check();
} }
static void check_cpu_stalls(void) static void check_cpu_stalls(void)
......
This diff is collapsed.
...@@ -252,7 +252,6 @@ struct rcu_data { ...@@ -252,7 +252,6 @@ struct rcu_data {
bool passed_quiesce; /* User-mode/idle loop etc. */ bool passed_quiesce; /* User-mode/idle loop etc. */
bool qs_pending; /* Core waits for quiesc state. */ bool qs_pending; /* Core waits for quiesc state. */
bool beenonline; /* CPU online at least once. */ bool beenonline; /* CPU online at least once. */
bool preemptible; /* Preemptible RCU? */
struct rcu_node *mynode; /* This CPU's leaf of hierarchy */ struct rcu_node *mynode; /* This CPU's leaf of hierarchy */
unsigned long grpmask; /* Mask to apply to leaf qsmask. */ unsigned long grpmask; /* Mask to apply to leaf qsmask. */
#ifdef CONFIG_RCU_CPU_STALL_INFO #ifdef CONFIG_RCU_CPU_STALL_INFO
...@@ -406,7 +405,8 @@ struct rcu_state { ...@@ -406,7 +405,8 @@ struct rcu_state {
unsigned long completed; /* # of last completed gp. */ unsigned long completed; /* # of last completed gp. */
struct task_struct *gp_kthread; /* Task for grace periods. */ struct task_struct *gp_kthread; /* Task for grace periods. */
wait_queue_head_t gp_wq; /* Where GP task waits. */ wait_queue_head_t gp_wq; /* Where GP task waits. */
int gp_flags; /* Commands for GP task. */ short gp_flags; /* Commands for GP task. */
short gp_state; /* GP kthread sleep state. */
/* End of fields guarded by root rcu_node's lock. */ /* End of fields guarded by root rcu_node's lock. */
...@@ -462,13 +462,17 @@ struct rcu_state { ...@@ -462,13 +462,17 @@ struct rcu_state {
const char *name; /* Name of structure. */ const char *name; /* Name of structure. */
char abbr; /* Abbreviated name. */ char abbr; /* Abbreviated name. */
struct list_head flavors; /* List of RCU flavors. */ struct list_head flavors; /* List of RCU flavors. */
struct irq_work wakeup_work; /* Postponed wakeups */
}; };
/* Values for rcu_state structure's gp_flags field. */ /* Values for rcu_state structure's gp_flags field. */
#define RCU_GP_FLAG_INIT 0x1 /* Need grace-period initialization. */ #define RCU_GP_FLAG_INIT 0x1 /* Need grace-period initialization. */
#define RCU_GP_FLAG_FQS 0x2 /* Need grace-period quiescent-state forcing. */ #define RCU_GP_FLAG_FQS 0x2 /* Need grace-period quiescent-state forcing. */
/* Values for rcu_state structure's gp_flags field. */
#define RCU_GP_WAIT_INIT 0 /* Initial state. */
#define RCU_GP_WAIT_GPS 1 /* Wait for grace-period start. */
#define RCU_GP_WAIT_FQS 2 /* Wait for force-quiescent-state time. */
extern struct list_head rcu_struct_flavors; extern struct list_head rcu_struct_flavors;
/* Sequence through rcu_state structures for each RCU flavor. */ /* Sequence through rcu_state structures for each RCU flavor. */
...@@ -547,7 +551,6 @@ static void print_cpu_stall_info(struct rcu_state *rsp, int cpu); ...@@ -547,7 +551,6 @@ static void print_cpu_stall_info(struct rcu_state *rsp, int cpu);
static void print_cpu_stall_info_end(void); static void print_cpu_stall_info_end(void);
static void zero_cpu_stall_ticks(struct rcu_data *rdp); static void zero_cpu_stall_ticks(struct rcu_data *rdp);
static void increment_cpu_stall_ticks(void); static void increment_cpu_stall_ticks(void);
static int rcu_nocb_needs_gp(struct rcu_state *rsp);
static void rcu_nocb_gp_set(struct rcu_node *rnp, int nrq); static void rcu_nocb_gp_set(struct rcu_node *rnp, int nrq);
static void rcu_nocb_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp); static void rcu_nocb_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp);
static void rcu_init_one_nocb(struct rcu_node *rnp); static void rcu_init_one_nocb(struct rcu_node *rnp);
......
...@@ -148,15 +148,6 @@ long rcu_batches_completed(void) ...@@ -148,15 +148,6 @@ long rcu_batches_completed(void)
} }
EXPORT_SYMBOL_GPL(rcu_batches_completed); EXPORT_SYMBOL_GPL(rcu_batches_completed);
/*
* Force a quiescent state for preemptible RCU.
*/
void rcu_force_quiescent_state(void)
{
force_quiescent_state(&rcu_preempt_state);
}
EXPORT_SYMBOL_GPL(rcu_force_quiescent_state);
/* /*
* Record a preemptible-RCU quiescent state for the specified CPU. Note * Record a preemptible-RCU quiescent state for the specified CPU. Note
* that this just means that the task currently running on the CPU is * that this just means that the task currently running on the CPU is
...@@ -688,20 +679,6 @@ void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu)) ...@@ -688,20 +679,6 @@ void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
} }
EXPORT_SYMBOL_GPL(call_rcu); EXPORT_SYMBOL_GPL(call_rcu);
/*
* Queue an RCU callback for lazy invocation after a grace period.
* This will likely be later named something like "call_rcu_lazy()",
* but this change will require some way of tagging the lazy RCU
* callbacks in the list of pending callbacks. Until then, this
* function may only be called from __kfree_rcu().
*/
void kfree_call_rcu(struct rcu_head *head,
void (*func)(struct rcu_head *rcu))
{
__call_rcu(head, func, &rcu_preempt_state, -1, 1);
}
EXPORT_SYMBOL_GPL(kfree_call_rcu);
/** /**
* synchronize_rcu - wait until a grace period has elapsed. * synchronize_rcu - wait until a grace period has elapsed.
* *
...@@ -990,16 +967,6 @@ long rcu_batches_completed(void) ...@@ -990,16 +967,6 @@ long rcu_batches_completed(void)
} }
EXPORT_SYMBOL_GPL(rcu_batches_completed); EXPORT_SYMBOL_GPL(rcu_batches_completed);
/*
* Force a quiescent state for RCU, which, because there is no preemptible
* RCU, becomes the same as rcu-sched.
*/
void rcu_force_quiescent_state(void)
{
rcu_sched_force_quiescent_state();
}
EXPORT_SYMBOL_GPL(rcu_force_quiescent_state);
/* /*
* Because preemptible RCU does not exist, we never have to check for * Because preemptible RCU does not exist, we never have to check for
* CPUs being in quiescent states. * CPUs being in quiescent states.
...@@ -1079,22 +1046,6 @@ static void rcu_preempt_check_callbacks(int cpu) ...@@ -1079,22 +1046,6 @@ static void rcu_preempt_check_callbacks(int cpu)
{ {
} }
/*
* Queue an RCU callback for lazy invocation after a grace period.
* This will likely be later named something like "call_rcu_lazy()",
* but this change will require some way of tagging the lazy RCU
* callbacks in the list of pending callbacks. Until then, this
* function may only be called from __kfree_rcu().
*
* Because there is no preemptible RCU, we use RCU-sched instead.
*/
void kfree_call_rcu(struct rcu_head *head,
void (*func)(struct rcu_head *rcu))
{
__call_rcu(head, func, &rcu_sched_state, -1, 1);
}
EXPORT_SYMBOL_GPL(kfree_call_rcu);
/* /*
* Wait for an rcu-preempt grace period, but make it happen quickly. * Wait for an rcu-preempt grace period, but make it happen quickly.
* But because preemptible RCU does not exist, map to rcu-sched. * But because preemptible RCU does not exist, map to rcu-sched.
...@@ -1744,6 +1695,7 @@ int rcu_needs_cpu(int cpu, unsigned long *dj) ...@@ -1744,6 +1695,7 @@ int rcu_needs_cpu(int cpu, unsigned long *dj)
static void rcu_prepare_for_idle(int cpu) static void rcu_prepare_for_idle(int cpu)
{ {
#ifndef CONFIG_RCU_NOCB_CPU_ALL #ifndef CONFIG_RCU_NOCB_CPU_ALL
bool needwake;
struct rcu_data *rdp; struct rcu_data *rdp;
struct rcu_dynticks *rdtp = &per_cpu(rcu_dynticks, cpu); struct rcu_dynticks *rdtp = &per_cpu(rcu_dynticks, cpu);
struct rcu_node *rnp; struct rcu_node *rnp;
...@@ -1792,8 +1744,10 @@ static void rcu_prepare_for_idle(int cpu) ...@@ -1792,8 +1744,10 @@ static void rcu_prepare_for_idle(int cpu)
rnp = rdp->mynode; rnp = rdp->mynode;
raw_spin_lock(&rnp->lock); /* irqs already disabled. */ raw_spin_lock(&rnp->lock); /* irqs already disabled. */
smp_mb__after_unlock_lock(); smp_mb__after_unlock_lock();
rcu_accelerate_cbs(rsp, rnp, rdp); needwake = rcu_accelerate_cbs(rsp, rnp, rdp);
raw_spin_unlock(&rnp->lock); /* irqs remain disabled. */ raw_spin_unlock(&rnp->lock); /* irqs remain disabled. */
if (needwake)
rcu_gp_kthread_wake(rsp);
} }
#endif /* #ifndef CONFIG_RCU_NOCB_CPU_ALL */ #endif /* #ifndef CONFIG_RCU_NOCB_CPU_ALL */
} }
...@@ -1855,7 +1809,7 @@ static void rcu_oom_notify_cpu(void *unused) ...@@ -1855,7 +1809,7 @@ static void rcu_oom_notify_cpu(void *unused)
struct rcu_data *rdp; struct rcu_data *rdp;
for_each_rcu_flavor(rsp) { for_each_rcu_flavor(rsp) {
rdp = __this_cpu_ptr(rsp->rda); rdp = raw_cpu_ptr(rsp->rda);
if (rdp->qlen_lazy != 0) { if (rdp->qlen_lazy != 0) {
atomic_inc(&oom_callback_count); atomic_inc(&oom_callback_count);
rsp->call(&rdp->oom_head, rcu_oom_callback); rsp->call(&rdp->oom_head, rcu_oom_callback);
...@@ -1997,7 +1951,7 @@ static void increment_cpu_stall_ticks(void) ...@@ -1997,7 +1951,7 @@ static void increment_cpu_stall_ticks(void)
struct rcu_state *rsp; struct rcu_state *rsp;
for_each_rcu_flavor(rsp) for_each_rcu_flavor(rsp)
__this_cpu_ptr(rsp->rda)->ticks_this_gp++; raw_cpu_inc(rsp->rda->ticks_this_gp);
} }
#else /* #ifdef CONFIG_RCU_CPU_STALL_INFO */ #else /* #ifdef CONFIG_RCU_CPU_STALL_INFO */
...@@ -2067,19 +2021,6 @@ static int __init parse_rcu_nocb_poll(char *arg) ...@@ -2067,19 +2021,6 @@ static int __init parse_rcu_nocb_poll(char *arg)
} }
early_param("rcu_nocb_poll", parse_rcu_nocb_poll); early_param("rcu_nocb_poll", parse_rcu_nocb_poll);
/*
* Do any no-CBs CPUs need another grace period?
*
* Interrupts must be disabled. If the caller does not hold the root
* rnp_node structure's ->lock, the results are advisory only.
*/
static int rcu_nocb_needs_gp(struct rcu_state *rsp)
{
struct rcu_node *rnp = rcu_get_root(rsp);
return rnp->need_future_gp[(ACCESS_ONCE(rnp->completed) + 1) & 0x1];
}
/* /*
* Wake up any no-CBs CPUs' kthreads that were waiting on the just-ended * Wake up any no-CBs CPUs' kthreads that were waiting on the just-ended
* grace period. * grace period.
...@@ -2109,7 +2050,7 @@ static void rcu_init_one_nocb(struct rcu_node *rnp) ...@@ -2109,7 +2050,7 @@ static void rcu_init_one_nocb(struct rcu_node *rnp)
} }
#ifndef CONFIG_RCU_NOCB_CPU_ALL #ifndef CONFIG_RCU_NOCB_CPU_ALL
/* Is the specified CPU a no-CPUs CPU? */ /* Is the specified CPU a no-CBs CPU? */
bool rcu_is_nocb_cpu(int cpu) bool rcu_is_nocb_cpu(int cpu)
{ {
if (have_rcu_nocb_mask) if (have_rcu_nocb_mask)
...@@ -2243,12 +2184,15 @@ static void rcu_nocb_wait_gp(struct rcu_data *rdp) ...@@ -2243,12 +2184,15 @@ static void rcu_nocb_wait_gp(struct rcu_data *rdp)
unsigned long c; unsigned long c;
bool d; bool d;
unsigned long flags; unsigned long flags;
bool needwake;
struct rcu_node *rnp = rdp->mynode; struct rcu_node *rnp = rdp->mynode;
raw_spin_lock_irqsave(&rnp->lock, flags); raw_spin_lock_irqsave(&rnp->lock, flags);
smp_mb__after_unlock_lock(); smp_mb__after_unlock_lock();
c = rcu_start_future_gp(rnp, rdp); needwake = rcu_start_future_gp(rnp, rdp, &c);
raw_spin_unlock_irqrestore(&rnp->lock, flags); raw_spin_unlock_irqrestore(&rnp->lock, flags);
if (needwake)
rcu_gp_kthread_wake(rdp->rsp);
/* /*
* Wait for the grace period. Do so interruptibly to avoid messing * Wait for the grace period. Do so interruptibly to avoid messing
...@@ -2402,11 +2346,6 @@ static bool init_nocb_callback_list(struct rcu_data *rdp) ...@@ -2402,11 +2346,6 @@ static bool init_nocb_callback_list(struct rcu_data *rdp)
#else /* #ifdef CONFIG_RCU_NOCB_CPU */ #else /* #ifdef CONFIG_RCU_NOCB_CPU */
static int rcu_nocb_needs_gp(struct rcu_state *rsp)
{
return 0;
}
static void rcu_nocb_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp) static void rcu_nocb_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp)
{ {
} }
...@@ -2656,20 +2595,6 @@ static bool is_sysidle_rcu_state(struct rcu_state *rsp) ...@@ -2656,20 +2595,6 @@ static bool is_sysidle_rcu_state(struct rcu_state *rsp)
return rsp == rcu_sysidle_state; return rsp == rcu_sysidle_state;
} }
/*
* Bind the grace-period kthread for the sysidle flavor of RCU to the
* timekeeping CPU.
*/
static void rcu_bind_gp_kthread(void)
{
int cpu = ACCESS_ONCE(tick_do_timer_cpu);
if (cpu < 0 || cpu >= nr_cpu_ids)
return;
if (raw_smp_processor_id() != cpu)
set_cpus_allowed_ptr(current, cpumask_of(cpu));
}
/* /*
* Return a delay in jiffies based on the number of CPUs, rcu_node * Return a delay in jiffies based on the number of CPUs, rcu_node
* leaf fanout, and jiffies tick rate. The idea is to allow larger * leaf fanout, and jiffies tick rate. The idea is to allow larger
...@@ -2734,7 +2659,8 @@ static void rcu_sysidle(unsigned long j) ...@@ -2734,7 +2659,8 @@ static void rcu_sysidle(unsigned long j)
static void rcu_sysidle_cancel(void) static void rcu_sysidle_cancel(void)
{ {
smp_mb(); smp_mb();
ACCESS_ONCE(full_sysidle_state) = RCU_SYSIDLE_NOT; if (full_sysidle_state > RCU_SYSIDLE_SHORT)
ACCESS_ONCE(full_sysidle_state) = RCU_SYSIDLE_NOT;
} }
/* /*
...@@ -2880,10 +2806,6 @@ static bool is_sysidle_rcu_state(struct rcu_state *rsp) ...@@ -2880,10 +2806,6 @@ static bool is_sysidle_rcu_state(struct rcu_state *rsp)
return false; return false;
} }
static void rcu_bind_gp_kthread(void)
{
}
static void rcu_sysidle_report_gp(struct rcu_state *rsp, int isidle, static void rcu_sysidle_report_gp(struct rcu_state *rsp, int isidle,
unsigned long maxj) unsigned long maxj)
{ {
...@@ -2914,3 +2836,19 @@ static bool rcu_nohz_full_cpu(struct rcu_state *rsp) ...@@ -2914,3 +2836,19 @@ static bool rcu_nohz_full_cpu(struct rcu_state *rsp)
#endif /* #ifdef CONFIG_NO_HZ_FULL */ #endif /* #ifdef CONFIG_NO_HZ_FULL */
return 0; return 0;
} }
/*
* Bind the grace-period kthread for the sysidle flavor of RCU to the
* timekeeping CPU.
*/
static void rcu_bind_gp_kthread(void)
{
#ifdef CONFIG_NO_HZ_FULL
int cpu = ACCESS_ONCE(tick_do_timer_cpu);
if (cpu < 0 || cpu >= nr_cpu_ids)
return;
if (raw_smp_processor_id() != cpu)
set_cpus_allowed_ptr(current, cpumask_of(cpu));
#endif /* #ifdef CONFIG_NO_HZ_FULL */
}
...@@ -338,3 +338,21 @@ static int __init check_cpu_stall_init(void) ...@@ -338,3 +338,21 @@ static int __init check_cpu_stall_init(void)
early_initcall(check_cpu_stall_init); early_initcall(check_cpu_stall_init);
#endif /* #ifdef CONFIG_RCU_STALL_COMMON */ #endif /* #ifdef CONFIG_RCU_STALL_COMMON */
/*
* Hooks for cond_resched() and friends to avoid RCU CPU stall warnings.
*/
DEFINE_PER_CPU(int, rcu_cond_resched_count);
/*
* Report a set of RCU quiescent states, for use by cond_resched()
* and friends. Out of line due to being called infrequently.
*/
void rcu_resched(void)
{
preempt_disable();
__this_cpu_write(rcu_cond_resched_count, 0);
rcu_note_context_switch(smp_processor_id());
preempt_enable();
}
...@@ -4051,6 +4051,7 @@ static void __cond_resched(void) ...@@ -4051,6 +4051,7 @@ static void __cond_resched(void)
int __sched _cond_resched(void) int __sched _cond_resched(void)
{ {
rcu_cond_resched();
if (should_resched()) { if (should_resched()) {
__cond_resched(); __cond_resched();
return 1; return 1;
...@@ -4069,15 +4070,18 @@ EXPORT_SYMBOL(_cond_resched); ...@@ -4069,15 +4070,18 @@ EXPORT_SYMBOL(_cond_resched);
*/ */
int __cond_resched_lock(spinlock_t *lock) int __cond_resched_lock(spinlock_t *lock)
{ {
bool need_rcu_resched = rcu_should_resched();
int resched = should_resched(); int resched = should_resched();
int ret = 0; int ret = 0;
lockdep_assert_held(lock); lockdep_assert_held(lock);
if (spin_needbreak(lock) || resched) { if (spin_needbreak(lock) || resched || need_rcu_resched) {
spin_unlock(lock); spin_unlock(lock);
if (resched) if (resched)
__cond_resched(); __cond_resched();
else if (unlikely(need_rcu_resched))
rcu_resched();
else else
cpu_relax(); cpu_relax();
ret = 1; ret = 1;
...@@ -4091,6 +4095,7 @@ int __sched __cond_resched_softirq(void) ...@@ -4091,6 +4095,7 @@ int __sched __cond_resched_softirq(void)
{ {
BUG_ON(!in_softirq()); BUG_ON(!in_softirq());
rcu_cond_resched(); /* BH disabled OK, just recording QSes. */
if (should_resched()) { if (should_resched()) {
local_bh_enable(); local_bh_enable();
__cond_resched(); __cond_resched();
......
...@@ -232,7 +232,6 @@ asmlinkage void __do_softirq(void) ...@@ -232,7 +232,6 @@ asmlinkage void __do_softirq(void)
bool in_hardirq; bool in_hardirq;
__u32 pending; __u32 pending;
int softirq_bit; int softirq_bit;
int cpu;
/* /*
* Mask out PF_MEMALLOC s current task context is borrowed for the * Mask out PF_MEMALLOC s current task context is borrowed for the
...@@ -247,7 +246,6 @@ asmlinkage void __do_softirq(void) ...@@ -247,7 +246,6 @@ asmlinkage void __do_softirq(void)
__local_bh_disable_ip(_RET_IP_, SOFTIRQ_OFFSET); __local_bh_disable_ip(_RET_IP_, SOFTIRQ_OFFSET);
in_hardirq = lockdep_softirq_start(); in_hardirq = lockdep_softirq_start();
cpu = smp_processor_id();
restart: restart:
/* Reset the pending bitmask before enabling irqs */ /* Reset the pending bitmask before enabling irqs */
set_softirq_pending(0); set_softirq_pending(0);
...@@ -276,11 +274,11 @@ asmlinkage void __do_softirq(void) ...@@ -276,11 +274,11 @@ asmlinkage void __do_softirq(void)
prev_count, preempt_count()); prev_count, preempt_count());
preempt_count_set(prev_count); preempt_count_set(prev_count);
} }
rcu_bh_qs(cpu);
h++; h++;
pending >>= softirq_bit; pending >>= softirq_bit;
} }
rcu_bh_qs(smp_processor_id());
local_irq_disable(); local_irq_disable();
pending = local_softirq_pending(); pending = local_softirq_pending();
......
...@@ -335,13 +335,8 @@ static void torture_shuffle_tasks(void) ...@@ -335,13 +335,8 @@ static void torture_shuffle_tasks(void)
shuffle_idle_cpu = cpumask_next(shuffle_idle_cpu, shuffle_tmp_mask); shuffle_idle_cpu = cpumask_next(shuffle_idle_cpu, shuffle_tmp_mask);
if (shuffle_idle_cpu >= nr_cpu_ids) if (shuffle_idle_cpu >= nr_cpu_ids)
shuffle_idle_cpu = -1; shuffle_idle_cpu = -1;
if (shuffle_idle_cpu != -1) { else
cpumask_clear_cpu(shuffle_idle_cpu, shuffle_tmp_mask); cpumask_clear_cpu(shuffle_idle_cpu, shuffle_tmp_mask);
if (cpumask_empty(shuffle_tmp_mask)) {
put_online_cpus();
return;
}
}
mutex_lock(&shuffle_task_mutex); mutex_lock(&shuffle_task_mutex);
list_for_each_entry(stp, &shuffle_task_list, st_l) list_for_each_entry(stp, &shuffle_task_list, st_l)
...@@ -533,7 +528,11 @@ void stutter_wait(const char *title) ...@@ -533,7 +528,11 @@ void stutter_wait(const char *title)
while (ACCESS_ONCE(stutter_pause_test) || while (ACCESS_ONCE(stutter_pause_test) ||
(torture_runnable && !ACCESS_ONCE(*torture_runnable))) { (torture_runnable && !ACCESS_ONCE(*torture_runnable))) {
if (stutter_pause_test) if (stutter_pause_test)
schedule_timeout_interruptible(1); if (ACCESS_ONCE(stutter_pause_test) == 1)
schedule_timeout_interruptible(1);
else
while (ACCESS_ONCE(stutter_pause_test))
cond_resched();
else else
schedule_timeout_interruptible(round_jiffies_relative(HZ)); schedule_timeout_interruptible(round_jiffies_relative(HZ));
torture_shutdown_absorb(title); torture_shutdown_absorb(title);
...@@ -550,7 +549,11 @@ static int torture_stutter(void *arg) ...@@ -550,7 +549,11 @@ static int torture_stutter(void *arg)
VERBOSE_TOROUT_STRING("torture_stutter task started"); VERBOSE_TOROUT_STRING("torture_stutter task started");
do { do {
if (!torture_must_stop()) { if (!torture_must_stop()) {
schedule_timeout_interruptible(stutter); if (stutter > 1) {
schedule_timeout_interruptible(stutter - 1);
ACCESS_ONCE(stutter_pause_test) = 2;
}
schedule_timeout_interruptible(1);
ACCESS_ONCE(stutter_pause_test) = 1; ACCESS_ONCE(stutter_pause_test) = 1;
} }
if (!torture_must_stop()) if (!torture_must_stop())
...@@ -596,21 +599,27 @@ static void torture_stutter_cleanup(void) ...@@ -596,21 +599,27 @@ static void torture_stutter_cleanup(void)
* The runnable parameter points to a flag that controls whether or not * The runnable parameter points to a flag that controls whether or not
* the test is currently runnable. If there is no such flag, pass in NULL. * the test is currently runnable. If there is no such flag, pass in NULL.
*/ */
void __init torture_init_begin(char *ttype, bool v, int *runnable) bool torture_init_begin(char *ttype, bool v, int *runnable)
{ {
mutex_lock(&fullstop_mutex); mutex_lock(&fullstop_mutex);
if (torture_type != NULL) {
pr_alert("torture_init_begin: refusing %s init: %s running",
ttype, torture_type);
mutex_unlock(&fullstop_mutex);
return false;
}
torture_type = ttype; torture_type = ttype;
verbose = v; verbose = v;
torture_runnable = runnable; torture_runnable = runnable;
fullstop = FULLSTOP_DONTSTOP; fullstop = FULLSTOP_DONTSTOP;
return true;
} }
EXPORT_SYMBOL_GPL(torture_init_begin); EXPORT_SYMBOL_GPL(torture_init_begin);
/* /*
* Tell the torture module that initialization is complete. * Tell the torture module that initialization is complete.
*/ */
void __init torture_init_end(void) void torture_init_end(void)
{ {
mutex_unlock(&fullstop_mutex); mutex_unlock(&fullstop_mutex);
register_reboot_notifier(&torture_shutdown_nb); register_reboot_notifier(&torture_shutdown_nb);
...@@ -642,6 +651,9 @@ bool torture_cleanup(void) ...@@ -642,6 +651,9 @@ bool torture_cleanup(void)
torture_shuffle_cleanup(); torture_shuffle_cleanup();
torture_stutter_cleanup(); torture_stutter_cleanup();
torture_onoff_cleanup(); torture_onoff_cleanup();
mutex_lock(&fullstop_mutex);
torture_type = NULL;
mutex_unlock(&fullstop_mutex);
return false; return false;
} }
EXPORT_SYMBOL_GPL(torture_cleanup); EXPORT_SYMBOL_GPL(torture_cleanup);
...@@ -674,8 +686,10 @@ EXPORT_SYMBOL_GPL(torture_must_stop_irq); ...@@ -674,8 +686,10 @@ EXPORT_SYMBOL_GPL(torture_must_stop_irq);
*/ */
void torture_kthread_stopping(char *title) void torture_kthread_stopping(char *title)
{ {
if (verbose) char buf[128];
VERBOSE_TOROUT_STRING(title);
snprintf(buf, sizeof(buf), "Stopping %s", title);
VERBOSE_TOROUT_STRING(buf);
while (!kthread_should_stop()) { while (!kthread_should_stop()) {
torture_shutdown_absorb(title); torture_shutdown_absorb(title);
schedule_timeout_uninterruptible(1); schedule_timeout_uninterruptible(1);
......
...@@ -62,7 +62,7 @@ grep '^grep' < $T/u.sh > $T/upd.sh ...@@ -62,7 +62,7 @@ grep '^grep' < $T/u.sh > $T/upd.sh
echo "cat - $c" >> $T/upd.sh echo "cat - $c" >> $T/upd.sh
make mrproper make mrproper
make $buildloc distclean > $builddir/Make.distclean 2>&1 make $buildloc distclean > $builddir/Make.distclean 2>&1
make $buildloc defconfig > $builddir/Make.defconfig.out 2>&1 make $buildloc $TORTURE_DEFCONFIG > $builddir/Make.defconfig.out 2>&1
mv $builddir/.config $builddir/.config.sav mv $builddir/.config $builddir/.config.sav
sh $T/upd.sh < $builddir/.config.sav > $builddir/.config sh $T/upd.sh < $builddir/.config.sav > $builddir/.config
cp $builddir/.config $builddir/.config.new cp $builddir/.config $builddir/.config.new
......
...@@ -76,15 +76,39 @@ configfrag_hotplug_cpu () { ...@@ -76,15 +76,39 @@ configfrag_hotplug_cpu () {
grep -q '^CONFIG_HOTPLUG_CPU=y$' "$1" grep -q '^CONFIG_HOTPLUG_CPU=y$' "$1"
} }
# identify_boot_image qemu-cmd
#
# Returns the relative path to the kernel build image. This will be
# arch/<arch>/boot/bzImage unless overridden with the TORTURE_BOOT_IMAGE
# environment variable.
identify_boot_image () {
if test -n "$TORTURE_BOOT_IMAGE"
then
echo $TORTURE_BOOT_IMAGE
else
case "$1" in
qemu-system-x86_64|qemu-system-i386)
echo arch/x86/boot/bzImage
;;
qemu-system-ppc64)
echo arch/powerpc/boot/bzImage
;;
*)
echo ""
;;
esac
fi
}
# identify_qemu builddir # identify_qemu builddir
# #
# Returns our best guess as to which qemu command is appropriate for # Returns our best guess as to which qemu command is appropriate for
# the kernel at hand. Override with the RCU_QEMU_CMD environment variable. # the kernel at hand. Override with the TORTURE_QEMU_CMD environment variable.
identify_qemu () { identify_qemu () {
local u="`file "$1"`" local u="`file "$1"`"
if test -n "$RCU_QEMU_CMD" if test -n "$TORTURE_QEMU_CMD"
then then
echo $RCU_QEMU_CMD echo $TORTURE_QEMU_CMD
elif echo $u | grep -q x86-64 elif echo $u | grep -q x86-64
then then
echo qemu-system-x86_64 echo qemu-system-x86_64
...@@ -98,7 +122,7 @@ identify_qemu () { ...@@ -98,7 +122,7 @@ identify_qemu () {
echo Cannot figure out what qemu command to use! 1>&2 echo Cannot figure out what qemu command to use! 1>&2
echo file $1 output: $u echo file $1 output: $u
# Usually this will be one of /usr/bin/qemu-system-* # Usually this will be one of /usr/bin/qemu-system-*
# Use RCU_QEMU_CMD environment variable or appropriate # Use TORTURE_QEMU_CMD environment variable or appropriate
# argument to top-level script. # argument to top-level script.
exit 1 exit 1
fi fi
...@@ -107,14 +131,14 @@ identify_qemu () { ...@@ -107,14 +131,14 @@ identify_qemu () {
# identify_qemu_append qemu-cmd # identify_qemu_append qemu-cmd
# #
# Output arguments for the qemu "-append" string based on CPU type # Output arguments for the qemu "-append" string based on CPU type
# and the RCU_QEMU_INTERACTIVE environment variable. # and the TORTURE_QEMU_INTERACTIVE environment variable.
identify_qemu_append () { identify_qemu_append () {
case "$1" in case "$1" in
qemu-system-x86_64|qemu-system-i386) qemu-system-x86_64|qemu-system-i386)
echo noapic selinux=0 initcall_debug debug echo noapic selinux=0 initcall_debug debug
;; ;;
esac esac
if test -n "$RCU_QEMU_INTERACTIVE" if test -n "$TORTURE_QEMU_INTERACTIVE"
then then
echo root=/dev/sda echo root=/dev/sda
else else
...@@ -124,8 +148,8 @@ identify_qemu_append () { ...@@ -124,8 +148,8 @@ identify_qemu_append () {
# identify_qemu_args qemu-cmd serial-file # identify_qemu_args qemu-cmd serial-file
# #
# Output arguments for qemu arguments based on the RCU_QEMU_MAC # Output arguments for qemu arguments based on the TORTURE_QEMU_MAC
# and RCU_QEMU_INTERACTIVE environment variables. # and TORTURE_QEMU_INTERACTIVE environment variables.
identify_qemu_args () { identify_qemu_args () {
case "$1" in case "$1" in
qemu-system-x86_64|qemu-system-i386) qemu-system-x86_64|qemu-system-i386)
...@@ -133,17 +157,17 @@ identify_qemu_args () { ...@@ -133,17 +157,17 @@ identify_qemu_args () {
qemu-system-ppc64) qemu-system-ppc64)
echo -enable-kvm -M pseries -cpu POWER7 -nodefaults echo -enable-kvm -M pseries -cpu POWER7 -nodefaults
echo -device spapr-vscsi echo -device spapr-vscsi
if test -n "$RCU_QEMU_INTERACTIVE" -a -n "$RCU_QEMU_MAC" if test -n "$TORTURE_QEMU_INTERACTIVE" -a -n "$TORTURE_QEMU_MAC"
then then
echo -device spapr-vlan,netdev=net0,mac=$RCU_QEMU_MAC echo -device spapr-vlan,netdev=net0,mac=$TORTURE_QEMU_MAC
echo -netdev bridge,br=br0,id=net0 echo -netdev bridge,br=br0,id=net0
elif test -n "$RCU_QEMU_INTERACTIVE" elif test -n "$TORTURE_QEMU_INTERACTIVE"
then then
echo -net nic -net user echo -net nic -net user
fi fi
;; ;;
esac esac
if test -n "$RCU_QEMU_INTERACTIVE" if test -n "$TORTURE_QEMU_INTERACTIVE"
then then
echo -monitor stdio -serial pty -S echo -monitor stdio -serial pty -S
else else
......
...@@ -45,9 +45,9 @@ T=/tmp/test-linux.sh.$$ ...@@ -45,9 +45,9 @@ T=/tmp/test-linux.sh.$$
trap 'rm -rf $T' 0 trap 'rm -rf $T' 0
mkdir $T mkdir $T
cat ${config_template} | grep -v CONFIG_RCU_TORTURE_TEST > $T/config grep -v 'CONFIG_[A-Z]*_TORTURE_TEST' < ${config_template} > $T/config
cat << ___EOF___ >> $T/config cat << ___EOF___ >> $T/config
CONFIG_INITRAMFS_SOURCE="$RCU_INITRD" CONFIG_INITRAMFS_SOURCE="$TORTURE_INITRD"
CONFIG_VIRTIO_PCI=y CONFIG_VIRTIO_PCI=y
CONFIG_VIRTIO_CONSOLE=y CONFIG_VIRTIO_CONSOLE=y
___EOF___ ___EOF___
...@@ -60,7 +60,7 @@ then ...@@ -60,7 +60,7 @@ then
exit 2 exit 2
fi fi
ncpus=`cpus2use.sh` ncpus=`cpus2use.sh`
make O=$builddir -j$ncpus $RCU_KMAKE_ARG > $builddir/Make.out 2>&1 make O=$builddir -j$ncpus $TORTURE_KMAKE_ARG > $builddir/Make.out 2>&1
retval=$? retval=$?
if test $retval -ne 0 || grep "rcu[^/]*": < $builddir/Make.out | egrep -q "Stop|Error|error:|warning:" || egrep -q "Stop|Error|error:" < $builddir/Make.out if test $retval -ne 0 || grep "rcu[^/]*": < $builddir/Make.out | egrep -q "Stop|Error|error:|warning:" || egrep -q "Stop|Error|error:" < $builddir/Make.out
then then
......
...@@ -35,7 +35,7 @@ configfile=`echo $i | sed -e 's/^.*\///'` ...@@ -35,7 +35,7 @@ configfile=`echo $i | sed -e 's/^.*\///'`
ncs=`grep "Writes: Total:" $i/console.log 2> /dev/null | tail -1 | sed -e 's/^.* Total: //' -e 's/ .*$//'` ncs=`grep "Writes: Total:" $i/console.log 2> /dev/null | tail -1 | sed -e 's/^.* Total: //' -e 's/ .*$//'`
if test -z "$ncs" if test -z "$ncs"
then then
echo $configfile echo "$configfile -------"
else else
title="$configfile ------- $ncs acquisitions/releases" title="$configfile ------- $ncs acquisitions/releases"
dur=`sed -e 's/^.* locktorture.shutdown_secs=//' -e 's/ .*$//' < $i/qemu-cmd 2> /dev/null` dur=`sed -e 's/^.* locktorture.shutdown_secs=//' -e 's/ .*$//' < $i/qemu-cmd 2> /dev/null`
......
...@@ -35,7 +35,7 @@ configfile=`echo $i | sed -e 's/^.*\///'` ...@@ -35,7 +35,7 @@ configfile=`echo $i | sed -e 's/^.*\///'`
ngps=`grep ver: $i/console.log 2> /dev/null | tail -1 | sed -e 's/^.* ver: //' -e 's/ .*$//'` ngps=`grep ver: $i/console.log 2> /dev/null | tail -1 | sed -e 's/^.* ver: //' -e 's/ .*$//'`
if test -z "$ngps" if test -z "$ngps"
then then
echo $configfile echo "$configfile -------"
else else
title="$configfile ------- $ngps grace periods" title="$configfile ------- $ngps grace periods"
dur=`sed -e 's/^.* rcutorture.shutdown_secs=//' -e 's/ .*$//' < $i/qemu-cmd 2> /dev/null` dur=`sed -e 's/^.* rcutorture.shutdown_secs=//' -e 's/ .*$//' < $i/qemu-cmd 2> /dev/null`
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
# Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com> # Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
PATH=`pwd`/tools/testing/selftests/rcutorture/bin:$PATH; export PATH PATH=`pwd`/tools/testing/selftests/rcutorture/bin:$PATH; export PATH
. tools/testing/selftests/rcutorture/bin/functions.sh
for rd in "$@" for rd in "$@"
do do
firsttime=1 firsttime=1
...@@ -39,13 +40,24 @@ do ...@@ -39,13 +40,24 @@ do
fi fi
TORTURE_SUITE="`cat $i/../TORTURE_SUITE`" TORTURE_SUITE="`cat $i/../TORTURE_SUITE`"
kvm-recheck-${TORTURE_SUITE}.sh $i kvm-recheck-${TORTURE_SUITE}.sh $i
configcheck.sh $i/.config $i/ConfigFragment if test -f "$i/console.log"
parse-build.sh $i/Make.out $configfile
parse-rcutorture.sh $i/console.log $configfile
parse-console.sh $i/console.log $configfile
if test -r $i/Warnings
then then
cat $i/Warnings configcheck.sh $i/.config $i/ConfigFragment
parse-build.sh $i/Make.out $configfile
parse-torture.sh $i/console.log $configfile
parse-console.sh $i/console.log $configfile
if test -r $i/Warnings
then
cat $i/Warnings
fi
else
if test -f "$i/qemu-cmd"
then
print_bug qemu failed
else
print_bug Build failed
fi
echo " $i"
fi fi
done done
done done
...@@ -94,9 +94,17 @@ fi ...@@ -94,9 +94,17 @@ fi
# CONFIG_YENTA=n # CONFIG_YENTA=n
if kvm-build.sh $config_template $builddir $T if kvm-build.sh $config_template $builddir $T
then then
QEMU="`identify_qemu $builddir/vmlinux`"
BOOT_IMAGE="`identify_boot_image $QEMU`"
cp $builddir/Make*.out $resdir cp $builddir/Make*.out $resdir
cp $builddir/.config $resdir cp $builddir/.config $resdir
cp $builddir/arch/x86/boot/bzImage $resdir if test -n "$BOOT_IMAGE"
then
cp $builddir/$BOOT_IMAGE $resdir
else
echo No identifiable boot image, not running KVM, see $resdir.
echo Do the torture scripts know about your architecture?
fi
parse-build.sh $resdir/Make.out $title parse-build.sh $resdir/Make.out $title
if test -f $builddir.wait if test -f $builddir.wait
then then
...@@ -104,6 +112,7 @@ then ...@@ -104,6 +112,7 @@ then
fi fi
else else
cp $builddir/Make*.out $resdir cp $builddir/Make*.out $resdir
cp $builddir/.config $resdir || :
echo Build failed, not running KVM, see $resdir. echo Build failed, not running KVM, see $resdir.
if test -f $builddir.wait if test -f $builddir.wait
then then
...@@ -124,9 +133,6 @@ cd $KVM ...@@ -124,9 +133,6 @@ cd $KVM
kstarttime=`awk 'BEGIN { print systime() }' < /dev/null` kstarttime=`awk 'BEGIN { print systime() }' < /dev/null`
echo ' ---' `date`: Starting kernel echo ' ---' `date`: Starting kernel
# Determine the appropriate flavor of qemu command.
QEMU="`identify_qemu $builddir/vmlinux`"
# Generate -smp qemu argument. # Generate -smp qemu argument.
qemu_args="-nographic $qemu_args" qemu_args="-nographic $qemu_args"
cpu_count=`configNR_CPUS.sh $config_template` cpu_count=`configNR_CPUS.sh $config_template`
...@@ -151,27 +157,38 @@ boot_args="`configfrag_boot_params "$boot_args" "$config_template"`" ...@@ -151,27 +157,38 @@ boot_args="`configfrag_boot_params "$boot_args" "$config_template"`"
# Generate kernel-version-specific boot parameters # Generate kernel-version-specific boot parameters
boot_args="`per_version_boot_params "$boot_args" $builddir/.config $seconds`" boot_args="`per_version_boot_params "$boot_args" $builddir/.config $seconds`"
echo $QEMU $qemu_args -m 512 -kernel $builddir/arch/x86/boot/bzImage -append \"$qemu_append $boot_args\" > $resdir/qemu-cmd echo $QEMU $qemu_args -m 512 -kernel $builddir/$BOOT_IMAGE -append \"$qemu_append $boot_args\" > $resdir/qemu-cmd
if test -n "$RCU_BUILDONLY" if test -n "$TORTURE_BUILDONLY"
then then
echo Build-only run specified, boot/test omitted. echo Build-only run specified, boot/test omitted.
exit 0 exit 0
fi fi
$QEMU $qemu_args -m 512 -kernel $builddir/arch/x86/boot/bzImage -append "$qemu_append $boot_args" & ( $QEMU $qemu_args -m 512 -kernel $builddir/$BOOT_IMAGE -append "$qemu_append $boot_args"; echo $? > $resdir/qemu-retval ) &
qemu_pid=$! qemu_pid=$!
commandcompleted=0 commandcompleted=0
echo Monitoring qemu job at pid $qemu_pid echo Monitoring qemu job at pid $qemu_pid
for ((i=0;i<$seconds;i++)) while :
do do
kruntime=`awk 'BEGIN { print systime() - '"$kstarttime"' }' < /dev/null`
if kill -0 $qemu_pid > /dev/null 2>&1 if kill -0 $qemu_pid > /dev/null 2>&1
then then
if test $kruntime -ge $seconds
then
break;
fi
sleep 1 sleep 1
else else
commandcompleted=1 commandcompleted=1
kruntime=`awk 'BEGIN { print systime() - '"$kstarttime"' }' < /dev/null`
if test $kruntime -lt $seconds if test $kruntime -lt $seconds
then then
echo Completed in $kruntime vs. $seconds >> $resdir/Warnings 2>&1 echo Completed in $kruntime vs. $seconds >> $resdir/Warnings 2>&1
grep "^(qemu) qemu:" $resdir/kvm-test-1-run.sh.out >> $resdir/Warnings 2>&1
killpid="`sed -n "s/^(qemu) qemu: terminating on signal [0-9]* from pid \([0-9]*\).*$/\1/p" $resdir/Warnings`"
if test -n "$killpid"
then
echo "ps -fp $killpid" >> $resdir/Warnings 2>&1
ps -fp $killpid >> $resdir/Warnings 2>&1
fi
else else
echo ' ---' `date`: Kernel done echo ' ---' `date`: Kernel done
fi fi
...@@ -181,23 +198,25 @@ done ...@@ -181,23 +198,25 @@ done
if test $commandcompleted -eq 0 if test $commandcompleted -eq 0
then then
echo Grace period for qemu job at pid $qemu_pid echo Grace period for qemu job at pid $qemu_pid
for ((i=0;i<=$grace;i++)) while :
do do
kruntime=`awk 'BEGIN { print systime() - '"$kstarttime"' }' < /dev/null`
if kill -0 $qemu_pid > /dev/null 2>&1 if kill -0 $qemu_pid > /dev/null 2>&1
then then
sleep 1 :
else else
break break
fi fi
if test $i -eq $grace if test $kruntime -ge $((seconds + grace))
then then
kruntime=`awk 'BEGIN { print systime() - '"$kstarttime"' }'`
echo "!!! Hang at $kruntime vs. $seconds seconds" >> $resdir/Warnings 2>&1 echo "!!! Hang at $kruntime vs. $seconds seconds" >> $resdir/Warnings 2>&1
kill -KILL $qemu_pid kill -KILL $qemu_pid
break
fi fi
sleep 1
done done
fi fi
cp $builddir/console.log $resdir cp $builddir/console.log $resdir
parse-${TORTURE_SUITE}torture.sh $resdir/console.log $title parse-torture.sh $resdir/console.log $title
parse-console.sh $resdir/console.log $title parse-console.sh $resdir/console.log $title
...@@ -38,9 +38,10 @@ dur=30 ...@@ -38,9 +38,10 @@ dur=30
dryrun="" dryrun=""
KVM="`pwd`/tools/testing/selftests/rcutorture"; export KVM KVM="`pwd`/tools/testing/selftests/rcutorture"; export KVM
PATH=${KVM}/bin:$PATH; export PATH PATH=${KVM}/bin:$PATH; export PATH
builddir="${KVM}/b1" TORTURE_DEFCONFIG=defconfig
RCU_INITRD="$KVM/initrd"; export RCU_INITRD TORTURE_BOOT_IMAGE=""
RCU_KMAKE_ARG=""; export RCU_KMAKE_ARG TORTURE_INITRD="$KVM/initrd"; export TORTURE_INITRD
TORTURE_KMAKE_ARG=""
TORTURE_SUITE=rcu TORTURE_SUITE=rcu
resdir="" resdir=""
configs="" configs=""
...@@ -53,11 +54,12 @@ kversion="" ...@@ -53,11 +54,12 @@ kversion=""
usage () { usage () {
echo "Usage: $scriptname optional arguments:" echo "Usage: $scriptname optional arguments:"
echo " --bootargs kernel-boot-arguments" echo " --bootargs kernel-boot-arguments"
echo " --builddir absolute-pathname" echo " --bootimage relative-path-to-kernel-boot-image"
echo " --buildonly" echo " --buildonly"
echo " --configs \"config-file list\"" echo " --configs \"config-file list\""
echo " --cpus N" echo " --cpus N"
echo " --datestamp string" echo " --datestamp string"
echo " --defconfig string"
echo " --dryrun sched|script" echo " --dryrun sched|script"
echo " --duration minutes" echo " --duration minutes"
echo " --interactive" echo " --interactive"
...@@ -67,7 +69,6 @@ usage () { ...@@ -67,7 +69,6 @@ usage () {
echo " --no-initrd" echo " --no-initrd"
echo " --qemu-args qemu-system-..." echo " --qemu-args qemu-system-..."
echo " --qemu-cmd qemu-system-..." echo " --qemu-cmd qemu-system-..."
echo " --relbuilddir relative-pathname"
echo " --results absolute-pathname" echo " --results absolute-pathname"
echo " --torture rcu" echo " --torture rcu"
exit 1 exit 1
...@@ -78,17 +79,16 @@ do ...@@ -78,17 +79,16 @@ do
case "$1" in case "$1" in
--bootargs) --bootargs)
checkarg --bootargs "(list of kernel boot arguments)" "$#" "$2" '.*' '^--' checkarg --bootargs "(list of kernel boot arguments)" "$#" "$2" '.*' '^--'
RCU_BOOTARGS="$2" TORTURE_BOOTARGS="$2"
shift shift
;; ;;
--builddir) --bootimage)
checkarg --builddir "(absolute pathname)" "$#" "$2" '^/' '^error' checkarg --bootimage "(relative path to kernel boot image)" "$#" "$2" '[a-zA-Z0-9][a-zA-Z0-9_]*' '^--'
builddir=$2 TORTURE_BOOT_IMAGE="$2"
gotbuilddir=1
shift shift
;; ;;
--buildonly) --buildonly)
RCU_BUILDONLY=1; export RCU_BUILDONLY TORTURE_BUILDONLY=1
;; ;;
--configs) --configs)
checkarg --configs "(list of config files)" "$#" "$2" '^[^/]*$' '^--' checkarg --configs "(list of config files)" "$#" "$2" '^[^/]*$' '^--'
...@@ -105,6 +105,11 @@ do ...@@ -105,6 +105,11 @@ do
ds=$2 ds=$2
shift shift
;; ;;
--defconfig)
checkarg --defconfig "defconfigtype" "$#" "$2" '^[^/][^/]*$' '^--'
TORTURE_DEFCONFIG=$2
shift
;;
--dryrun) --dryrun)
checkarg --dryrun "sched|script" $# "$2" 'sched\|script' '^--' checkarg --dryrun "sched|script" $# "$2" 'sched\|script' '^--'
dryrun=$2 dryrun=$2
...@@ -116,11 +121,11 @@ do ...@@ -116,11 +121,11 @@ do
shift shift
;; ;;
--interactive) --interactive)
RCU_QEMU_INTERACTIVE=1; export RCU_QEMU_INTERACTIVE TORTURE_QEMU_INTERACTIVE=1; export TORTURE_QEMU_INTERACTIVE
;; ;;
--kmake-arg) --kmake-arg)
checkarg --kmake-arg "(kernel make arguments)" $# "$2" '.*' '^error$' checkarg --kmake-arg "(kernel make arguments)" $# "$2" '.*' '^error$'
RCU_KMAKE_ARG="$2"; export RCU_KMAKE_ARG TORTURE_KMAKE_ARG="$2"
shift shift
;; ;;
--kversion) --kversion)
...@@ -130,27 +135,20 @@ do ...@@ -130,27 +135,20 @@ do
;; ;;
--mac) --mac)
checkarg --mac "(MAC address)" $# "$2" '^\([0-9a-fA-F]\{2\}:\)\{5\}[0-9a-fA-F]\{2\}$' error checkarg --mac "(MAC address)" $# "$2" '^\([0-9a-fA-F]\{2\}:\)\{5\}[0-9a-fA-F]\{2\}$' error
RCU_QEMU_MAC=$2; export RCU_QEMU_MAC TORTURE_QEMU_MAC=$2
shift shift
;; ;;
--no-initrd) --no-initrd)
RCU_INITRD=""; export RCU_INITRD TORTURE_INITRD=""; export TORTURE_INITRD
;; ;;
--qemu-args) --qemu-args)
checkarg --qemu-args "-qemu args" $# "$2" '^-' '^error' checkarg --qemu-args "-qemu args" $# "$2" '^-' '^error'
RCU_QEMU_ARG="$2" TORTURE_QEMU_ARG="$2"
shift shift
;; ;;
--qemu-cmd) --qemu-cmd)
checkarg --qemu-cmd "(qemu-system-...)" $# "$2" 'qemu-system-' '^--' checkarg --qemu-cmd "(qemu-system-...)" $# "$2" 'qemu-system-' '^--'
RCU_QEMU_CMD="$2"; export RCU_QEMU_CMD TORTURE_QEMU_CMD="$2"
shift
;;
--relbuilddir)
checkarg --relbuilddir "(relative pathname)" "$#" "$2" '^[^/]*$' '^--'
relbuilddir=$2
gotrelbuilddir=1
builddir=${KVM}/${relbuilddir}
shift shift
;; ;;
--results) --results)
...@@ -184,30 +182,6 @@ then ...@@ -184,30 +182,6 @@ then
resdir=$KVM/res resdir=$KVM/res
fi fi
if test "$dryrun" = ""
then
if ! test -e $resdir
then
mkdir -p "$resdir" || :
fi
mkdir $resdir/$ds
# Be noisy only if running the script.
echo Results directory: $resdir/$ds
echo $scriptname $args
touch $resdir/$ds/log
echo $scriptname $args >> $resdir/$ds/log
echo ${TORTURE_SUITE} > $resdir/$ds/TORTURE_SUITE
pwd > $resdir/$ds/testid.txt
if test -d .git
then
git status >> $resdir/$ds/testid.txt
git rev-parse HEAD >> $resdir/$ds/testid.txt
fi
fi
# Create a file of test-name/#cpus pairs, sorted by decreasing #cpus. # Create a file of test-name/#cpus pairs, sorted by decreasing #cpus.
touch $T/cfgcpu touch $T/cfgcpu
for CF in $configs for CF in $configs
...@@ -274,7 +248,39 @@ END { ...@@ -274,7 +248,39 @@ END {
# Generate a script to execute the tests in appropriate batches. # Generate a script to execute the tests in appropriate batches.
cat << ___EOF___ > $T/script cat << ___EOF___ > $T/script
CONFIGFRAG="$CONFIGFRAG"; export CONFIGFRAG
KVM="$KVM"; export KVM
KVPATH="$KVPATH"; export KVPATH
PATH="$PATH"; export PATH
TORTURE_BOOT_IMAGE="$TORTURE_BOOT_IMAGE"; export TORTURE_BOOT_IMAGE
TORTURE_BUILDONLY="$TORTURE_BUILDONLY"; export TORTURE_BUILDONLY
TORTURE_DEFCONFIG="$TORTURE_DEFCONFIG"; export TORTURE_DEFCONFIG
TORTURE_INITRD="$TORTURE_INITRD"; export TORTURE_INITRD
TORTURE_KMAKE_ARG="$TORTURE_KMAKE_ARG"; export TORTURE_KMAKE_ARG
TORTURE_QEMU_CMD="$TORTURE_QEMU_CMD"; export TORTURE_QEMU_CMD
TORTURE_QEMU_INTERACTIVE="$TORTURE_QEMU_INTERACTIVE"; export TORTURE_QEMU_INTERACTIVE
TORTURE_QEMU_MAC="$TORTURE_QEMU_MAC"; export TORTURE_QEMU_MAC
TORTURE_SUITE="$TORTURE_SUITE"; export TORTURE_SUITE TORTURE_SUITE="$TORTURE_SUITE"; export TORTURE_SUITE
if ! test -e $resdir
then
mkdir -p "$resdir" || :
fi
mkdir $resdir/$ds
echo Results directory: $resdir/$ds
echo $scriptname $args
touch $resdir/$ds/log
echo $scriptname $args >> $resdir/$ds/log
echo ${TORTURE_SUITE} > $resdir/$ds/TORTURE_SUITE
pwd > $resdir/$ds/testid.txt
if test -d .git
then
git status >> $resdir/$ds/testid.txt
git rev-parse HEAD >> $resdir/$ds/testid.txt
if ! git diff HEAD > $T/git-diff 2>&1
then
cp $T/git-diff $resdir/$ds
fi
fi
___EOF___ ___EOF___
awk < $T/cfgcpu.pack \ awk < $T/cfgcpu.pack \
-v CONFIGDIR="$CONFIGFRAG/$kversion/" \ -v CONFIGDIR="$CONFIGFRAG/$kversion/" \
...@@ -282,8 +288,8 @@ awk < $T/cfgcpu.pack \ ...@@ -282,8 +288,8 @@ awk < $T/cfgcpu.pack \
-v ncpus=$cpus \ -v ncpus=$cpus \
-v rd=$resdir/$ds/ \ -v rd=$resdir/$ds/ \
-v dur=$dur \ -v dur=$dur \
-v RCU_QEMU_ARG=$RCU_QEMU_ARG \ -v TORTURE_QEMU_ARG="$TORTURE_QEMU_ARG" \
-v RCU_BOOTARGS=$RCU_BOOTARGS \ -v TORTURE_BOOTARGS="$TORTURE_BOOTARGS" \
'BEGIN { 'BEGIN {
i = 0; i = 0;
} }
...@@ -320,7 +326,7 @@ function dump(first, pastlast) ...@@ -320,7 +326,7 @@ function dump(first, pastlast)
print "touch " builddir ".wait"; print "touch " builddir ".wait";
print "mkdir " builddir " > /dev/null 2>&1 || :"; print "mkdir " builddir " > /dev/null 2>&1 || :";
print "mkdir " rd cfr[jn] " || :"; print "mkdir " rd cfr[jn] " || :";
print "kvm-test-1-run.sh " CONFIGDIR cf[j], builddir, rd cfr[jn], dur " \"" RCU_QEMU_ARG "\" \"" RCU_BOOTARGS "\" > " rd cfr[jn] "/kvm-test-1-run.sh.out 2>&1 &" print "kvm-test-1-run.sh " CONFIGDIR cf[j], builddir, rd cfr[jn], dur " \"" TORTURE_QEMU_ARG "\" \"" TORTURE_BOOTARGS "\" > " rd cfr[jn] "/kvm-test-1-run.sh.out 2>&1 &"
print "echo ", cfr[jn], cpusr[jn] ovf ": Waiting for build to complete. `date`"; print "echo ", cfr[jn], cpusr[jn] ovf ": Waiting for build to complete. `date`";
print "echo ", cfr[jn], cpusr[jn] ovf ": Waiting for build to complete. `date` >> " rd "/log"; print "echo ", cfr[jn], cpusr[jn] ovf ": Waiting for build to complete. `date` >> " rd "/log";
print "while test -f " builddir ".wait" print "while test -f " builddir ".wait"
...@@ -374,28 +380,26 @@ END { ...@@ -374,28 +380,26 @@ END {
dump(first, i); dump(first, i);
}' >> $T/script }' >> $T/script
cat << ___EOF___ >> $T/script
echo
echo
echo " --- `date` Test summary:"
echo Results directory: $resdir/$ds
if test -z "$TORTURE_BUILDONLY"
then
kvm-recheck.sh $resdir/$ds
fi
___EOF___
if test "$dryrun" = script if test "$dryrun" = script
then then
# Dump out the script, but define the environment variables that
# it needs to run standalone.
echo CONFIGFRAG="$CONFIGFRAG; export CONFIGFRAG"
echo KVM="$KVM; export KVM"
echo KVPATH="$KVPATH; export KVPATH"
echo PATH="$PATH; export PATH"
echo RCU_BUILDONLY="$RCU_BUILDONLY; export RCU_BUILDONLY"
echo RCU_INITRD="$RCU_INITRD; export RCU_INITRD"
echo RCU_KMAKE_ARG="$RCU_KMAKE_ARG; export RCU_KMAKE_ARG"
echo RCU_QEMU_CMD="$RCU_QEMU_CMD; export RCU_QEMU_CMD"
echo RCU_QEMU_INTERACTIVE="$RCU_QEMU_INTERACTIVE; export RCU_QEMU_INTERACTIVE"
echo RCU_QEMU_MAC="$RCU_QEMU_MAC; export RCU_QEMU_MAC"
echo "mkdir -p "$resdir" || :"
echo "mkdir $resdir/$ds"
cat $T/script cat $T/script
exit 0 exit 0
elif test "$dryrun" = sched elif test "$dryrun" = sched
then then
# Extract the test run schedule from the script. # Extract the test run schedule from the script.
egrep 'start batch|Starting build\.' $T/script | egrep 'Start batch|Starting build\.' $T/script |
grep -v ">>" |
sed -e 's/:.*$//' -e 's/^echo //' sed -e 's/:.*$//' -e 's/^echo //'
exit 0 exit 0
else else
...@@ -404,9 +408,3 @@ else ...@@ -404,9 +408,3 @@ else
fi fi
# Tracing: trace_event=rcu:rcu_grace_period,rcu:rcu_future_grace_period,rcu:rcu_grace_period_init,rcu:rcu_nocb_wake,rcu:rcu_preempt_task,rcu:rcu_unlock_preempted_task,rcu:rcu_quiescent_state_report,rcu:rcu_fqs,rcu:rcu_callback,rcu:rcu_kfree_callback,rcu:rcu_batch_start,rcu:rcu_invoke_callback,rcu:rcu_invoke_kfree_callback,rcu:rcu_batch_end,rcu:rcu_torture_read,rcu:rcu_barrier # Tracing: trace_event=rcu:rcu_grace_period,rcu:rcu_future_grace_period,rcu:rcu_grace_period_init,rcu:rcu_nocb_wake,rcu:rcu_preempt_task,rcu:rcu_unlock_preempted_task,rcu:rcu_quiescent_state_report,rcu:rcu_fqs,rcu:rcu_callback,rcu:rcu_kfree_callback,rcu:rcu_batch_start,rcu:rcu_invoke_callback,rcu:rcu_invoke_kfree_callback,rcu:rcu_batch_end,rcu:rcu_torture_read,rcu:rcu_barrier
echo
echo
echo " --- `date` Test summary:"
echo Results directory: $resdir/$ds
kvm-recheck.sh $resdir/$ds
#!/bin/sh #!/bin/sh
# #
# Check the console output from an rcutorture run for goodness. # Check the console output from a torture run for goodness.
# The "file" is a pathname on the local system, and "title" is # The "file" is a pathname on the local system, and "title" is
# a text string for error-message purposes. # a text string for error-message purposes.
# #
# The file must contain rcutorture output, but can be interspersed # The file must contain torture output, but can be interspersed
# with other dmesg text. # with other dmesg text, as in console-log output.
# #
# Usage: # Usage:
# sh parse-rcutorture.sh file title # sh parse-torture.sh file title
# #
# This program is free software; you can redistribute it and/or modify # 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 # it under the terms of the GNU General Public License as published by
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
# #
# Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com> # Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
T=/tmp/parse-rcutorture.sh.$$ T=/tmp/parse-torture.sh.$$
file="$1" file="$1"
title="$2" title="$2"
...@@ -36,13 +36,13 @@ trap 'rm -f $T.seq' 0 ...@@ -36,13 +36,13 @@ trap 'rm -f $T.seq' 0
. functions.sh . functions.sh
# check for presence of rcutorture.txt file # check for presence of torture output file.
if test -f "$file" -a -r "$file" if test -f "$file" -a -r "$file"
then then
: :
else else
echo $title unreadable rcutorture.txt file: $file echo $title unreadable torture output file: $file
exit 1 exit 1
fi fi
...@@ -76,9 +76,9 @@ BEGIN { ...@@ -76,9 +76,9 @@ BEGIN {
END { END {
if (badseq) { if (badseq) {
if (badseqno1 == badseqno2 && badseqno2 == ver) if (badseqno1 == badseqno2 && badseqno2 == ver)
print "RCU GP HANG at " ver " rcutorture stat " badseqnr; print "GP HANG at " ver " torture stat " badseqnr;
else else
print "BAD SEQ " badseqno1 ":" badseqno2 " last:" ver " RCU version " badseqnr; print "BAD SEQ " badseqno1 ":" badseqno2 " last:" ver " version " badseqnr;
} }
}' > $T.seq }' > $T.seq
...@@ -91,13 +91,13 @@ then ...@@ -91,13 +91,13 @@ then
exit 2 exit 2
fi fi
else else
if grep -q RCU_HOTPLUG $file if grep -q "_HOTPLUG:" $file
then then
print_warning HOTPLUG FAILURES $title `cat $T.seq` print_warning HOTPLUG FAILURES $title `cat $T.seq`
echo " " $file echo " " $file
exit 3 exit 3
fi fi
echo $title no success message, `grep --binary-files=text 'ver:' $file | wc -l` successful RCU version messages echo $title no success message, `grep --binary-files=text 'ver:' $file | wc -l` successful version messages
if test -s $T.seq if test -s $T.seq
then then
print_warning $title `cat $T.seq` print_warning $title `cat $T.seq`
......
CONFIG_SMP=y
CONFIG_NR_CPUS=8
CONFIG_PREEMPT_NONE=n
CONFIG_PREEMPT_VOLUNTARY=n
CONFIG_PREEMPT=y
#CHECK#CONFIG_TREE_PREEMPT_RCU=y
CONFIG_HZ_PERIODIC=n
CONFIG_NO_HZ_IDLE=y
CONFIG_NO_HZ_FULL=n
CONFIG_RCU_FAST_NO_HZ=n
CONFIG_RCU_TRACE=y
CONFIG_HOTPLUG_CPU=n
CONFIG_SUSPEND=n
CONFIG_HIBERNATION=n
CONFIG_RCU_FANOUT=3
CONFIG_RCU_FANOUT_LEAF=3
CONFIG_RCU_FANOUT_EXACT=n
CONFIG_RCU_NOCB_CPU=n
CONFIG_DEBUG_LOCK_ALLOC=y
CONFIG_PROVE_LOCKING=n
CONFIG_PROVE_RCU_DELAY=n
CONFIG_RCU_CPU_STALL_INFO=n
CONFIG_RCU_CPU_STALL_VERBOSE=y
CONFIG_RCU_BOOST=n
CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment