[S390] cmm: fix crash on module unload

There might be a scheduled cmm_timer if the cmm module gets unloaded.
That timer was not deleted during module unload and thus could lead
to system crash later on.
Besides that reorder function calls in module init and exit code to
avoid a couple of other races which could lead to accesses to
uninitialized data.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

authored by Heiko Carstens and committed by Martin Schwidefsky 1ef6acf5 63a64403

+9 -9
+9 -9
arch/s390/mm/cmm.c
··· 53 53 static DEFINE_SPINLOCK(cmm_lock); 54 54 55 55 static struct task_struct *cmm_thread_ptr; 56 - static wait_queue_head_t cmm_thread_wait; 57 - static struct timer_list cmm_timer; 56 + static DECLARE_WAIT_QUEUE_HEAD(cmm_thread_wait); 57 + static DEFINE_TIMER(cmm_timer, NULL, 0, 0); 58 58 59 59 static void cmm_timer_fn(unsigned long); 60 60 static void cmm_set_timer(void); ··· 466 466 rc = register_pm_notifier(&cmm_power_notifier); 467 467 if (rc) 468 468 goto out_pm; 469 - init_waitqueue_head(&cmm_thread_wait); 470 - init_timer(&cmm_timer); 471 469 cmm_thread_ptr = kthread_run(cmm_thread, NULL, "cmmthread"); 472 470 rc = IS_ERR(cmm_thread_ptr) ? PTR_ERR(cmm_thread_ptr) : 0; 473 471 if (rc) ··· 485 487 unregister_sysctl_table(cmm_sysctl_header); 486 488 out_sysctl: 487 489 #endif 490 + del_timer_sync(&cmm_timer); 488 491 return rc; 489 492 } 490 493 491 494 static void 492 495 cmm_exit(void) 493 496 { 494 - kthread_stop(cmm_thread_ptr); 495 - unregister_pm_notifier(&cmm_power_notifier); 496 - unregister_oom_notifier(&cmm_oom_nb); 497 - cmm_free_pages(cmm_pages, &cmm_pages, &cmm_page_list); 498 - cmm_free_pages(cmm_timed_pages, &cmm_timed_pages, &cmm_timed_page_list); 499 497 #ifdef CONFIG_CMM_PROC 500 498 unregister_sysctl_table(cmm_sysctl_header); 501 499 #endif 502 500 #ifdef CONFIG_CMM_IUCV 503 501 smsg_unregister_callback(SMSG_PREFIX, cmm_smsg_target); 504 502 #endif 503 + unregister_pm_notifier(&cmm_power_notifier); 504 + unregister_oom_notifier(&cmm_oom_nb); 505 + kthread_stop(cmm_thread_ptr); 506 + del_timer_sync(&cmm_timer); 507 + cmm_free_pages(cmm_pages, &cmm_pages, &cmm_page_list); 508 + cmm_free_pages(cmm_timed_pages, &cmm_timed_pages, &cmm_timed_page_list); 505 509 } 506 510 507 511 module_init(cmm_init);