Index: linux-2.6.30.x86_64/drivers/char/sysrq.c
===================================================================
--- linux-2.6.30.x86_64.orig/drivers/char/sysrq.c
+++ linux-2.6.30.x86_64/drivers/char/sysrq.c
@@ -253,6 +253,18 @@ static struct sysrq_key_op sysrq_showreg
 	.enable_mask	= SYSRQ_ENABLE_DUMP,
 };
 
+static void sysrq_handle_showeventd(int key, struct tty_struct *tty)
+{
+	printk(KERN_INFO "Showing keventd status, jiffies=%lu\n", jiffies);
+	print_eventd();
+}
+static struct sysrq_key_op sysrq_showeventd_op = {
+	.handler	= sysrq_handle_showeventd,
+	.help_msg	= "show-eventd(/)",
+	.action_msg	= "Show Keventd State",
+	.enable_mask	= SYSRQ_ENABLE_DUMP,
+};
+
 static void sysrq_handle_showstate(int key, struct tty_struct *tty)
 {
 	show_state();
@@ -386,7 +398,7 @@ static struct sysrq_key_op sysrq_unrt_op
 /* Key Operations table and lock */
 static DEFINE_SPINLOCK(sysrq_key_table_lock);
 
-static struct sysrq_key_op *sysrq_key_table[36] = {
+static struct sysrq_key_op *sysrq_key_table[37] = {
 	&sysrq_loglevel_op,		/* 0 */
 	&sysrq_loglevel_op,		/* 1 */
 	&sysrq_loglevel_op,		/* 2 */
@@ -441,6 +453,7 @@ static struct sysrq_key_op *sysrq_key_ta
 	/* y: May be registered on sparc64 for global register dump */
 	NULL,				/* y */
 	&sysrq_ftrace_dump_op,		/* z */
+	&sysrq_showeventd_op,		/* / */
 };
 
 /* key2index calculation, -1 on invalid index */
@@ -452,6 +465,8 @@ static int sysrq_key_table_key2index(int
 		retval = key - '0';
 	else if ((key >= 'a') && (key <= 'z'))
 		retval = key + 10 - 'a';
+	else if (key == '/')
+		retval = 36;
 	else
 		retval = -1;
 	return retval;
Index: linux-2.6.30.x86_64/kernel/workqueue.c
===================================================================
--- linux-2.6.30.x86_64.orig/kernel/workqueue.c
+++ linux-2.6.30.x86_64/kernel/workqueue.c
@@ -35,6 +35,8 @@
 #include <linux/lockdep.h>
 #include <trace/workqueue.h>
 
+#define CONFIG_SYSRQ_WQ 1
+
 /*
  * The per-CPU workqueue (if single thread, we always use the first
  * possible cpu).
@@ -49,6 +51,10 @@ struct cpu_workqueue_struct {
 
 	struct workqueue_struct *wq;
 	struct task_struct *thread;
+#ifdef CONFIG_SYSRQ_WQ
+	work_func_t current_fn, previous_fn;
+	typeof(jiffies) previous_time;
+#endif
 } ____cacheline_aligned;
 
 /*
@@ -271,6 +277,9 @@ static void run_workqueue(struct cpu_wor
 		struct work_struct *work = list_entry(cwq->worklist.next,
 						struct work_struct, entry);
 		work_func_t f = work->func;
+#ifdef CONFIG_SYSRQ_WQ
+		cwq->current_fn = f;
+#endif
 #ifdef CONFIG_LOCKDEP
 		/*
 		 * It is permissible to free the struct work_struct
@@ -307,6 +316,11 @@ static void run_workqueue(struct cpu_wor
 		}
 
 		spin_lock_irq(&cwq->lock);
+#ifdef CONFIG_SYSRQ_WQ
+		cwq->previous_fn = f;
+		cwq->previous_time = jiffies;
+		cwq->current_fn = NULL;
+#endif
 		cwq->current_work = NULL;
 	}
 	spin_unlock_irq(&cwq->lock);
@@ -1023,3 +1037,26 @@ void __init init_workqueues(void)
 	keventd_wq = create_workqueue("events");
 	BUG_ON(!keventd_wq);
 }
+
+#ifdef CONFIG_SYSRQ_WQ
+void print_eventd(void)
+{
+	struct cpu_workqueue_struct *cwq;
+	struct workqueue_struct *wq;
+	unsigned int cpu;
+
+	spin_lock(&workqueue_lock);
+	list_for_each_entry(wq, &workqueues, list) {
+		if (strcmp(wq->name, "events"))
+			continue;
+		for_each_cpu(cpu, cpu_populated_map) {
+			cwq = per_cpu_ptr(wq->cpu_wq, cpu);
+			printk(KERN_INFO "%u: last @%lu: ", cpu, cwq->previous_time);
+			print_symbol("%s  ", (unsigned long)cwq->previous_fn);
+			print_symbol("curr %s\n", (unsigned long)cwq->current_fn);
+		}
+		break;
+	}
+	spin_unlock(&workqueue_lock);
+}
+#endif
Index: linux-2.6.30.x86_64/include/linux/workqueue.h
===================================================================
--- linux-2.6.30.x86_64.orig/include/linux/workqueue.h
+++ linux-2.6.30.x86_64/include/linux/workqueue.h
@@ -224,6 +224,8 @@ extern int flush_work(struct work_struct
 
 extern int cancel_work_sync(struct work_struct *work);
 
+extern void print_eventd(void);
+
 /*
  * Kill off a pending schedule_delayed_work().  Note that the work callback
  * function may still be running on return from cancel_delayed_work(), unless
