]> err.no Git - linux-2.6/commitdiff
[AF_IUCV]: Avoid deadlock between iucv_path_connect and tasklet.
authorUrsula Braun <braunu@de.ibm.com>
Sun, 15 Jul 2007 02:03:41 +0000 (19:03 -0700)
committerDavid S. Miller <davem@davemloft.net>
Sun, 15 Jul 2007 02:03:41 +0000 (19:03 -0700)
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>
net/iucv/iucv.c

index b7333061016dfffbf8122460f63dda56e724a3c8..ad5150b8dfa9b583a20a73a2d03a348a386e4d10 100644 (file)
@@ -1494,7 +1494,10 @@ static void iucv_tasklet_fn(unsigned long ignored)
        struct iucv_irq_list *p, *n;
 
        /* Serialize tasklet, iucv_path_sever and iucv_path_connect. */
-       spin_lock(&iucv_table_lock);
+       if (!spin_trylock(&iucv_table_lock)) {
+               tasklet_schedule(&iucv_tasklet);
+               return;
+       }
        iucv_active_cpu = smp_processor_id();
 
        spin_lock_irq(&iucv_queue_lock);