aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2010-05-26 17:26:17 -0400
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2010-05-26 17:26:29 -0400
commit1ef6acf597559fd1c244190512144c40619299bf (patch)
tree459e74f8c4bebc2d53effbb322ea426e6cca70ce /arch
parent63a6440326e4cd01d6a663069208a0e68e9b833f (diff)
[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>
Diffstat (limited to 'arch')
-rw-r--r--arch/s390/mm/cmm.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c
index f87b34731e1d..c17352634a46 100644
--- a/arch/s390/mm/cmm.c
+++ b/arch/s390/mm/cmm.c
@@ -53,8 +53,8 @@ static struct cmm_page_array *cmm_timed_page_list;
53static DEFINE_SPINLOCK(cmm_lock); 53static DEFINE_SPINLOCK(cmm_lock);
54 54
55static struct task_struct *cmm_thread_ptr; 55static struct task_struct *cmm_thread_ptr;
56static wait_queue_head_t cmm_thread_wait; 56static DECLARE_WAIT_QUEUE_HEAD(cmm_thread_wait);
57static struct timer_list cmm_timer; 57static DEFINE_TIMER(cmm_timer, NULL, 0, 0);
58 58
59static void cmm_timer_fn(unsigned long); 59static void cmm_timer_fn(unsigned long);
60static void cmm_set_timer(void); 60static void cmm_set_timer(void);
@@ -466,8 +466,6 @@ cmm_init (void)
466 rc = register_pm_notifier(&cmm_power_notifier); 466 rc = register_pm_notifier(&cmm_power_notifier);
467 if (rc) 467 if (rc)
468 goto out_pm; 468 goto out_pm;
469 init_waitqueue_head(&cmm_thread_wait);
470 init_timer(&cmm_timer);
471 cmm_thread_ptr = kthread_run(cmm_thread, NULL, "cmmthread"); 469 cmm_thread_ptr = kthread_run(cmm_thread, NULL, "cmmthread");
472 rc = IS_ERR(cmm_thread_ptr) ? PTR_ERR(cmm_thread_ptr) : 0; 470 rc = IS_ERR(cmm_thread_ptr) ? PTR_ERR(cmm_thread_ptr) : 0;
473 if (rc) 471 if (rc)
@@ -487,23 +485,25 @@ out_smsg:
487 unregister_sysctl_table(cmm_sysctl_header); 485 unregister_sysctl_table(cmm_sysctl_header);
488out_sysctl: 486out_sysctl:
489#endif 487#endif
488 del_timer_sync(&cmm_timer);
490 return rc; 489 return rc;
491} 490}
492 491
493static void 492static void
494cmm_exit(void) 493cmm_exit(void)
495{ 494{
496 kthread_stop(cmm_thread_ptr);
497 unregister_pm_notifier(&cmm_power_notifier);
498 unregister_oom_notifier(&cmm_oom_nb);
499 cmm_free_pages(cmm_pages, &cmm_pages, &cmm_page_list);
500 cmm_free_pages(cmm_timed_pages, &cmm_timed_pages, &cmm_timed_page_list);
501#ifdef CONFIG_CMM_PROC 495#ifdef CONFIG_CMM_PROC
502 unregister_sysctl_table(cmm_sysctl_header); 496 unregister_sysctl_table(cmm_sysctl_header);
503#endif 497#endif
504#ifdef CONFIG_CMM_IUCV 498#ifdef CONFIG_CMM_IUCV
505 smsg_unregister_callback(SMSG_PREFIX, cmm_smsg_target); 499 smsg_unregister_callback(SMSG_PREFIX, cmm_smsg_target);
506#endif 500#endif
501 unregister_pm_notifier(&cmm_power_notifier);
502 unregister_oom_notifier(&cmm_oom_nb);
503 kthread_stop(cmm_thread_ptr);
504 del_timer_sync(&cmm_timer);
505 cmm_free_pages(cmm_pages, &cmm_pages, &cmm_page_list);
506 cmm_free_pages(cmm_timed_pages, &cmm_timed_pages, &cmm_timed_page_list);
507} 507}
508 508
509module_init(cmm_init); 509module_init(cmm_init);