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 f8fcc3d10327..16ce9cd4f39e 100644 --- a/net/iucv/Kconfig +++ b/net/iucv/Kconfig | |||
@@ -1,13 +1,13 @@ | |||
1 | config IUCV | 1 | config IUCV |
2 | tristate "IUCV support (VM only)" | 2 | tristate "IUCV support (S390 - z/VM only)" |
3 | depends on S390 | 3 | depends on S390 |
4 | help | 4 | help |
5 | Select this option if you want to use inter-user communication under | 5 | Select this option if you want to use inter-user communication |
6 | VM or VIF sockets. If you run on z/VM, say "Y" to enable a fast | 6 | under VM or VIF. If you run on z/VM, say "Y" to enable a fast |
7 | communication link between VM guests. | 7 | communication link between VM guests. |
8 | 8 | ||
9 | config AFIUCV | 9 | config AFIUCV |
10 | tristate "AF_IUCV support (VM only)" | 10 | tristate "AF_IUCV support (S390 - z/VM only)" |
11 | depends on IUCV | 11 | depends on IUCV |
12 | help | 12 | help |
13 | Select this option if you want to use inter-user communication under | 13 | 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 d9e9ddb8eac5..53ae14c35f70 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) | |||
219 | 219 | ||
220 | sock_init_data(sock, sk); | 220 | sock_init_data(sock, sk); |
221 | INIT_LIST_HEAD(&iucv_sk(sk)->accept_q); | 221 | INIT_LIST_HEAD(&iucv_sk(sk)->accept_q); |
222 | spin_lock_init(&iucv_sk(sk)->accept_q_lock); | ||
222 | skb_queue_head_init(&iucv_sk(sk)->send_skb_q); | 223 | skb_queue_head_init(&iucv_sk(sk)->send_skb_q); |
223 | skb_queue_head_init(&iucv_sk(sk)->backlog_skb_q); | 224 | skb_queue_head_init(&iucv_sk(sk)->backlog_skb_q); |
224 | iucv_sk(sk)->send_tag = 0; | 225 | iucv_sk(sk)->send_tag = 0; |
@@ -274,15 +275,25 @@ void iucv_sock_unlink(struct iucv_sock_list *l, struct sock *sk) | |||
274 | 275 | ||
275 | void iucv_accept_enqueue(struct sock *parent, struct sock *sk) | 276 | void iucv_accept_enqueue(struct sock *parent, struct sock *sk) |
276 | { | 277 | { |
278 | unsigned long flags; | ||
279 | struct iucv_sock *par = iucv_sk(parent); | ||
280 | |||
277 | sock_hold(sk); | 281 | sock_hold(sk); |
278 | list_add_tail(&iucv_sk(sk)->accept_q, &iucv_sk(parent)->accept_q); | 282 | spin_lock_irqsave(&par->accept_q_lock, flags); |
283 | list_add_tail(&iucv_sk(sk)->accept_q, &par->accept_q); | ||
284 | spin_unlock_irqrestore(&par->accept_q_lock, flags); | ||
279 | iucv_sk(sk)->parent = parent; | 285 | iucv_sk(sk)->parent = parent; |
280 | parent->sk_ack_backlog++; | 286 | parent->sk_ack_backlog++; |
281 | } | 287 | } |
282 | 288 | ||
283 | void iucv_accept_unlink(struct sock *sk) | 289 | void iucv_accept_unlink(struct sock *sk) |
284 | { | 290 | { |
291 | unsigned long flags; | ||
292 | struct iucv_sock *par = iucv_sk(iucv_sk(sk)->parent); | ||
293 | |||
294 | spin_lock_irqsave(&par->accept_q_lock, flags); | ||
285 | list_del_init(&iucv_sk(sk)->accept_q); | 295 | list_del_init(&iucv_sk(sk)->accept_q); |
296 | spin_unlock_irqrestore(&par->accept_q_lock, flags); | ||
286 | iucv_sk(sk)->parent->sk_ack_backlog--; | 297 | iucv_sk(sk)->parent->sk_ack_backlog--; |
287 | iucv_sk(sk)->parent = NULL; | 298 | iucv_sk(sk)->parent = NULL; |
288 | sock_put(sk); | 299 | sock_put(sk); |
@@ -298,8 +309,8 @@ struct sock *iucv_accept_dequeue(struct sock *parent, struct socket *newsock) | |||
298 | lock_sock(sk); | 309 | lock_sock(sk); |
299 | 310 | ||
300 | if (sk->sk_state == IUCV_CLOSED) { | 311 | if (sk->sk_state == IUCV_CLOSED) { |
301 | release_sock(sk); | ||
302 | iucv_accept_unlink(sk); | 312 | iucv_accept_unlink(sk); |
313 | release_sock(sk); | ||
303 | continue; | 314 | continue; |
304 | } | 315 | } |
305 | 316 | ||
@@ -879,6 +890,7 @@ static int iucv_callback_connreq(struct iucv_path *path, | |||
879 | /* Find out if this path belongs to af_iucv. */ | 890 | /* Find out if this path belongs to af_iucv. */ |
880 | read_lock(&iucv_sk_list.lock); | 891 | read_lock(&iucv_sk_list.lock); |
881 | iucv = NULL; | 892 | iucv = NULL; |
893 | sk = NULL; | ||
882 | sk_for_each(sk, node, &iucv_sk_list.head) | 894 | sk_for_each(sk, node, &iucv_sk_list.head) |
883 | if (sk->sk_state == IUCV_LISTEN && | 895 | if (sk->sk_state == IUCV_LISTEN && |
884 | !memcmp(&iucv_sk(sk)->src_name, src_name, 8)) { | 896 | !memcmp(&iucv_sk(sk)->src_name, src_name, 8)) { |
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); |