Merge branches 'fixes.2018.02.23a', 'srcu.2018.02.20a' and 'torture.2018.02.20a' into HEAD
fixes.2018.02.23a: Miscellaneous fixes srcu.2018.02.20a: SRCU updates torture.2018.02.20a: Torture-test updates
This commit is contained in:
commit
338c46403f
@ -61,11 +61,30 @@ MODULE_AUTHOR("Paul E. McKenney <paulmck@linux.vnet.ibm.com>");
|
|||||||
#define VERBOSE_PERFOUT_ERRSTRING(s) \
|
#define VERBOSE_PERFOUT_ERRSTRING(s) \
|
||||||
do { if (verbose) pr_alert("%s" PERF_FLAG "!!! %s\n", perf_type, s); } while (0)
|
do { if (verbose) pr_alert("%s" PERF_FLAG "!!! %s\n", perf_type, s); } while (0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The intended use cases for the nreaders and nwriters module parameters
|
||||||
|
* are as follows:
|
||||||
|
*
|
||||||
|
* 1. Specify only the nr_cpus kernel boot parameter. This will
|
||||||
|
* set both nreaders and nwriters to the value specified by
|
||||||
|
* nr_cpus for a mixed reader/writer test.
|
||||||
|
*
|
||||||
|
* 2. Specify the nr_cpus kernel boot parameter, but set
|
||||||
|
* rcuperf.nreaders to zero. This will set nwriters to the
|
||||||
|
* value specified by nr_cpus for an update-only test.
|
||||||
|
*
|
||||||
|
* 3. Specify the nr_cpus kernel boot parameter, but set
|
||||||
|
* rcuperf.nwriters to zero. This will set nreaders to the
|
||||||
|
* value specified by nr_cpus for a read-only test.
|
||||||
|
*
|
||||||
|
* Various other use cases may of course be specified.
|
||||||
|
*/
|
||||||
|
|
||||||
torture_param(bool, gp_async, false, "Use asynchronous GP wait primitives");
|
torture_param(bool, gp_async, false, "Use asynchronous GP wait primitives");
|
||||||
torture_param(int, gp_async_max, 1000, "Max # outstanding waits per reader");
|
torture_param(int, gp_async_max, 1000, "Max # outstanding waits per reader");
|
||||||
torture_param(bool, gp_exp, false, "Use expedited GP wait primitives");
|
torture_param(bool, gp_exp, false, "Use expedited GP wait primitives");
|
||||||
torture_param(int, holdoff, 10, "Holdoff time before test start (s)");
|
torture_param(int, holdoff, 10, "Holdoff time before test start (s)");
|
||||||
torture_param(int, nreaders, 0, "Number of RCU reader threads");
|
torture_param(int, nreaders, -1, "Number of RCU reader threads");
|
||||||
torture_param(int, nwriters, -1, "Number of RCU updater threads");
|
torture_param(int, nwriters, -1, "Number of RCU updater threads");
|
||||||
torture_param(bool, shutdown, !IS_ENABLED(MODULE),
|
torture_param(bool, shutdown, !IS_ENABLED(MODULE),
|
||||||
"Shutdown at end of performance tests.");
|
"Shutdown at end of performance tests.");
|
||||||
|
@ -909,34 +909,38 @@ rcu_torture_writer(void *arg)
|
|||||||
int nsynctypes = 0;
|
int nsynctypes = 0;
|
||||||
|
|
||||||
VERBOSE_TOROUT_STRING("rcu_torture_writer task started");
|
VERBOSE_TOROUT_STRING("rcu_torture_writer task started");
|
||||||
if (!can_expedite) {
|
if (!can_expedite)
|
||||||
pr_alert("%s" TORTURE_FLAG
|
pr_alert("%s" TORTURE_FLAG
|
||||||
" GP expediting controlled from boot/sysfs for %s,\n",
|
" GP expediting controlled from boot/sysfs for %s.\n",
|
||||||
torture_type, cur_ops->name);
|
torture_type, cur_ops->name);
|
||||||
pr_alert("%s" TORTURE_FLAG
|
|
||||||
" Disabled dynamic grace-period expediting.\n",
|
|
||||||
torture_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize synctype[] array. If none set, take default. */
|
/* Initialize synctype[] array. If none set, take default. */
|
||||||
if (!gp_cond1 && !gp_exp1 && !gp_normal1 && !gp_sync1)
|
if (!gp_cond1 && !gp_exp1 && !gp_normal1 && !gp_sync1)
|
||||||
gp_cond1 = gp_exp1 = gp_normal1 = gp_sync1 = true;
|
gp_cond1 = gp_exp1 = gp_normal1 = gp_sync1 = true;
|
||||||
if (gp_cond1 && cur_ops->get_state && cur_ops->cond_sync)
|
if (gp_cond1 && cur_ops->get_state && cur_ops->cond_sync) {
|
||||||
synctype[nsynctypes++] = RTWS_COND_GET;
|
synctype[nsynctypes++] = RTWS_COND_GET;
|
||||||
else if (gp_cond && (!cur_ops->get_state || !cur_ops->cond_sync))
|
pr_info("%s: Testing conditional GPs.\n", __func__);
|
||||||
pr_alert("rcu_torture_writer: gp_cond without primitives.\n");
|
} else if (gp_cond && (!cur_ops->get_state || !cur_ops->cond_sync)) {
|
||||||
if (gp_exp1 && cur_ops->exp_sync)
|
pr_alert("%s: gp_cond without primitives.\n", __func__);
|
||||||
|
}
|
||||||
|
if (gp_exp1 && cur_ops->exp_sync) {
|
||||||
synctype[nsynctypes++] = RTWS_EXP_SYNC;
|
synctype[nsynctypes++] = RTWS_EXP_SYNC;
|
||||||
else if (gp_exp && !cur_ops->exp_sync)
|
pr_info("%s: Testing expedited GPs.\n", __func__);
|
||||||
pr_alert("rcu_torture_writer: gp_exp without primitives.\n");
|
} else if (gp_exp && !cur_ops->exp_sync) {
|
||||||
if (gp_normal1 && cur_ops->deferred_free)
|
pr_alert("%s: gp_exp without primitives.\n", __func__);
|
||||||
|
}
|
||||||
|
if (gp_normal1 && cur_ops->deferred_free) {
|
||||||
synctype[nsynctypes++] = RTWS_DEF_FREE;
|
synctype[nsynctypes++] = RTWS_DEF_FREE;
|
||||||
else if (gp_normal && !cur_ops->deferred_free)
|
pr_info("%s: Testing asynchronous GPs.\n", __func__);
|
||||||
pr_alert("rcu_torture_writer: gp_normal without primitives.\n");
|
} else if (gp_normal && !cur_ops->deferred_free) {
|
||||||
if (gp_sync1 && cur_ops->sync)
|
pr_alert("%s: gp_normal without primitives.\n", __func__);
|
||||||
|
}
|
||||||
|
if (gp_sync1 && cur_ops->sync) {
|
||||||
synctype[nsynctypes++] = RTWS_SYNC;
|
synctype[nsynctypes++] = RTWS_SYNC;
|
||||||
else if (gp_sync && !cur_ops->sync)
|
pr_info("%s: Testing normal GPs.\n", __func__);
|
||||||
pr_alert("rcu_torture_writer: gp_sync without primitives.\n");
|
} else if (gp_sync && !cur_ops->sync) {
|
||||||
|
pr_alert("%s: gp_sync without primitives.\n", __func__);
|
||||||
|
}
|
||||||
if (WARN_ONCE(nsynctypes == 0,
|
if (WARN_ONCE(nsynctypes == 0,
|
||||||
"rcu_torture_writer: No update-side primitives.\n")) {
|
"rcu_torture_writer: No update-side primitives.\n")) {
|
||||||
/*
|
/*
|
||||||
@ -1011,6 +1015,9 @@ rcu_torture_writer(void *arg)
|
|||||||
rcu_unexpedite_gp();
|
rcu_unexpedite_gp();
|
||||||
if (++expediting > 3)
|
if (++expediting > 3)
|
||||||
expediting = -expediting;
|
expediting = -expediting;
|
||||||
|
} else if (!can_expedite) { /* Disabled during boot, recheck. */
|
||||||
|
can_expedite = !rcu_gp_is_expedited() &&
|
||||||
|
!rcu_gp_is_normal();
|
||||||
}
|
}
|
||||||
rcu_torture_writer_state = RTWS_STUTTER;
|
rcu_torture_writer_state = RTWS_STUTTER;
|
||||||
stutter_wait("rcu_torture_writer");
|
stutter_wait("rcu_torture_writer");
|
||||||
@ -1021,6 +1028,10 @@ rcu_torture_writer(void *arg)
|
|||||||
while (can_expedite && expediting++ < 0)
|
while (can_expedite && expediting++ < 0)
|
||||||
rcu_unexpedite_gp();
|
rcu_unexpedite_gp();
|
||||||
WARN_ON_ONCE(can_expedite && rcu_gp_is_expedited());
|
WARN_ON_ONCE(can_expedite && rcu_gp_is_expedited());
|
||||||
|
if (!can_expedite)
|
||||||
|
pr_alert("%s" TORTURE_FLAG
|
||||||
|
" Dynamic grace-period expediting was disabled.\n",
|
||||||
|
torture_type);
|
||||||
rcu_torture_writer_state = RTWS_STOPPING;
|
rcu_torture_writer_state = RTWS_STOPPING;
|
||||||
torture_kthread_stopping("rcu_torture_writer");
|
torture_kthread_stopping("rcu_torture_writer");
|
||||||
return 0;
|
return 0;
|
||||||
@ -1045,13 +1056,13 @@ rcu_torture_fakewriter(void *arg)
|
|||||||
torture_random(&rand) % (nfakewriters * 8) == 0) {
|
torture_random(&rand) % (nfakewriters * 8) == 0) {
|
||||||
cur_ops->cb_barrier();
|
cur_ops->cb_barrier();
|
||||||
} else if (gp_normal == gp_exp) {
|
} else if (gp_normal == gp_exp) {
|
||||||
if (torture_random(&rand) & 0x80)
|
if (cur_ops->sync && torture_random(&rand) & 0x80)
|
||||||
cur_ops->sync();
|
cur_ops->sync();
|
||||||
else
|
else if (cur_ops->exp_sync)
|
||||||
cur_ops->exp_sync();
|
cur_ops->exp_sync();
|
||||||
} else if (gp_normal) {
|
} else if (gp_normal && cur_ops->sync) {
|
||||||
cur_ops->sync();
|
cur_ops->sync();
|
||||||
} else {
|
} else if (cur_ops->exp_sync) {
|
||||||
cur_ops->exp_sync();
|
cur_ops->exp_sync();
|
||||||
}
|
}
|
||||||
stutter_wait("rcu_torture_fakewriter");
|
stutter_wait("rcu_torture_fakewriter");
|
||||||
@ -1557,11 +1568,10 @@ static int rcu_torture_barrier_init(void)
|
|||||||
atomic_set(&barrier_cbs_count, 0);
|
atomic_set(&barrier_cbs_count, 0);
|
||||||
atomic_set(&barrier_cbs_invoked, 0);
|
atomic_set(&barrier_cbs_invoked, 0);
|
||||||
barrier_cbs_tasks =
|
barrier_cbs_tasks =
|
||||||
kzalloc(n_barrier_cbs * sizeof(barrier_cbs_tasks[0]),
|
kcalloc(n_barrier_cbs, sizeof(barrier_cbs_tasks[0]),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
barrier_cbs_wq =
|
barrier_cbs_wq =
|
||||||
kzalloc(n_barrier_cbs * sizeof(barrier_cbs_wq[0]),
|
kcalloc(n_barrier_cbs, sizeof(barrier_cbs_wq[0]), GFP_KERNEL);
|
||||||
GFP_KERNEL);
|
|
||||||
if (barrier_cbs_tasks == NULL || !barrier_cbs_wq)
|
if (barrier_cbs_tasks == NULL || !barrier_cbs_wq)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
for (i = 0; i < n_barrier_cbs; i++) {
|
for (i = 0; i < n_barrier_cbs; i++) {
|
||||||
@ -1674,7 +1684,7 @@ static void rcu_torture_err_cb(struct rcu_head *rhp)
|
|||||||
* next grace period. Unlikely, but can happen. If it
|
* next grace period. Unlikely, but can happen. If it
|
||||||
* does happen, the debug-objects subsystem won't have splatted.
|
* does happen, the debug-objects subsystem won't have splatted.
|
||||||
*/
|
*/
|
||||||
pr_alert("rcutorture: duplicated callback was invoked.\n");
|
pr_alert("%s: duplicated callback was invoked.\n", KBUILD_MODNAME);
|
||||||
}
|
}
|
||||||
#endif /* #ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD */
|
#endif /* #ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD */
|
||||||
|
|
||||||
@ -1691,7 +1701,7 @@ static void rcu_test_debug_objects(void)
|
|||||||
|
|
||||||
init_rcu_head_on_stack(&rh1);
|
init_rcu_head_on_stack(&rh1);
|
||||||
init_rcu_head_on_stack(&rh2);
|
init_rcu_head_on_stack(&rh2);
|
||||||
pr_alert("rcutorture: WARN: Duplicate call_rcu() test starting.\n");
|
pr_alert("%s: WARN: Duplicate call_rcu() test starting.\n", KBUILD_MODNAME);
|
||||||
|
|
||||||
/* Try to queue the rh2 pair of callbacks for the same grace period. */
|
/* Try to queue the rh2 pair of callbacks for the same grace period. */
|
||||||
preempt_disable(); /* Prevent preemption from interrupting test. */
|
preempt_disable(); /* Prevent preemption from interrupting test. */
|
||||||
@ -1706,11 +1716,11 @@ static void rcu_test_debug_objects(void)
|
|||||||
|
|
||||||
/* Wait for them all to get done so we can safely return. */
|
/* Wait for them all to get done so we can safely return. */
|
||||||
rcu_barrier();
|
rcu_barrier();
|
||||||
pr_alert("rcutorture: WARN: Duplicate call_rcu() test complete.\n");
|
pr_alert("%s: WARN: Duplicate call_rcu() test complete.\n", KBUILD_MODNAME);
|
||||||
destroy_rcu_head_on_stack(&rh1);
|
destroy_rcu_head_on_stack(&rh1);
|
||||||
destroy_rcu_head_on_stack(&rh2);
|
destroy_rcu_head_on_stack(&rh2);
|
||||||
#else /* #ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD */
|
#else /* #ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD */
|
||||||
pr_alert("rcutorture: !CONFIG_DEBUG_OBJECTS_RCU_HEAD, not testing duplicate call_rcu()\n");
|
pr_alert("%s: !CONFIG_DEBUG_OBJECTS_RCU_HEAD, not testing duplicate call_rcu()\n", KBUILD_MODNAME);
|
||||||
#endif /* #else #ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD */
|
#endif /* #else #ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1799,7 +1809,7 @@ rcu_torture_init(void)
|
|||||||
if (firsterr)
|
if (firsterr)
|
||||||
goto unwind;
|
goto unwind;
|
||||||
if (nfakewriters > 0) {
|
if (nfakewriters > 0) {
|
||||||
fakewriter_tasks = kzalloc(nfakewriters *
|
fakewriter_tasks = kcalloc(nfakewriters,
|
||||||
sizeof(fakewriter_tasks[0]),
|
sizeof(fakewriter_tasks[0]),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (fakewriter_tasks == NULL) {
|
if (fakewriter_tasks == NULL) {
|
||||||
@ -1814,7 +1824,7 @@ rcu_torture_init(void)
|
|||||||
if (firsterr)
|
if (firsterr)
|
||||||
goto unwind;
|
goto unwind;
|
||||||
}
|
}
|
||||||
reader_tasks = kzalloc(nrealreaders * sizeof(reader_tasks[0]),
|
reader_tasks = kcalloc(nrealreaders, sizeof(reader_tasks[0]),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (reader_tasks == NULL) {
|
if (reader_tasks == NULL) {
|
||||||
VERBOSE_TOROUT_ERRSTRING("out of memory");
|
VERBOSE_TOROUT_ERRSTRING("out of memory");
|
||||||
|
@ -386,7 +386,7 @@ void cleanup_srcu_struct(struct srcu_struct *sp)
|
|||||||
flush_delayed_work(&per_cpu_ptr(sp->sda, cpu)->work);
|
flush_delayed_work(&per_cpu_ptr(sp->sda, cpu)->work);
|
||||||
if (WARN_ON(rcu_seq_state(READ_ONCE(sp->srcu_gp_seq)) != SRCU_STATE_IDLE) ||
|
if (WARN_ON(rcu_seq_state(READ_ONCE(sp->srcu_gp_seq)) != SRCU_STATE_IDLE) ||
|
||||||
WARN_ON(srcu_readers_active(sp))) {
|
WARN_ON(srcu_readers_active(sp))) {
|
||||||
pr_info("cleanup_srcu_struct: Active srcu_struct %p state: %d\n", sp, rcu_seq_state(READ_ONCE(sp->srcu_gp_seq)));
|
pr_info("%s: Active srcu_struct %p state: %d\n", __func__, sp, rcu_seq_state(READ_ONCE(sp->srcu_gp_seq)));
|
||||||
return; /* Caller forgot to stop doing call_srcu()? */
|
return; /* Caller forgot to stop doing call_srcu()? */
|
||||||
}
|
}
|
||||||
free_percpu(sp->sda);
|
free_percpu(sp->sda);
|
||||||
@ -526,11 +526,11 @@ static void srcu_gp_end(struct srcu_struct *sp)
|
|||||||
{
|
{
|
||||||
unsigned long cbdelay;
|
unsigned long cbdelay;
|
||||||
bool cbs;
|
bool cbs;
|
||||||
|
bool last_lvl;
|
||||||
int cpu;
|
int cpu;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
unsigned long gpseq;
|
unsigned long gpseq;
|
||||||
int idx;
|
int idx;
|
||||||
int idxnext;
|
|
||||||
unsigned long mask;
|
unsigned long mask;
|
||||||
struct srcu_data *sdp;
|
struct srcu_data *sdp;
|
||||||
struct srcu_node *snp;
|
struct srcu_node *snp;
|
||||||
@ -554,11 +554,11 @@ static void srcu_gp_end(struct srcu_struct *sp)
|
|||||||
|
|
||||||
/* Initiate callback invocation as needed. */
|
/* Initiate callback invocation as needed. */
|
||||||
idx = rcu_seq_ctr(gpseq) % ARRAY_SIZE(snp->srcu_have_cbs);
|
idx = rcu_seq_ctr(gpseq) % ARRAY_SIZE(snp->srcu_have_cbs);
|
||||||
idxnext = (idx + 1) % ARRAY_SIZE(snp->srcu_have_cbs);
|
|
||||||
rcu_for_each_node_breadth_first(sp, snp) {
|
rcu_for_each_node_breadth_first(sp, snp) {
|
||||||
spin_lock_irq_rcu_node(snp);
|
spin_lock_irq_rcu_node(snp);
|
||||||
cbs = false;
|
cbs = false;
|
||||||
if (snp >= sp->level[rcu_num_lvls - 1])
|
last_lvl = snp >= sp->level[rcu_num_lvls - 1];
|
||||||
|
if (last_lvl)
|
||||||
cbs = snp->srcu_have_cbs[idx] == gpseq;
|
cbs = snp->srcu_have_cbs[idx] == gpseq;
|
||||||
snp->srcu_have_cbs[idx] = gpseq;
|
snp->srcu_have_cbs[idx] = gpseq;
|
||||||
rcu_seq_set_state(&snp->srcu_have_cbs[idx], 1);
|
rcu_seq_set_state(&snp->srcu_have_cbs[idx], 1);
|
||||||
@ -571,13 +571,16 @@ static void srcu_gp_end(struct srcu_struct *sp)
|
|||||||
srcu_schedule_cbs_snp(sp, snp, mask, cbdelay);
|
srcu_schedule_cbs_snp(sp, snp, mask, cbdelay);
|
||||||
|
|
||||||
/* Occasionally prevent srcu_data counter wrap. */
|
/* Occasionally prevent srcu_data counter wrap. */
|
||||||
if (!(gpseq & counter_wrap_check))
|
if (!(gpseq & counter_wrap_check) && last_lvl)
|
||||||
for (cpu = snp->grplo; cpu <= snp->grphi; cpu++) {
|
for (cpu = snp->grplo; cpu <= snp->grphi; cpu++) {
|
||||||
sdp = per_cpu_ptr(sp->sda, cpu);
|
sdp = per_cpu_ptr(sp->sda, cpu);
|
||||||
spin_lock_irqsave_rcu_node(sdp, flags);
|
spin_lock_irqsave_rcu_node(sdp, flags);
|
||||||
if (ULONG_CMP_GE(gpseq,
|
if (ULONG_CMP_GE(gpseq,
|
||||||
sdp->srcu_gp_seq_needed + 100))
|
sdp->srcu_gp_seq_needed + 100))
|
||||||
sdp->srcu_gp_seq_needed = gpseq;
|
sdp->srcu_gp_seq_needed = gpseq;
|
||||||
|
if (ULONG_CMP_GE(gpseq,
|
||||||
|
sdp->srcu_gp_seq_needed_exp + 100))
|
||||||
|
sdp->srcu_gp_seq_needed_exp = gpseq;
|
||||||
spin_unlock_irqrestore_rcu_node(sdp, flags);
|
spin_unlock_irqrestore_rcu_node(sdp, flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -592,9 +595,7 @@ static void srcu_gp_end(struct srcu_struct *sp)
|
|||||||
ULONG_CMP_LT(gpseq, sp->srcu_gp_seq_needed)) {
|
ULONG_CMP_LT(gpseq, sp->srcu_gp_seq_needed)) {
|
||||||
srcu_gp_start(sp);
|
srcu_gp_start(sp);
|
||||||
spin_unlock_irq_rcu_node(sp);
|
spin_unlock_irq_rcu_node(sp);
|
||||||
/* Throttle expedited grace periods: Should be rare! */
|
srcu_reschedule(sp, 0);
|
||||||
srcu_reschedule(sp, rcu_seq_ctr(gpseq) & 0x3ff
|
|
||||||
? 0 : SRCU_INTERVAL);
|
|
||||||
} else {
|
} else {
|
||||||
spin_unlock_irq_rcu_node(sp);
|
spin_unlock_irq_rcu_node(sp);
|
||||||
}
|
}
|
||||||
|
@ -136,6 +136,9 @@ identify_boot_image () {
|
|||||||
qemu-system-x86_64|qemu-system-i386)
|
qemu-system-x86_64|qemu-system-i386)
|
||||||
echo arch/x86/boot/bzImage
|
echo arch/x86/boot/bzImage
|
||||||
;;
|
;;
|
||||||
|
qemu-system-aarch64)
|
||||||
|
echo arch/arm64/boot/Image
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
echo vmlinux
|
echo vmlinux
|
||||||
;;
|
;;
|
||||||
@ -158,6 +161,9 @@ identify_qemu () {
|
|||||||
elif echo $u | grep -q "Intel 80386"
|
elif echo $u | grep -q "Intel 80386"
|
||||||
then
|
then
|
||||||
echo qemu-system-i386
|
echo qemu-system-i386
|
||||||
|
elif echo $u | grep -q aarch64
|
||||||
|
then
|
||||||
|
echo qemu-system-aarch64
|
||||||
elif uname -a | grep -q ppc64
|
elif uname -a | grep -q ppc64
|
||||||
then
|
then
|
||||||
echo qemu-system-ppc64
|
echo qemu-system-ppc64
|
||||||
@ -176,16 +182,20 @@ identify_qemu () {
|
|||||||
# Output arguments for the qemu "-append" string based on CPU type
|
# Output arguments for the qemu "-append" string based on CPU type
|
||||||
# and the TORTURE_QEMU_INTERACTIVE environment variable.
|
# and the TORTURE_QEMU_INTERACTIVE environment variable.
|
||||||
identify_qemu_append () {
|
identify_qemu_append () {
|
||||||
|
local console=ttyS0
|
||||||
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
|
||||||
;;
|
;;
|
||||||
|
qemu-system-aarch64)
|
||||||
|
console=ttyAMA0
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
if test -n "$TORTURE_QEMU_INTERACTIVE"
|
if test -n "$TORTURE_QEMU_INTERACTIVE"
|
||||||
then
|
then
|
||||||
echo root=/dev/sda
|
echo root=/dev/sda
|
||||||
else
|
else
|
||||||
echo console=ttyS0
|
echo console=$console
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,6 +207,9 @@ identify_qemu_args () {
|
|||||||
case "$1" in
|
case "$1" in
|
||||||
qemu-system-x86_64|qemu-system-i386)
|
qemu-system-x86_64|qemu-system-i386)
|
||||||
;;
|
;;
|
||||||
|
qemu-system-aarch64)
|
||||||
|
echo -machine virt,gic-version=host -cpu host
|
||||||
|
;;
|
||||||
qemu-system-ppc64)
|
qemu-system-ppc64)
|
||||||
echo -enable-kvm -M pseries -nodefaults
|
echo -enable-kvm -M pseries -nodefaults
|
||||||
echo -device spapr-vscsi
|
echo -device spapr-vscsi
|
||||||
@ -254,7 +267,7 @@ specify_qemu_cpus () {
|
|||||||
echo $2
|
echo $2
|
||||||
else
|
else
|
||||||
case "$1" in
|
case "$1" in
|
||||||
qemu-system-x86_64|qemu-system-i386)
|
qemu-system-x86_64|qemu-system-i386|qemu-system-aarch64)
|
||||||
echo $2 -smp $3
|
echo $2 -smp $3
|
||||||
;;
|
;;
|
||||||
qemu-system-ppc64)
|
qemu-system-ppc64)
|
||||||
|
@ -39,30 +39,31 @@ sed -e 's/us : / : /' |
|
|||||||
tr -d '\015' |
|
tr -d '\015' |
|
||||||
awk '
|
awk '
|
||||||
$8 == "start" {
|
$8 == "start" {
|
||||||
if (starttask != "")
|
if (startseq != "")
|
||||||
nlost++;
|
nlost++;
|
||||||
starttask = $1;
|
starttask = $1;
|
||||||
starttime = $3;
|
starttime = $3;
|
||||||
startseq = $7;
|
startseq = $7;
|
||||||
|
seqtask[startseq] = starttask;
|
||||||
}
|
}
|
||||||
|
|
||||||
$8 == "end" {
|
$8 == "end" {
|
||||||
if (starttask == $1 && startseq == $7) {
|
if (startseq == $7) {
|
||||||
curgpdur = $3 - starttime;
|
curgpdur = $3 - starttime;
|
||||||
gptimes[++n] = curgpdur;
|
gptimes[++n] = curgpdur;
|
||||||
gptaskcnt[starttask]++;
|
gptaskcnt[starttask]++;
|
||||||
sum += curgpdur;
|
sum += curgpdur;
|
||||||
if (curgpdur > 1000)
|
if (curgpdur > 1000)
|
||||||
print "Long GP " starttime "us to " $3 "us (" curgpdur "us)";
|
print "Long GP " starttime "us to " $3 "us (" curgpdur "us)";
|
||||||
starttask = "";
|
startseq = "";
|
||||||
} else {
|
} else {
|
||||||
# Lost a message or some such, reset.
|
# Lost a message or some such, reset.
|
||||||
starttask = "";
|
startseq = "";
|
||||||
nlost++;
|
nlost++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$8 == "done" {
|
$8 == "done" && seqtask[$7] != $1 {
|
||||||
piggybackcnt[$1]++;
|
piggybackcnt[$1]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,8 +177,8 @@ then
|
|||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
echo "NOTE: $QEMU either did not run or was interactive" > $resdir/console.log
|
echo "NOTE: $QEMU either did not run or was interactive" > $resdir/console.log
|
||||||
echo $QEMU $qemu_args -m 512 -kernel $KERNEL -append \"$qemu_append $boot_args\" > $resdir/qemu-cmd
|
echo $QEMU $qemu_args -m $TORTURE_QEMU_MEM -kernel $KERNEL -append \"$qemu_append $boot_args\" > $resdir/qemu-cmd
|
||||||
( $QEMU $qemu_args -m 512 -kernel $KERNEL -append "$qemu_append $boot_args"& echo $! > $resdir/qemu_pid; wait `cat $resdir/qemu_pid`; echo $? > $resdir/qemu-retval ) &
|
( $QEMU $qemu_args -m $TORTURE_QEMU_MEM -kernel $KERNEL -append "$qemu_append $boot_args"& echo $! > $resdir/qemu_pid; wait `cat $resdir/qemu_pid`; echo $? > $resdir/qemu-retval ) &
|
||||||
commandcompleted=0
|
commandcompleted=0
|
||||||
sleep 10 # Give qemu's pid a chance to reach the file
|
sleep 10 # Give qemu's pid a chance to reach the file
|
||||||
if test -s "$resdir/qemu_pid"
|
if test -s "$resdir/qemu_pid"
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
#
|
#
|
||||||
# Run a series of 14 tests under KVM. These are not particularly
|
# Run a series of tests under KVM. By default, this series is specified
|
||||||
# well-selected or well-tuned, but are the current set.
|
# by the relevant CFLIST file, but can be overridden by the --configs
|
||||||
#
|
# command-line argument.
|
||||||
# Edit the definitions below to set the locations of the various directories,
|
|
||||||
# as well as the test duration.
|
|
||||||
#
|
#
|
||||||
# Usage: kvm.sh [ options ]
|
# Usage: kvm.sh [ options ]
|
||||||
#
|
#
|
||||||
@ -44,6 +42,7 @@ TORTURE_BOOT_IMAGE=""
|
|||||||
TORTURE_INITRD="$KVM/initrd"; export TORTURE_INITRD
|
TORTURE_INITRD="$KVM/initrd"; export TORTURE_INITRD
|
||||||
TORTURE_KCONFIG_ARG=""
|
TORTURE_KCONFIG_ARG=""
|
||||||
TORTURE_KMAKE_ARG=""
|
TORTURE_KMAKE_ARG=""
|
||||||
|
TORTURE_QEMU_MEM=512
|
||||||
TORTURE_SHUTDOWN_GRACE=180
|
TORTURE_SHUTDOWN_GRACE=180
|
||||||
TORTURE_SUITE=rcu
|
TORTURE_SUITE=rcu
|
||||||
resdir=""
|
resdir=""
|
||||||
@ -70,6 +69,7 @@ usage () {
|
|||||||
echo " --kconfig Kconfig-options"
|
echo " --kconfig Kconfig-options"
|
||||||
echo " --kmake-arg kernel-make-arguments"
|
echo " --kmake-arg kernel-make-arguments"
|
||||||
echo " --mac nn:nn:nn:nn:nn:nn"
|
echo " --mac nn:nn:nn:nn:nn:nn"
|
||||||
|
echo " --memory megabytes | nnnG"
|
||||||
echo " --no-initrd"
|
echo " --no-initrd"
|
||||||
echo " --qemu-args qemu-arguments"
|
echo " --qemu-args qemu-arguments"
|
||||||
echo " --qemu-cmd qemu-system-..."
|
echo " --qemu-cmd qemu-system-..."
|
||||||
@ -147,6 +147,11 @@ do
|
|||||||
TORTURE_QEMU_MAC=$2
|
TORTURE_QEMU_MAC=$2
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
|
--memory)
|
||||||
|
checkarg --memory "(memory size)" $# "$2" '^[0-9]\+[MG]\?$' error
|
||||||
|
TORTURE_QEMU_MEM=$2
|
||||||
|
shift
|
||||||
|
;;
|
||||||
--no-initrd)
|
--no-initrd)
|
||||||
TORTURE_INITRD=""; export TORTURE_INITRD
|
TORTURE_INITRD=""; export TORTURE_INITRD
|
||||||
;;
|
;;
|
||||||
@ -174,6 +179,12 @@ do
|
|||||||
checkarg --torture "(suite name)" "$#" "$2" '^\(lock\|rcu\|rcuperf\)$' '^--'
|
checkarg --torture "(suite name)" "$#" "$2" '^\(lock\|rcu\|rcuperf\)$' '^--'
|
||||||
TORTURE_SUITE=$2
|
TORTURE_SUITE=$2
|
||||||
shift
|
shift
|
||||||
|
if test "$TORTURE_SUITE" = rcuperf
|
||||||
|
then
|
||||||
|
# If you really want jitter for rcuperf, specify
|
||||||
|
# it after specifying rcuperf. (But why?)
|
||||||
|
jitter=0
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo Unknown argument $1
|
echo Unknown argument $1
|
||||||
@ -288,6 +299,7 @@ TORTURE_KMAKE_ARG="$TORTURE_KMAKE_ARG"; export TORTURE_KMAKE_ARG
|
|||||||
TORTURE_QEMU_CMD="$TORTURE_QEMU_CMD"; export TORTURE_QEMU_CMD
|
TORTURE_QEMU_CMD="$TORTURE_QEMU_CMD"; export TORTURE_QEMU_CMD
|
||||||
TORTURE_QEMU_INTERACTIVE="$TORTURE_QEMU_INTERACTIVE"; export TORTURE_QEMU_INTERACTIVE
|
TORTURE_QEMU_INTERACTIVE="$TORTURE_QEMU_INTERACTIVE"; export TORTURE_QEMU_INTERACTIVE
|
||||||
TORTURE_QEMU_MAC="$TORTURE_QEMU_MAC"; export TORTURE_QEMU_MAC
|
TORTURE_QEMU_MAC="$TORTURE_QEMU_MAC"; export TORTURE_QEMU_MAC
|
||||||
|
TORTURE_QEMU_MEM="$TORTURE_QEMU_MEM"; export TORTURE_QEMU_MEM
|
||||||
TORTURE_SHUTDOWN_GRACE="$TORTURE_SHUTDOWN_GRACE"; export TORTURE_SHUTDOWN_GRACE
|
TORTURE_SHUTDOWN_GRACE="$TORTURE_SHUTDOWN_GRACE"; export TORTURE_SHUTDOWN_GRACE
|
||||||
TORTURE_SUITE="$TORTURE_SUITE"; export TORTURE_SUITE
|
TORTURE_SUITE="$TORTURE_SUITE"; export TORTURE_SUITE
|
||||||
if ! test -e $resdir
|
if ! test -e $resdir
|
||||||
|
@ -20,32 +20,10 @@
|
|||||||
#
|
#
|
||||||
# Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
|
# Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
|
||||||
|
|
||||||
# rcuperf_param_nreaders bootparam-string
|
|
||||||
#
|
|
||||||
# Adds nreaders rcuperf module parameter if not already specified.
|
|
||||||
rcuperf_param_nreaders () {
|
|
||||||
if ! echo "$1" | grep -q "rcuperf.nreaders"
|
|
||||||
then
|
|
||||||
echo rcuperf.nreaders=-1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# rcuperf_param_nwriters bootparam-string
|
|
||||||
#
|
|
||||||
# Adds nwriters rcuperf module parameter if not already specified.
|
|
||||||
rcuperf_param_nwriters () {
|
|
||||||
if ! echo "$1" | grep -q "rcuperf.nwriters"
|
|
||||||
then
|
|
||||||
echo rcuperf.nwriters=-1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# per_version_boot_params bootparam-string config-file seconds
|
# per_version_boot_params bootparam-string config-file seconds
|
||||||
#
|
#
|
||||||
# Adds per-version torture-module parameters to kernels supporting them.
|
# Adds per-version torture-module parameters to kernels supporting them.
|
||||||
per_version_boot_params () {
|
per_version_boot_params () {
|
||||||
echo $1 `rcuperf_param_nreaders "$1"` \
|
echo $1 rcuperf.shutdown=1 \
|
||||||
`rcuperf_param_nwriters "$1"` \
|
|
||||||
rcuperf.shutdown=1 \
|
|
||||||
rcuperf.verbose=1
|
rcuperf.verbose=1
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user