diff options
Diffstat (limited to 'net/iucv')
-rw-r--r-- | net/iucv/Kconfig | 8 | ||||
-rw-r--r-- | net/iucv/af_iucv.c | 16 | ||||
-rw-r--r-- | net/iucv/iucv.c | 5 |
3 files changed, 22 insertions, 7 deletions
diff --git a/net/iucv/Kconfig b/net/iucv/Kconfig index f8fcc3d1032..16ce9cd4f39 100644 --- a/net/iucv/Kconfig +++ b/net/iucv/Kconfig @@ -1,13 +1,13 @@ config IUCV - tristate "IUCV support (VM only)" + tristate "IUCV support (S390 - z/VM only)" depends on S390 help - Select this option if you want to use inter-user communication under - VM or VIF sockets. If you run on z/VM, say "Y" to enable a fast + Select this option if you want to use inter-user communication + under VM or VIF. If you run on z/VM, say "Y" to enable a fast communication link between VM guests. config AFIUCV - tristate "AF_IUCV support (VM only)" + tristate "AF_IUCV support (S390 - z/VM only)" depends on IUCV help Select this option if you want to use inter-user communication under diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index d9e9ddb8eac..53ae14c35f7 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c @@ -219,6 +219,7 @@ static struct sock *iucv_sock_alloc(struct socket *sock, int proto, gfp_t prio) sock_init_data(sock, sk); INIT_LIST_HEAD(&iucv_sk(sk)->accept_q); + spin_lock_init(&iucv_sk(sk)->accept_q_lock); skb_queue_head_init(&iucv_sk(sk)->send_skb_q); skb_queue_head_init(&iucv_sk(sk)->backlog_skb_q); iucv_sk(sk)->send_tag = 0; @@ -274,15 +275,25 @@ void iucv_sock_unlink(struct iucv_sock_list *l, struct sock *sk) void iucv_accept_enqueue(struct sock *parent, struct sock *sk) { + unsigned long flags; + struct iucv_sock *par = iucv_sk(parent); + sock_hold(sk); - list_add_tail(&iucv_sk(sk)->accept_q, &iucv_sk(parent)->accept_q); + spin_lock_irqsave(&par->accept_q_lock, flags); + list_add_tail(&iucv_sk(sk)->accept_q, &par->accept_q); + spin_unlock_irqrestore(&par->accept_q_lock, flags); iucv_sk(sk)->parent = parent; parent->sk_ack_backlog++; } void iucv_accept_unlink(struct sock *sk) { + unsigned long flags; + struct iucv_sock *par = iucv_sk(iucv_sk(sk)->parent); + + spin_lock_irqsave(&par->accept_q_lock, flags); list_del_init(&iucv_sk(sk)->accept_q); + spin_unlock_irqrestore(&par->accept_q_lock, flags); iucv_sk(sk)->parent->sk_ack_backlog--; iucv_sk(sk)->parent = NULL; sock_put(sk); @@ -298,8 +309,8 @@ struct sock *iucv_accept_dequeue(struct sock *parent, struct socket *newsock) lock_sock(sk); if (sk->sk_state == IUCV_CLOSED) { - release_sock(sk); iucv_accept_unlink(sk); + release_sock(sk); continue; } @@ -879,6 +890,7 @@ static int iucv_callback_connreq(struct iucv_path *path, /* Find out if this path belongs to af_iucv. */ read_lock(&iucv_sk_list.lock); iucv = NULL; + sk = NULL; sk_for_each(sk, node, &iucv_sk_list.head) if (sk->sk_state == IUCV_LISTEN && !memcmp(&iucv_sk(sk)->src_name, src_name, 8)) { diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c index b7333061016..ad5150b8dfa 100644 --- a/net/iucv/iucv.c +++ b/net/iucv/iucv.c @@ -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); |