aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/rcutorture.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/rcutorture.c')
-rw-r--r--kernel/rcutorture.c53
1 files changed, 29 insertions, 24 deletions
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
index e0450210ce4d..6e2f0a8344c2 100644
--- a/kernel/rcutorture.c
+++ b/kernel/rcutorture.c
@@ -117,6 +117,7 @@ static atomic_t n_rcu_torture_alloc_fail;
117static atomic_t n_rcu_torture_free; 117static atomic_t n_rcu_torture_free;
118static atomic_t n_rcu_torture_mberror; 118static atomic_t n_rcu_torture_mberror;
119static atomic_t n_rcu_torture_error; 119static atomic_t n_rcu_torture_error;
120static struct list_head rcu_torture_removed;
120 121
121/* 122/*
122 * Allocate an element from the rcu_tortures pool. 123 * Allocate an element from the rcu_tortures pool.
@@ -270,6 +271,32 @@ static struct rcu_torture_ops rcu_ops = {
270 .name = "rcu" 271 .name = "rcu"
271}; 272};
272 273
274static void rcu_sync_torture_deferred_free(struct rcu_torture *p)
275{
276 int i;
277 struct rcu_torture *rp;
278 struct rcu_torture *rp1;
279
280 cur_ops->sync();
281 list_add(&p->rtort_free, &rcu_torture_removed);
282 list_for_each_entry_safe(rp, rp1, &rcu_torture_removed, rtort_free) {
283 i = rp->rtort_pipe_count;
284 if (i > RCU_TORTURE_PIPE_LEN)
285 i = RCU_TORTURE_PIPE_LEN;
286 atomic_inc(&rcu_torture_wcount[i]);
287 if (++rp->rtort_pipe_count >= RCU_TORTURE_PIPE_LEN) {
288 rp->rtort_mbtest = 0;
289 list_del(&rp->rtort_free);
290 rcu_torture_free(rp);
291 }
292 }
293}
294
295static void rcu_sync_torture_init(void)
296{
297 INIT_LIST_HEAD(&rcu_torture_removed);
298}
299
273/* 300/*
274 * Definitions for rcu_bh torture testing. 301 * Definitions for rcu_bh torture testing.
275 */ 302 */
@@ -335,12 +362,11 @@ static struct rcu_torture_ops rcu_bh_ops = {
335 */ 362 */
336 363
337static struct srcu_struct srcu_ctl; 364static struct srcu_struct srcu_ctl;
338static struct list_head srcu_removed;
339 365
340static void srcu_torture_init(void) 366static void srcu_torture_init(void)
341{ 367{
342 init_srcu_struct(&srcu_ctl); 368 init_srcu_struct(&srcu_ctl);
343 INIT_LIST_HEAD(&srcu_removed); 369 rcu_sync_torture_init();
344} 370}
345 371
346static void srcu_torture_cleanup(void) 372static void srcu_torture_cleanup(void)
@@ -377,27 +403,6 @@ static int srcu_torture_completed(void)
377 return srcu_batches_completed(&srcu_ctl); 403 return srcu_batches_completed(&srcu_ctl);
378} 404}
379 405
380static void srcu_torture_deferred_free(struct rcu_torture *p)
381{
382 int i;
383 struct rcu_torture *rp;
384 struct rcu_torture *rp1;
385
386 synchronize_srcu(&srcu_ctl);
387 list_add(&p->rtort_free, &srcu_removed);
388 list_for_each_entry_safe(rp, rp1, &srcu_removed, rtort_free) {
389 i = rp->rtort_pipe_count;
390 if (i > RCU_TORTURE_PIPE_LEN)
391 i = RCU_TORTURE_PIPE_LEN;
392 atomic_inc(&rcu_torture_wcount[i]);
393 if (++rp->rtort_pipe_count >= RCU_TORTURE_PIPE_LEN) {
394 rp->rtort_mbtest = 0;
395 list_del(&rp->rtort_free);
396 rcu_torture_free(rp);
397 }
398 }
399}
400
401static void srcu_torture_synchronize(void) 406static void srcu_torture_synchronize(void)
402{ 407{
403 synchronize_srcu(&srcu_ctl); 408 synchronize_srcu(&srcu_ctl);
@@ -427,7 +432,7 @@ static struct rcu_torture_ops srcu_ops = {
427 .readdelay = srcu_read_delay, 432 .readdelay = srcu_read_delay,
428 .readunlock = srcu_torture_read_unlock, 433 .readunlock = srcu_torture_read_unlock,
429 .completed = srcu_torture_completed, 434 .completed = srcu_torture_completed,
430 .deferredfree = srcu_torture_deferred_free, 435 .deferredfree = rcu_sync_torture_deferred_free,
431 .sync = srcu_torture_synchronize, 436 .sync = srcu_torture_synchronize,
432 .stats = srcu_torture_stats, 437 .stats = srcu_torture_stats,
433 .name = "srcu" 438 .name = "srcu"