The RCU tasks flavors of RCU now need concurrent callback flooding to test their ability to switch between single-queue mode and per-CPU queue mode, but their lack of heavy-duty forward-progress features rules out the use of rcutorture's current callback-flooding code. This commit therefore provides the ability to limit the intensity of the callback floods using a new ->cbflood_max field in the rcu_operations structure. When this field is zero, there is no limit, otherwise, each callback-flood kthread allocates at most ->cbflood_max callbacks.
Showing the changes to kernel (1 of 1 file). Show all
Unified · Split
| @@ -348,6 +348,7 @@ struct rcu_torture_ops { · 347 unmodified lines | ||
| 348 | 348 | void (*gp_kthread_dbg)(void); |
| 349 | 349 | bool (*check_boost_failed)(unsigned long gp_state, int *cpup); |
| 350 | 350 | int (*stall_dur)(void); |
| 351 | + long cbflood_max; | |
| 351 | 352 | int irq_capable; |
| 352 | 353 | int can_boost; |
| 353 | 354 | int extendables; |
| @@ -841,6 +842,7 @@ static struct rcu_torture_ops tasks_rude_ops = { · 487 unmodified lines | ||
| 841 | 842 | .call = call_rcu_tasks_rude, |
| 842 | 843 | .cb_barrier = rcu_barrier_tasks_rude, |
| 843 | 844 | .gp_kthread_dbg = show_rcu_tasks_rude_gp_kthread, |
| 845 | + .cbflood_max = 50000, | |
| 844 | 846 | .fqs = NULL, |
| 845 | 847 | .stats = NULL, |
| 846 | 848 | .irq_capable = 1, |
| @@ -881,6 +883,7 @@ static struct rcu_torture_ops tasks_tracing_ops = { · 34 unmodified lines | ||
| 881 | 883 | .call = call_rcu_tasks_trace, |
| 882 | 884 | .cb_barrier = rcu_barrier_tasks_trace, |
| 883 | 885 | .gp_kthread_dbg = show_rcu_tasks_trace_gp_kthread, |
| 886 | + .cbflood_max = 50000, | |
| 884 | 887 | .fqs = NULL, |
| 885 | 888 | .stats = NULL, |
| 886 | 889 | .irq_capable = 1, |
| @@ -2387,7 +2390,7 @@ static void rcu_torture_fwd_prog_cr(struct rcu_fwd *rfp) · 1500 unmodified lines | ||
| 2387 | 2390 | rfp->rcu_fwd_cb_head = rfcpn; |
| 2388 | 2391 | n_launders++; |
| 2389 | 2392 | n_launders_sa++; |
| 2390 | − } else { | |
| 2393 | + } else if (!cur_ops->cbflood_max || cur_ops->cbflood_max > n_max_cbs) { | |
| 2391 | 2394 | rfcp = kmalloc(sizeof(*rfcp), GFP_KERNEL); |
| 2392 | 2395 | if (WARN_ON_ONCE(!rfcp)) { |
| 2393 | 2396 | schedule_timeout_interruptible(1); |
| @@ -2397,8 +2400,11 @@ static void rcu_torture_fwd_prog_cr(struct rcu_fwd *rfp) · 3 unmodified lines | ||
| 2397 | 2400 | n_launders_sa = 0; |
| 2398 | 2401 | rfcp->rfc_gps = 0; |
| 2399 | 2402 | rfcp->rfc_rfp = rfp; |
| 2403 | + } else { | |
| 2404 | + rfcp = NULL; | |
| 2400 | 2405 | } |
| 2401 | − cur_ops->call(&rfcp->rh, rcu_torture_fwd_cb_cr); | |
| 2406 | + if (rfcp) | |
| 2407 | + cur_ops->call(&rfcp->rh, rcu_torture_fwd_cb_cr); | |
| 2402 | 2408 | rcu_torture_fwd_prog_cond_resched(n_launders + n_max_cbs); |
| 2403 | 2409 | if (tick_nohz_full_enabled()) { |
| 2404 | 2410 | local_irq_save(flags); |
| @@ -2506,8 +2512,10 @@ static int rcu_torture_fwd_prog(void *args) · 101 unmodified lines | ||
| 2506 | 2512 | pr_alert("%s: Starting forward-progress test %d\n", __func__, rfp->rcu_fwd_id); |
| 2507 | 2513 | if (rcu_inkernel_boot_has_ended() && torture_num_online_cpus() > rfp->rcu_fwd_id) |
| 2508 | 2514 | rcu_torture_fwd_prog_cr(rfp); |
| 2509 | − if (!IS_ENABLED(CONFIG_TINY_RCU) || | |
| 2510 | − (rcu_inkernel_boot_has_ended() && torture_num_online_cpus() > rfp->rcu_fwd_id)) | |
| 2515 | + if ((cur_ops->stall_dur && cur_ops->stall_dur() > 0) && | |
| 2516 | + (!IS_ENABLED(CONFIG_TINY_RCU) || | |
| 2517 | + (rcu_inkernel_boot_has_ended() && | |
| 2518 | + torture_num_online_cpus() > rfp->rcu_fwd_id))) | |
| 2511 | 2519 | rcu_torture_fwd_prog_nr(rfp, &tested, &tested_tries); |
| 2512 | 2520 | |
| 2513 | 2521 | /* Avoid slow periods, better to test when busy. */ |
| @@ -2539,7 +2547,8 @@ static int __init rcu_torture_fwd_prog_init(void) · 25 unmodified lines | ||
| 2539 | 2547 | fwd_progress = nr_cpu_ids; |
| 2540 | 2548 | } |
| 2541 | 2549 | if ((!cur_ops->sync && !cur_ops->call) || |
| 2542 | − !cur_ops->stall_dur || cur_ops->stall_dur() <= 0 || cur_ops == &rcu_busted_ops) { | |
| 2550 | + (!cur_ops->cbflood_max && (!cur_ops->stall_dur || cur_ops->stall_dur() <= 0)) || | |
| 2551 | + cur_ops == &rcu_busted_ops) { | |
| 2543 | 2552 | VERBOSE_TOROUT_STRING("rcu_torture_fwd_prog_init: Disabled, unsupported by RCU flavor under test"); |
| 2544 | 2553 | fwd_progress = 0; |
| 2545 | 2554 | return 0; |