diff options
Diffstat (limited to 'kernel/rcutorture.c')
-rw-r--r-- | kernel/rcutorture.c | 53 |
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; | |||
117 | static atomic_t n_rcu_torture_free; | 117 | static atomic_t n_rcu_torture_free; |
118 | static atomic_t n_rcu_torture_mberror; | 118 | static atomic_t n_rcu_torture_mberror; |
119 | static atomic_t n_rcu_torture_error; | 119 | static atomic_t n_rcu_torture_error; |
120 | static 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 | ||
274 | static 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 | |||
295 | static 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 | ||
337 | static struct srcu_struct srcu_ctl; | 364 | static struct srcu_struct srcu_ctl; |
338 | static struct list_head srcu_removed; | ||
339 | 365 | ||
340 | static void srcu_torture_init(void) | 366 | static 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 | ||
346 | static void srcu_torture_cleanup(void) | 372 | static 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 | ||
380 | static 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 | |||
401 | static void srcu_torture_synchronize(void) | 406 | static 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" |