diff options
Diffstat (limited to 'kernel/torture.c')
-rw-r--r-- | kernel/torture.c | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/kernel/torture.c b/kernel/torture.c index 41ae5cc3c4c3..b02fa2785bbb 100644 --- a/kernel/torture.c +++ b/kernel/torture.c | |||
@@ -54,8 +54,7 @@ static bool verbose; | |||
54 | 54 | ||
55 | int fullstop = FULLSTOP_RMMOD; | 55 | int fullstop = FULLSTOP_RMMOD; |
56 | EXPORT_SYMBOL_GPL(fullstop); | 56 | EXPORT_SYMBOL_GPL(fullstop); |
57 | DEFINE_MUTEX(fullstop_mutex); | 57 | static DEFINE_MUTEX(fullstop_mutex); |
58 | EXPORT_SYMBOL_GPL(fullstop_mutex); | ||
59 | 58 | ||
60 | #ifdef CONFIG_HOTPLUG_CPU | 59 | #ifdef CONFIG_HOTPLUG_CPU |
61 | 60 | ||
@@ -422,15 +421,33 @@ EXPORT_SYMBOL_GPL(torture_shuffle_cleanup); | |||
422 | void torture_shutdown_absorb(const char *title) | 421 | void torture_shutdown_absorb(const char *title) |
423 | { | 422 | { |
424 | while (ACCESS_ONCE(fullstop) == FULLSTOP_SHUTDOWN) { | 423 | while (ACCESS_ONCE(fullstop) == FULLSTOP_SHUTDOWN) { |
425 | pr_notice( | 424 | pr_notice("torture thread %s parking due to system shutdown\n", |
426 | "torture thread %s parking due to system shutdown\n", | 425 | title); |
427 | title); | ||
428 | schedule_timeout_uninterruptible(MAX_SCHEDULE_TIMEOUT); | 426 | schedule_timeout_uninterruptible(MAX_SCHEDULE_TIMEOUT); |
429 | } | 427 | } |
430 | } | 428 | } |
431 | EXPORT_SYMBOL_GPL(torture_shutdown_absorb); | 429 | EXPORT_SYMBOL_GPL(torture_shutdown_absorb); |
432 | 430 | ||
433 | /* | 431 | /* |
432 | * Detect and respond to a system shutdown. | ||
433 | */ | ||
434 | static int torture_shutdown_notify(struct notifier_block *unused1, | ||
435 | unsigned long unused2, void *unused3) | ||
436 | { | ||
437 | mutex_lock(&fullstop_mutex); | ||
438 | if (fullstop == FULLSTOP_DONTSTOP) | ||
439 | fullstop = FULLSTOP_SHUTDOWN; | ||
440 | else | ||
441 | pr_warn("Concurrent rmmod and shutdown illegal!\n"); | ||
442 | mutex_unlock(&fullstop_mutex); | ||
443 | return NOTIFY_DONE; | ||
444 | } | ||
445 | |||
446 | static struct notifier_block torture_shutdown_nb = { | ||
447 | .notifier_call = torture_shutdown_notify, | ||
448 | }; | ||
449 | |||
450 | /* | ||
434 | * Initialize torture module. Please note that this is -not- invoked via | 451 | * Initialize torture module. Please note that this is -not- invoked via |
435 | * the usual module_init() mechanism, but rather by an explicit call from | 452 | * the usual module_init() mechanism, but rather by an explicit call from |
436 | * the client torture module. This call must be paired with a later | 453 | * the client torture module. This call must be paired with a later |
@@ -451,6 +468,7 @@ EXPORT_SYMBOL_GPL(torture_init_begin); | |||
451 | void __init torture_init_end(void) | 468 | void __init torture_init_end(void) |
452 | { | 469 | { |
453 | mutex_unlock(&fullstop_mutex); | 470 | mutex_unlock(&fullstop_mutex); |
471 | register_reboot_notifier(&torture_shutdown_nb); | ||
454 | } | 472 | } |
455 | EXPORT_SYMBOL_GPL(torture_init_end); | 473 | EXPORT_SYMBOL_GPL(torture_init_end); |
456 | 474 | ||
@@ -474,6 +492,7 @@ bool torture_cleanup(void) | |||
474 | } | 492 | } |
475 | fullstop = FULLSTOP_RMMOD; | 493 | fullstop = FULLSTOP_RMMOD; |
476 | mutex_unlock(&fullstop_mutex); | 494 | mutex_unlock(&fullstop_mutex); |
495 | unregister_reboot_notifier(&torture_shutdown_nb); | ||
477 | torture_shuffle_cleanup(); | 496 | torture_shuffle_cleanup(); |
478 | torture_onoff_cleanup(); | 497 | torture_onoff_cleanup(); |
479 | return false; | 498 | return false; |