Subject: track and print last unloaded module in the oops trace
Date: Sun, 6 Jan 2008 15:19:46 -0800
From: Arjan van de Ven <arjan@linux.intel.com>

CC: rusty@rustcorp.com.au
CC: ak@suse.de
CC: mingo@elte.hu

Based on a suggestion from Andi:
In various cases, the unload of a module may leave some bad state around
that causes a kernel crash AFTER a module is unloaded; and it's then hard
to find which module caused that.

This patch tracks the last unloaded module, and prints this as part of the
module list in the oops trace.

Right now, only the last 1 module is tracked; I expect that this is enough
for the vast majority of cases where this information matters; if it turns
out that tracking more is important, we can always extend it to that.

Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
 kernel/module.c |    6 ++++++
 1 file changed, 6 insertions(+)

diff -r 1239f52deb02 kernel/module.c
--- a/kernel/module.c	Tue Jan 08 17:39:23 2008 +1100
+++ b/kernel/module.c	Tue Jan 08 22:53:51 2008 +1100
@@ -71,6 +71,8 @@ static DECLARE_WAIT_QUEUE_HEAD(module_wq
 static DECLARE_WAIT_QUEUE_HEAD(module_wq);
 
 static BLOCKING_NOTIFIER_HEAD(module_notify_list);
+
+static char last_unloaded_module[MODULE_NAME_LEN+1];
 
 int register_module_notifier(struct notifier_block * nb)
 {
@@ -737,6 +739,8 @@ sys_delete_module(const char __user *nam
 		mod->exit();
 		mutex_lock(&module_mutex);
 	}
+	/* Store the name of the last unloaded module for diagnostic purposes */
+	strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module));
 	free_module(mod);
 
  out:
@@ -2519,6 +2523,8 @@ void print_modules(void)
 	printk("Modules linked in:");
 	list_for_each_entry(mod, &modules, list)
 		printk(" %s%s", mod->name, module_flags(mod, buf));
+	if (last_unloaded_module[0])
+		printk(" [last unloaded: %s]", last_unloaded_module);
 	printk("\n");
 }
 
