Commit 996417d2 authored by Paul E. McKenney's avatar Paul E. McKenney Committed by Linus Torvalds

[PATCH] add success/failure indication to RCU torture test

One issue with the RCU torture test is that the current error flagging can
be lost in dmesg.  This patch adds a "SUCCESS"/"FAILURE" string to the line
that flags the end of the test, where it can easily be seen with "dmesg |
tail" at the end of the test.  Also adds tests of architecture-specific
memory barriers -- or, more likely, of the RCU torture test itself.

Cc: <vatsa@in.ibm.com>
Signed-off-by: default avatar"Paul E. McKenney" <paulmck@us.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 2463ade2
...@@ -80,6 +80,7 @@ struct rcu_torture { ...@@ -80,6 +80,7 @@ struct rcu_torture {
struct rcu_head rtort_rcu; struct rcu_head rtort_rcu;
int rtort_pipe_count; int rtort_pipe_count;
struct list_head rtort_free; struct list_head rtort_free;
int rtort_mbtest;
}; };
static int fullstop = 0; /* stop generating callbacks at test end. */ static int fullstop = 0; /* stop generating callbacks at test end. */
...@@ -96,6 +97,8 @@ static atomic_t rcu_torture_wcount[RCU_TORTURE_PIPE_LEN + 1]; ...@@ -96,6 +97,8 @@ static atomic_t rcu_torture_wcount[RCU_TORTURE_PIPE_LEN + 1];
atomic_t n_rcu_torture_alloc; atomic_t n_rcu_torture_alloc;
atomic_t n_rcu_torture_alloc_fail; atomic_t n_rcu_torture_alloc_fail;
atomic_t n_rcu_torture_free; atomic_t n_rcu_torture_free;
atomic_t n_rcu_torture_mberror;
atomic_t n_rcu_torture_error;
/* /*
* Allocate an element from the rcu_tortures pool. * Allocate an element from the rcu_tortures pool.
...@@ -145,9 +148,10 @@ rcu_torture_cb(struct rcu_head *p) ...@@ -145,9 +148,10 @@ rcu_torture_cb(struct rcu_head *p)
if (i > RCU_TORTURE_PIPE_LEN) if (i > RCU_TORTURE_PIPE_LEN)
i = RCU_TORTURE_PIPE_LEN; i = RCU_TORTURE_PIPE_LEN;
atomic_inc(&rcu_torture_wcount[i]); atomic_inc(&rcu_torture_wcount[i]);
if (++rp->rtort_pipe_count >= RCU_TORTURE_PIPE_LEN) if (++rp->rtort_pipe_count >= RCU_TORTURE_PIPE_LEN) {
rp->rtort_mbtest = 0;
rcu_torture_free(rp); rcu_torture_free(rp);
else } else
call_rcu(p, rcu_torture_cb); call_rcu(p, rcu_torture_cb);
} }
...@@ -206,6 +210,7 @@ rcu_torture_writer(void *arg) ...@@ -206,6 +210,7 @@ rcu_torture_writer(void *arg)
rp->rtort_pipe_count = 0; rp->rtort_pipe_count = 0;
udelay(rcu_random(&rand) & 0x3ff); udelay(rcu_random(&rand) & 0x3ff);
old_rp = rcu_torture_current; old_rp = rcu_torture_current;
rp->rtort_mbtest = 1;
rcu_assign_pointer(rcu_torture_current, rp); rcu_assign_pointer(rcu_torture_current, rp);
smp_wmb(); smp_wmb();
if (old_rp != NULL) { if (old_rp != NULL) {
...@@ -252,6 +257,8 @@ rcu_torture_reader(void *arg) ...@@ -252,6 +257,8 @@ rcu_torture_reader(void *arg)
schedule_timeout_interruptible(HZ); schedule_timeout_interruptible(HZ);
continue; continue;
} }
if (p->rtort_mbtest == 0)
atomic_inc(&n_rcu_torture_mberror);
udelay(rcu_random(&rand) & 0x7f); udelay(rcu_random(&rand) & 0x7f);
preempt_disable(); preempt_disable();
pipe_count = p->rtort_pipe_count; pipe_count = p->rtort_pipe_count;
...@@ -300,16 +307,22 @@ rcu_torture_printk(char *page) ...@@ -300,16 +307,22 @@ rcu_torture_printk(char *page)
} }
cnt += sprintf(&page[cnt], "rcutorture: "); cnt += sprintf(&page[cnt], "rcutorture: ");
cnt += sprintf(&page[cnt], cnt += sprintf(&page[cnt],
"rtc: %p ver: %ld tfle: %d rta: %d rtaf: %d rtf: %d", "rtc: %p ver: %ld tfle: %d rta: %d rtaf: %d rtf: %d "
"rtmbe: %d",
rcu_torture_current, rcu_torture_current,
rcu_torture_current_version, rcu_torture_current_version,
list_empty(&rcu_torture_freelist), list_empty(&rcu_torture_freelist),
atomic_read(&n_rcu_torture_alloc), atomic_read(&n_rcu_torture_alloc),
atomic_read(&n_rcu_torture_alloc_fail), atomic_read(&n_rcu_torture_alloc_fail),
atomic_read(&n_rcu_torture_free)); atomic_read(&n_rcu_torture_free),
atomic_read(&n_rcu_torture_mberror));
if (atomic_read(&n_rcu_torture_mberror) != 0)
cnt += sprintf(&page[cnt], " !!!");
cnt += sprintf(&page[cnt], "\nrcutorture: "); cnt += sprintf(&page[cnt], "\nrcutorture: ");
if (i > 1) if (i > 1) {
cnt += sprintf(&page[cnt], "!!! "); cnt += sprintf(&page[cnt], "!!! ");
atomic_inc(&n_rcu_torture_error);
}
cnt += sprintf(&page[cnt], "Reader Pipe: "); cnt += sprintf(&page[cnt], "Reader Pipe: ");
for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++) for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++)
cnt += sprintf(&page[cnt], " %ld", pipesummary[i]); cnt += sprintf(&page[cnt], " %ld", pipesummary[i]);
...@@ -400,7 +413,9 @@ rcu_torture_cleanup(void) ...@@ -400,7 +413,9 @@ rcu_torture_cleanup(void)
for (i = 0; i < RCU_TORTURE_PIPE_LEN; i++) for (i = 0; i < RCU_TORTURE_PIPE_LEN; i++)
synchronize_rcu(); synchronize_rcu();
rcu_torture_stats_print(); /* -After- the stats thread is stopped! */ rcu_torture_stats_print(); /* -After- the stats thread is stopped! */
PRINTK_STRING("--- End of test"); printk(KERN_ALERT TORTURE_FLAG
"--- End of test: %s\n",
atomic_read(&n_rcu_torture_error) == 0 ? "SUCCESS" : "FAILURE");
} }
static int static int
...@@ -425,6 +440,7 @@ rcu_torture_init(void) ...@@ -425,6 +440,7 @@ rcu_torture_init(void)
INIT_LIST_HEAD(&rcu_torture_freelist); INIT_LIST_HEAD(&rcu_torture_freelist);
for (i = 0; i < sizeof(rcu_tortures) / sizeof(rcu_tortures[0]); i++) { for (i = 0; i < sizeof(rcu_tortures) / sizeof(rcu_tortures[0]); i++) {
rcu_tortures[i].rtort_mbtest = 0;
list_add_tail(&rcu_tortures[i].rtort_free, list_add_tail(&rcu_tortures[i].rtort_free,
&rcu_torture_freelist); &rcu_torture_freelist);
} }
...@@ -436,6 +452,8 @@ rcu_torture_init(void) ...@@ -436,6 +452,8 @@ rcu_torture_init(void)
atomic_set(&n_rcu_torture_alloc, 0); atomic_set(&n_rcu_torture_alloc, 0);
atomic_set(&n_rcu_torture_alloc_fail, 0); atomic_set(&n_rcu_torture_alloc_fail, 0);
atomic_set(&n_rcu_torture_free, 0); atomic_set(&n_rcu_torture_free, 0);
atomic_set(&n_rcu_torture_mberror, 0);
atomic_set(&n_rcu_torture_error, 0);
for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++) for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++)
atomic_set(&rcu_torture_wcount[i], 0); atomic_set(&rcu_torture_wcount[i], 0);
for_each_cpu(cpu) { for_each_cpu(cpu) {
......
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