aboutsummaryrefslogtreecommitdiffstats
path: root/net/iucv
diff options
context:
space:
mode:
authorUrsula Braun <braunu@de.ibm.com>2007-07-14 22:03:41 -0400
committerDavid S. Miller <davem@davemloft.net>2007-07-14 22:03:41 -0400
commit13fdc9a74df0fec70f421c6891e184ed8c3b9088 (patch)
treeefd81d0f35e2300ee86e538fa8c136654c7c0dae /net/iucv
parentda7de31cc50796a53593785d4508b7b7ffa9a9b2 (diff)
[AF_IUCV]: Avoid deadlock between iucv_path_connect and tasklet.
An iucv deadlock may occur, where one CPU is spinning on the iucv_table_lock for iucv_tasklet_fn(), while another CPU is holding the iucv_table_lock for an iucv_path_connect() and is waiting for the first CPU in an smp_call_function. Solution: replace spin_lock in iucv_tasklet_fn by spin_trylock and reschedule tasklet in case of non-granted lock. Signed-off-by: Ursula Braun <braunu@de.ibm.com> Acked-by: Frank Pavlic <fpavlic@de.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/iucv')
-rw-r--r--net/iucv/iucv.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c
index b7333061016d..ad5150b8dfa9 100644
--- a/net/iucv/iucv.c
+++ b/net/iucv/iucv.c
@@ -1494,7 +1494,10 @@ static void iucv_tasklet_fn(unsigned long ignored)
1494 struct iucv_irq_list *p, *n; 1494 struct iucv_irq_list *p, *n;
1495 1495
1496 /* Serialize tasklet, iucv_path_sever and iucv_path_connect. */ 1496 /* Serialize tasklet, iucv_path_sever and iucv_path_connect. */
1497 spin_lock(&iucv_table_lock); 1497 if (!spin_trylock(&iucv_table_lock)) {
1498 tasklet_schedule(&iucv_tasklet);
1499 return;
1500 }
1498 iucv_active_cpu = smp_processor_id(); 1501 iucv_active_cpu = smp_processor_id();
1499 1502
1500 spin_lock_irq(&iucv_queue_lock); 1503 spin_lock_irq(&iucv_queue_lock);