Skip to contentSkip to conversation

perform reboot notification in process context

PATCH New Andrew Morton 1 participant 1 message Mar 4, 2001

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 perform reboot notification in process context

ctrl_alt_del() is called from hard interrupt context. It traverses the reboot_notifier_list. Many of the callouts on that list are not designed to be called in this context.

DAC960_Finalise()
Calls remove_proc_entry() within interrupt context. remove_proc_entry uses spin_lock()s.
Can deadlock.

drivers/char/sbc60xxwdt.c:sbc60xxwdt_unload()
Calls misc_deregister which calls down().

drivers/i2o/i2o_core.c
calls i2o_post_wait()
calls i2o_reset_controller()

Both of these schedule(). Crashes every time.

drivers/scsi/gdth.c

        gdth_halt()
        calls gdth_do_cmd
                does down().

This patch makes keventd do the callout.

kernel/sys.c +13 -4
@@ -330,6 +330,12 @@
 	return 0;
 }
 
+static void deferred_cad(void *dummy)
+{
+	notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
+	machine_restart(NULL);
+}
+
 /*
  * This function gets called by ctrl-alt-del - ie the keyboard interrupt.
  * As it's called within an interrupt, it may NOT sync: the only choice
@@ -337,10 +343,13 @@
  */
 void ctrl_alt_del(void)
 {
-	if (C_A_D) {
-		notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
-		machine_restart(NULL);
-	} else
+	static struct tq_struct cad_tq = {
+		routine: deferred_cad,
+	};
+
+	if (C_A_D)
+		schedule_task(&cad_tq);
+	else
 		kill_proc(1, SIGINT, 1);
 }