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) { |