diff options
Diffstat (limited to 'kernel/rcutorture.c')
| -rw-r--r-- | kernel/rcutorture.c | 159 |
1 files changed, 97 insertions, 62 deletions
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c index 25b15033c61f..aaa7b9f3532a 100644 --- a/kernel/rcutorture.c +++ b/kernel/rcutorture.c | |||
| @@ -53,10 +53,11 @@ MODULE_AUTHOR("Paul E. McKenney <paulmck@us.ibm.com> and Josh Triplett <josh@fre | |||
| 53 | 53 | ||
| 54 | static int nreaders = -1; /* # reader threads, defaults to 2*ncpus */ | 54 | static int nreaders = -1; /* # reader threads, defaults to 2*ncpus */ |
| 55 | static int nfakewriters = 4; /* # fake writer threads */ | 55 | static int nfakewriters = 4; /* # fake writer threads */ |
| 56 | static int stat_interval; /* Interval between stats, in seconds. */ | 56 | static int stat_interval = 60; /* Interval between stats, in seconds. */ |
| 57 | /* Defaults to "only at end of test". */ | 57 | /* Zero means "only at end of test". */ |
| 58 | static bool verbose; /* Print more debug info. */ | 58 | static bool verbose; /* Print more debug info. */ |
| 59 | static bool test_no_idle_hz; /* Test RCU's support for tickless idle CPUs. */ | 59 | static bool test_no_idle_hz = true; |
| 60 | /* Test RCU support for tickless idle CPUs. */ | ||
| 60 | static int shuffle_interval = 3; /* Interval between shuffles (in sec)*/ | 61 | static int shuffle_interval = 3; /* Interval between shuffles (in sec)*/ |
| 61 | static int stutter = 5; /* Start/stop testing interval (in sec) */ | 62 | static int stutter = 5; /* Start/stop testing interval (in sec) */ |
| 62 | static int irqreader = 1; /* RCU readers from irq (timers). */ | 63 | static int irqreader = 1; /* RCU readers from irq (timers). */ |
| @@ -119,11 +120,11 @@ MODULE_PARM_DESC(torture_type, "Type of RCU to torture (rcu, rcu_bh, srcu)"); | |||
| 119 | 120 | ||
| 120 | #define TORTURE_FLAG "-torture:" | 121 | #define TORTURE_FLAG "-torture:" |
| 121 | #define PRINTK_STRING(s) \ | 122 | #define PRINTK_STRING(s) \ |
| 122 | do { printk(KERN_ALERT "%s" TORTURE_FLAG s "\n", torture_type); } while (0) | 123 | do { pr_alert("%s" TORTURE_FLAG s "\n", torture_type); } while (0) |
| 123 | #define VERBOSE_PRINTK_STRING(s) \ | 124 | #define VERBOSE_PRINTK_STRING(s) \ |
| 124 | do { if (verbose) printk(KERN_ALERT "%s" TORTURE_FLAG s "\n", torture_type); } while (0) | 125 | do { if (verbose) pr_alert("%s" TORTURE_FLAG s "\n", torture_type); } while (0) |
| 125 | #define VERBOSE_PRINTK_ERRSTRING(s) \ | 126 | #define VERBOSE_PRINTK_ERRSTRING(s) \ |
| 126 | do { if (verbose) printk(KERN_ALERT "%s" TORTURE_FLAG "!!! " s "\n", torture_type); } while (0) | 127 | do { if (verbose) pr_alert("%s" TORTURE_FLAG "!!! " s "\n", torture_type); } while (0) |
| 127 | 128 | ||
| 128 | static char printk_buf[4096]; | 129 | static char printk_buf[4096]; |
| 129 | 130 | ||
| @@ -176,8 +177,14 @@ static long n_rcu_torture_boosts; | |||
| 176 | static long n_rcu_torture_timers; | 177 | static long n_rcu_torture_timers; |
| 177 | static long n_offline_attempts; | 178 | static long n_offline_attempts; |
| 178 | static long n_offline_successes; | 179 | static long n_offline_successes; |
| 180 | static unsigned long sum_offline; | ||
| 181 | static int min_offline = -1; | ||
| 182 | static int max_offline; | ||
| 179 | static long n_online_attempts; | 183 | static long n_online_attempts; |
| 180 | static long n_online_successes; | 184 | static long n_online_successes; |
| 185 | static unsigned long sum_online; | ||
| 186 | static int min_online = -1; | ||
| 187 | static int max_online; | ||
| 181 | static long n_barrier_attempts; | 188 | static long n_barrier_attempts; |
| 182 | static long n_barrier_successes; | 189 | static long n_barrier_successes; |
| 183 | static struct list_head rcu_torture_removed; | 190 | static struct list_head rcu_torture_removed; |
| @@ -235,7 +242,7 @@ rcutorture_shutdown_notify(struct notifier_block *unused1, | |||
| 235 | if (fullstop == FULLSTOP_DONTSTOP) | 242 | if (fullstop == FULLSTOP_DONTSTOP) |
| 236 | fullstop = FULLSTOP_SHUTDOWN; | 243 | fullstop = FULLSTOP_SHUTDOWN; |
| 237 | else | 244 | else |
| 238 | printk(KERN_WARNING /* but going down anyway, so... */ | 245 | pr_warn(/* but going down anyway, so... */ |
| 239 | "Concurrent 'rmmod rcutorture' and shutdown illegal!\n"); | 246 | "Concurrent 'rmmod rcutorture' and shutdown illegal!\n"); |
| 240 | mutex_unlock(&fullstop_mutex); | 247 | mutex_unlock(&fullstop_mutex); |
| 241 | return NOTIFY_DONE; | 248 | return NOTIFY_DONE; |
| @@ -248,7 +255,7 @@ rcutorture_shutdown_notify(struct notifier_block *unused1, | |||
| 248 | static void rcutorture_shutdown_absorb(char *title) | 255 | static void rcutorture_shutdown_absorb(char *title) |
| 249 | { | 256 | { |
| 250 | if (ACCESS_ONCE(fullstop) == FULLSTOP_SHUTDOWN) { | 257 | if (ACCESS_ONCE(fullstop) == FULLSTOP_SHUTDOWN) { |
| 251 | printk(KERN_NOTICE | 258 | pr_notice( |
| 252 | "rcutorture thread %s parking due to system shutdown\n", | 259 | "rcutorture thread %s parking due to system shutdown\n", |
| 253 | title); | 260 | title); |
| 254 | schedule_timeout_uninterruptible(MAX_SCHEDULE_TIMEOUT); | 261 | schedule_timeout_uninterruptible(MAX_SCHEDULE_TIMEOUT); |
| @@ -1214,11 +1221,13 @@ rcu_torture_printk(char *page) | |||
| 1214 | n_rcu_torture_boost_failure, | 1221 | n_rcu_torture_boost_failure, |
| 1215 | n_rcu_torture_boosts, | 1222 | n_rcu_torture_boosts, |
| 1216 | n_rcu_torture_timers); | 1223 | n_rcu_torture_timers); |
| 1217 | cnt += sprintf(&page[cnt], "onoff: %ld/%ld:%ld/%ld ", | 1224 | cnt += sprintf(&page[cnt], |
| 1218 | n_online_successes, | 1225 | "onoff: %ld/%ld:%ld/%ld %d,%d:%d,%d %lu:%lu (HZ=%d) ", |
| 1219 | n_online_attempts, | 1226 | n_online_successes, n_online_attempts, |
| 1220 | n_offline_successes, | 1227 | n_offline_successes, n_offline_attempts, |
| 1221 | n_offline_attempts); | 1228 | min_online, max_online, |
| 1229 | min_offline, max_offline, | ||
| 1230 | sum_online, sum_offline, HZ); | ||
| 1222 | cnt += sprintf(&page[cnt], "barrier: %ld/%ld:%ld", | 1231 | cnt += sprintf(&page[cnt], "barrier: %ld/%ld:%ld", |
| 1223 | n_barrier_successes, | 1232 | n_barrier_successes, |
| 1224 | n_barrier_attempts, | 1233 | n_barrier_attempts, |
| @@ -1267,7 +1276,7 @@ rcu_torture_stats_print(void) | |||
| 1267 | int cnt; | 1276 | int cnt; |
| 1268 | 1277 | ||
| 1269 | cnt = rcu_torture_printk(printk_buf); | 1278 | cnt = rcu_torture_printk(printk_buf); |
| 1270 | printk(KERN_ALERT "%s", printk_buf); | 1279 | pr_alert("%s", printk_buf); |
| 1271 | } | 1280 | } |
| 1272 | 1281 | ||
| 1273 | /* | 1282 | /* |
| @@ -1380,20 +1389,20 @@ rcu_torture_stutter(void *arg) | |||
| 1380 | static inline void | 1389 | static inline void |
| 1381 | rcu_torture_print_module_parms(struct rcu_torture_ops *cur_ops, char *tag) | 1390 | rcu_torture_print_module_parms(struct rcu_torture_ops *cur_ops, char *tag) |
| 1382 | { | 1391 | { |
| 1383 | printk(KERN_ALERT "%s" TORTURE_FLAG | 1392 | pr_alert("%s" TORTURE_FLAG |
| 1384 | "--- %s: nreaders=%d nfakewriters=%d " | 1393 | "--- %s: nreaders=%d nfakewriters=%d " |
| 1385 | "stat_interval=%d verbose=%d test_no_idle_hz=%d " | 1394 | "stat_interval=%d verbose=%d test_no_idle_hz=%d " |
| 1386 | "shuffle_interval=%d stutter=%d irqreader=%d " | 1395 | "shuffle_interval=%d stutter=%d irqreader=%d " |
| 1387 | "fqs_duration=%d fqs_holdoff=%d fqs_stutter=%d " | 1396 | "fqs_duration=%d fqs_holdoff=%d fqs_stutter=%d " |
| 1388 | "test_boost=%d/%d test_boost_interval=%d " | 1397 | "test_boost=%d/%d test_boost_interval=%d " |
| 1389 | "test_boost_duration=%d shutdown_secs=%d " | 1398 | "test_boost_duration=%d shutdown_secs=%d " |
| 1390 | "onoff_interval=%d onoff_holdoff=%d\n", | 1399 | "onoff_interval=%d onoff_holdoff=%d\n", |
| 1391 | torture_type, tag, nrealreaders, nfakewriters, | 1400 | torture_type, tag, nrealreaders, nfakewriters, |
| 1392 | stat_interval, verbose, test_no_idle_hz, shuffle_interval, | 1401 | stat_interval, verbose, test_no_idle_hz, shuffle_interval, |
| 1393 | stutter, irqreader, fqs_duration, fqs_holdoff, fqs_stutter, | 1402 | stutter, irqreader, fqs_duration, fqs_holdoff, fqs_stutter, |
| 1394 | test_boost, cur_ops->can_boost, | 1403 | test_boost, cur_ops->can_boost, |
| 1395 | test_boost_interval, test_boost_duration, shutdown_secs, | 1404 | test_boost_interval, test_boost_duration, shutdown_secs, |
| 1396 | onoff_interval, onoff_holdoff); | 1405 | onoff_interval, onoff_holdoff); |
| 1397 | } | 1406 | } |
| 1398 | 1407 | ||
| 1399 | static struct notifier_block rcutorture_shutdown_nb = { | 1408 | static struct notifier_block rcutorture_shutdown_nb = { |
| @@ -1460,9 +1469,9 @@ rcu_torture_shutdown(void *arg) | |||
| 1460 | !kthread_should_stop()) { | 1469 | !kthread_should_stop()) { |
| 1461 | delta = shutdown_time - jiffies_snap; | 1470 | delta = shutdown_time - jiffies_snap; |
| 1462 | if (verbose) | 1471 | if (verbose) |
| 1463 | printk(KERN_ALERT "%s" TORTURE_FLAG | 1472 | pr_alert("%s" TORTURE_FLAG |
| 1464 | "rcu_torture_shutdown task: %lu jiffies remaining\n", | 1473 | "rcu_torture_shutdown task: %lu jiffies remaining\n", |
| 1465 | torture_type, delta); | 1474 | torture_type, delta); |
| 1466 | schedule_timeout_interruptible(delta); | 1475 | schedule_timeout_interruptible(delta); |
| 1467 | jiffies_snap = ACCESS_ONCE(jiffies); | 1476 | jiffies_snap = ACCESS_ONCE(jiffies); |
| 1468 | } | 1477 | } |
| @@ -1490,8 +1499,10 @@ static int __cpuinit | |||
| 1490 | rcu_torture_onoff(void *arg) | 1499 | rcu_torture_onoff(void *arg) |
| 1491 | { | 1500 | { |
| 1492 | int cpu; | 1501 | int cpu; |
| 1502 | unsigned long delta; | ||
| 1493 | int maxcpu = -1; | 1503 | int maxcpu = -1; |
| 1494 | DEFINE_RCU_RANDOM(rand); | 1504 | DEFINE_RCU_RANDOM(rand); |
| 1505 | unsigned long starttime; | ||
| 1495 | 1506 | ||
| 1496 | VERBOSE_PRINTK_STRING("rcu_torture_onoff task started"); | 1507 | VERBOSE_PRINTK_STRING("rcu_torture_onoff task started"); |
| 1497 | for_each_online_cpu(cpu) | 1508 | for_each_online_cpu(cpu) |
| @@ -1506,29 +1517,51 @@ rcu_torture_onoff(void *arg) | |||
| 1506 | cpu = (rcu_random(&rand) >> 4) % (maxcpu + 1); | 1517 | cpu = (rcu_random(&rand) >> 4) % (maxcpu + 1); |
| 1507 | if (cpu_online(cpu) && cpu_is_hotpluggable(cpu)) { | 1518 | if (cpu_online(cpu) && cpu_is_hotpluggable(cpu)) { |
| 1508 | if (verbose) | 1519 | if (verbose) |
| 1509 | printk(KERN_ALERT "%s" TORTURE_FLAG | 1520 | pr_alert("%s" TORTURE_FLAG |
| 1510 | "rcu_torture_onoff task: offlining %d\n", | 1521 | "rcu_torture_onoff task: offlining %d\n", |
| 1511 | torture_type, cpu); | 1522 | torture_type, cpu); |
| 1523 | starttime = jiffies; | ||
| 1512 | n_offline_attempts++; | 1524 | n_offline_attempts++; |
| 1513 | if (cpu_down(cpu) == 0) { | 1525 | if (cpu_down(cpu) == 0) { |
| 1514 | if (verbose) | 1526 | if (verbose) |
| 1515 | printk(KERN_ALERT "%s" TORTURE_FLAG | 1527 | pr_alert("%s" TORTURE_FLAG |
| 1516 | "rcu_torture_onoff task: offlined %d\n", | 1528 | "rcu_torture_onoff task: offlined %d\n", |
| 1517 | torture_type, cpu); | 1529 | torture_type, cpu); |
| 1518 | n_offline_successes++; | 1530 | n_offline_successes++; |
| 1531 | delta = jiffies - starttime; | ||
| 1532 | sum_offline += delta; | ||
| 1533 | if (min_offline < 0) { | ||
| 1534 | min_offline = delta; | ||
| 1535 | max_offline = delta; | ||
| 1536 | } | ||
| 1537 | if (min_offline > delta) | ||
| 1538 | min_offline = delta; | ||
| 1539 | if (max_offline < delta) | ||
| 1540 | max_offline = delta; | ||
| 1519 | } | 1541 | } |
| 1520 | } else if (cpu_is_hotpluggable(cpu)) { | 1542 | } else if (cpu_is_hotpluggable(cpu)) { |
| 1521 | if (verbose) | 1543 | if (verbose) |
| 1522 | printk(KERN_ALERT "%s" TORTURE_FLAG | 1544 | pr_alert("%s" TORTURE_FLAG |
| 1523 | "rcu_torture_onoff task: onlining %d\n", | 1545 | "rcu_torture_onoff task: onlining %d\n", |
| 1524 | torture_type, cpu); | 1546 | torture_type, cpu); |
| 1547 | starttime = jiffies; | ||
| 1525 | n_online_attempts++; | 1548 | n_online_attempts++; |
| 1526 | if (cpu_up(cpu) == 0) { | 1549 | if (cpu_up(cpu) == 0) { |
| 1527 | if (verbose) | 1550 | if (verbose) |
| 1528 | printk(KERN_ALERT "%s" TORTURE_FLAG | 1551 | pr_alert("%s" TORTURE_FLAG |
| 1529 | "rcu_torture_onoff task: onlined %d\n", | 1552 | "rcu_torture_onoff task: onlined %d\n", |
| 1530 | torture_type, cpu); | 1553 | torture_type, cpu); |
| 1531 | n_online_successes++; | 1554 | n_online_successes++; |
| 1555 | delta = jiffies - starttime; | ||
| 1556 | sum_online += delta; | ||
| 1557 | if (min_online < 0) { | ||
| 1558 | min_online = delta; | ||
| 1559 | max_online = delta; | ||
| 1560 | } | ||
| 1561 | if (min_online > delta) | ||
| 1562 | min_online = delta; | ||
| 1563 | if (max_online < delta) | ||
| 1564 | max_online = delta; | ||
| 1532 | } | 1565 | } |
| 1533 | } | 1566 | } |
| 1534 | schedule_timeout_interruptible(onoff_interval * HZ); | 1567 | schedule_timeout_interruptible(onoff_interval * HZ); |
| @@ -1593,14 +1626,14 @@ static int __cpuinit rcu_torture_stall(void *args) | |||
| 1593 | if (!kthread_should_stop()) { | 1626 | if (!kthread_should_stop()) { |
| 1594 | stop_at = get_seconds() + stall_cpu; | 1627 | stop_at = get_seconds() + stall_cpu; |
| 1595 | /* RCU CPU stall is expected behavior in following code. */ | 1628 | /* RCU CPU stall is expected behavior in following code. */ |
| 1596 | printk(KERN_ALERT "rcu_torture_stall start.\n"); | 1629 | pr_alert("rcu_torture_stall start.\n"); |
| 1597 | rcu_read_lock(); | 1630 | rcu_read_lock(); |
| 1598 | preempt_disable(); | 1631 | preempt_disable(); |
| 1599 | while (ULONG_CMP_LT(get_seconds(), stop_at)) | 1632 | while (ULONG_CMP_LT(get_seconds(), stop_at)) |
| 1600 | continue; /* Induce RCU CPU stall warning. */ | 1633 | continue; /* Induce RCU CPU stall warning. */ |
| 1601 | preempt_enable(); | 1634 | preempt_enable(); |
| 1602 | rcu_read_unlock(); | 1635 | rcu_read_unlock(); |
| 1603 | printk(KERN_ALERT "rcu_torture_stall end.\n"); | 1636 | pr_alert("rcu_torture_stall end.\n"); |
| 1604 | } | 1637 | } |
| 1605 | rcutorture_shutdown_absorb("rcu_torture_stall"); | 1638 | rcutorture_shutdown_absorb("rcu_torture_stall"); |
| 1606 | while (!kthread_should_stop()) | 1639 | while (!kthread_should_stop()) |
| @@ -1716,12 +1749,12 @@ static int rcu_torture_barrier_init(void) | |||
| 1716 | if (n_barrier_cbs == 0) | 1749 | if (n_barrier_cbs == 0) |
| 1717 | return 0; | 1750 | return 0; |
| 1718 | if (cur_ops->call == NULL || cur_ops->cb_barrier == NULL) { | 1751 | if (cur_ops->call == NULL || cur_ops->cb_barrier == NULL) { |
| 1719 | printk(KERN_ALERT "%s" TORTURE_FLAG | 1752 | pr_alert("%s" TORTURE_FLAG |
| 1720 | " Call or barrier ops missing for %s,\n", | 1753 | " Call or barrier ops missing for %s,\n", |
| 1721 | torture_type, cur_ops->name); | 1754 | torture_type, cur_ops->name); |
| 1722 | printk(KERN_ALERT "%s" TORTURE_FLAG | 1755 | pr_alert("%s" TORTURE_FLAG |
| 1723 | " RCU barrier testing omitted from run.\n", | 1756 | " RCU barrier testing omitted from run.\n", |
| 1724 | torture_type); | 1757 | torture_type); |
| 1725 | return 0; | 1758 | return 0; |
| 1726 | } | 1759 | } |
| 1727 | atomic_set(&barrier_cbs_count, 0); | 1760 | atomic_set(&barrier_cbs_count, 0); |
| @@ -1814,7 +1847,7 @@ rcu_torture_cleanup(void) | |||
| 1814 | mutex_lock(&fullstop_mutex); | 1847 | mutex_lock(&fullstop_mutex); |
| 1815 | rcutorture_record_test_transition(); | 1848 | rcutorture_record_test_transition(); |
| 1816 | if (fullstop == FULLSTOP_SHUTDOWN) { | 1849 | if (fullstop == FULLSTOP_SHUTDOWN) { |
| 1817 | printk(KERN_WARNING /* but going down anyway, so... */ | 1850 | pr_warn(/* but going down anyway, so... */ |
| 1818 | "Concurrent 'rmmod rcutorture' and shutdown illegal!\n"); | 1851 | "Concurrent 'rmmod rcutorture' and shutdown illegal!\n"); |
| 1819 | mutex_unlock(&fullstop_mutex); | 1852 | mutex_unlock(&fullstop_mutex); |
| 1820 | schedule_timeout_uninterruptible(10); | 1853 | schedule_timeout_uninterruptible(10); |
| @@ -1938,17 +1971,17 @@ rcu_torture_init(void) | |||
| 1938 | break; | 1971 | break; |
| 1939 | } | 1972 | } |
| 1940 | if (i == ARRAY_SIZE(torture_ops)) { | 1973 | if (i == ARRAY_SIZE(torture_ops)) { |
| 1941 | printk(KERN_ALERT "rcu-torture: invalid torture type: \"%s\"\n", | 1974 | pr_alert("rcu-torture: invalid torture type: \"%s\"\n", |
| 1942 | torture_type); | 1975 | torture_type); |
| 1943 | printk(KERN_ALERT "rcu-torture types:"); | 1976 | pr_alert("rcu-torture types:"); |
| 1944 | for (i = 0; i < ARRAY_SIZE(torture_ops); i++) | 1977 | for (i = 0; i < ARRAY_SIZE(torture_ops); i++) |
| 1945 | printk(KERN_ALERT " %s", torture_ops[i]->name); | 1978 | pr_alert(" %s", torture_ops[i]->name); |
| 1946 | printk(KERN_ALERT "\n"); | 1979 | pr_alert("\n"); |
| 1947 | mutex_unlock(&fullstop_mutex); | 1980 | mutex_unlock(&fullstop_mutex); |
| 1948 | return -EINVAL; | 1981 | return -EINVAL; |
| 1949 | } | 1982 | } |
| 1950 | if (cur_ops->fqs == NULL && fqs_duration != 0) { | 1983 | if (cur_ops->fqs == NULL && fqs_duration != 0) { |
| 1951 | printk(KERN_ALERT "rcu-torture: ->fqs NULL and non-zero fqs_duration, fqs disabled.\n"); | 1984 | pr_alert("rcu-torture: ->fqs NULL and non-zero fqs_duration, fqs disabled.\n"); |
| 1952 | fqs_duration = 0; | 1985 | fqs_duration = 0; |
| 1953 | } | 1986 | } |
| 1954 | if (cur_ops->init) | 1987 | if (cur_ops->init) |
| @@ -1996,14 +2029,15 @@ rcu_torture_init(void) | |||
| 1996 | /* Start up the kthreads. */ | 2029 | /* Start up the kthreads. */ |
| 1997 | 2030 | ||
| 1998 | VERBOSE_PRINTK_STRING("Creating rcu_torture_writer task"); | 2031 | VERBOSE_PRINTK_STRING("Creating rcu_torture_writer task"); |
| 1999 | writer_task = kthread_run(rcu_torture_writer, NULL, | 2032 | writer_task = kthread_create(rcu_torture_writer, NULL, |
| 2000 | "rcu_torture_writer"); | 2033 | "rcu_torture_writer"); |
| 2001 | if (IS_ERR(writer_task)) { | 2034 | if (IS_ERR(writer_task)) { |
| 2002 | firsterr = PTR_ERR(writer_task); | 2035 | firsterr = PTR_ERR(writer_task); |
| 2003 | VERBOSE_PRINTK_ERRSTRING("Failed to create writer"); | 2036 | VERBOSE_PRINTK_ERRSTRING("Failed to create writer"); |
| 2004 | writer_task = NULL; | 2037 | writer_task = NULL; |
| 2005 | goto unwind; | 2038 | goto unwind; |
| 2006 | } | 2039 | } |
| 2040 | wake_up_process(writer_task); | ||
| 2007 | fakewriter_tasks = kzalloc(nfakewriters * sizeof(fakewriter_tasks[0]), | 2041 | fakewriter_tasks = kzalloc(nfakewriters * sizeof(fakewriter_tasks[0]), |
| 2008 | GFP_KERNEL); | 2042 | GFP_KERNEL); |
| 2009 | if (fakewriter_tasks == NULL) { | 2043 | if (fakewriter_tasks == NULL) { |
| @@ -2118,14 +2152,15 @@ rcu_torture_init(void) | |||
| 2118 | } | 2152 | } |
| 2119 | if (shutdown_secs > 0) { | 2153 | if (shutdown_secs > 0) { |
| 2120 | shutdown_time = jiffies + shutdown_secs * HZ; | 2154 | shutdown_time = jiffies + shutdown_secs * HZ; |
| 2121 | shutdown_task = kthread_run(rcu_torture_shutdown, NULL, | 2155 | shutdown_task = kthread_create(rcu_torture_shutdown, NULL, |
| 2122 | "rcu_torture_shutdown"); | 2156 | "rcu_torture_shutdown"); |
| 2123 | if (IS_ERR(shutdown_task)) { | 2157 | if (IS_ERR(shutdown_task)) { |
| 2124 | firsterr = PTR_ERR(shutdown_task); | 2158 | firsterr = PTR_ERR(shutdown_task); |
| 2125 | VERBOSE_PRINTK_ERRSTRING("Failed to create shutdown"); | 2159 | VERBOSE_PRINTK_ERRSTRING("Failed to create shutdown"); |
| 2126 | shutdown_task = NULL; | 2160 | shutdown_task = NULL; |
| 2127 | goto unwind; | 2161 | goto unwind; |
| 2128 | } | 2162 | } |
| 2163 | wake_up_process(shutdown_task); | ||
| 2129 | } | 2164 | } |
| 2130 | i = rcu_torture_onoff_init(); | 2165 | i = rcu_torture_onoff_init(); |
| 2131 | if (i != 0) { | 2166 | if (i != 0) { |
