From b7c2aecc0747f5c86a1959bce6a7ce8170a556b0 Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Thu, 12 Nov 2009 21:46:27 +0000 Subject: iucv: add work_queue cleanup for suspend If iucv_work_queue is not empty during kernel freeze, a kernel panic occurs. This suspend-patch adds flushing of the work queue for pending connection requests and severing of remaining pending connections. Signed-off-by: Ursula Braun Signed-off-by: David S. Miller --- net/iucv/iucv.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c index 3973d0e..3b1f5f5 100644 --- a/net/iucv/iucv.c +++ b/net/iucv/iucv.c @@ -1768,7 +1768,6 @@ static void iucv_tasklet_fn(unsigned long ignored) */ static void iucv_work_fn(struct work_struct *work) { - typedef void iucv_irq_fn(struct iucv_irq_data *); LIST_HEAD(work_queue); struct iucv_irq_list *p, *n; @@ -1878,14 +1877,25 @@ int iucv_path_table_empty(void) static int iucv_pm_freeze(struct device *dev) { int cpu; + struct iucv_irq_list *p, *n; int rc = 0; #ifdef CONFIG_PM_DEBUG printk(KERN_WARNING "iucv_pm_freeze\n"); #endif + if (iucv_pm_state != IUCV_PM_FREEZING) { + for_each_cpu_mask_nr(cpu, iucv_irq_cpumask) + smp_call_function_single(cpu, iucv_block_cpu_almost, + NULL, 1); + cancel_work_sync(&iucv_work); + list_for_each_entry_safe(p, n, &iucv_work_queue, list) { + list_del_init(&p->list); + iucv_sever_pathid(p->data.ippathid, + iucv_error_no_listener); + kfree(p); + } + } iucv_pm_state = IUCV_PM_FREEZING; - for_each_cpu_mask_nr(cpu, iucv_irq_cpumask) - smp_call_function_single(cpu, iucv_block_cpu_almost, NULL, 1); if (dev->driver && dev->driver->pm && dev->driver->pm->freeze) rc = dev->driver->pm->freeze(dev); if (iucv_path_table_empty()) -- cgit v1.1