diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/unix/af_unix.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index aca650109425..e9a287bc3142 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -565,6 +565,14 @@ static struct proto unix_proto = { | |||
565 | .obj_size = sizeof(struct unix_sock), | 565 | .obj_size = sizeof(struct unix_sock), |
566 | }; | 566 | }; |
567 | 567 | ||
568 | /* | ||
569 | * AF_UNIX sockets do not interact with hardware, hence they | ||
570 | * dont trigger interrupts - so it's safe for them to have | ||
571 | * bh-unsafe locking for their sk_receive_queue.lock. Split off | ||
572 | * this special lock-class by reinitializing the spinlock key: | ||
573 | */ | ||
574 | static struct lock_class_key af_unix_sk_receive_queue_lock_key; | ||
575 | |||
568 | static struct sock * unix_create1(struct socket *sock) | 576 | static struct sock * unix_create1(struct socket *sock) |
569 | { | 577 | { |
570 | struct sock *sk = NULL; | 578 | struct sock *sk = NULL; |
@@ -580,6 +588,8 @@ static struct sock * unix_create1(struct socket *sock) | |||
580 | atomic_inc(&unix_nr_socks); | 588 | atomic_inc(&unix_nr_socks); |
581 | 589 | ||
582 | sock_init_data(sock,sk); | 590 | sock_init_data(sock,sk); |
591 | lockdep_set_class(&sk->sk_receive_queue.lock, | ||
592 | &af_unix_sk_receive_queue_lock_key); | ||
583 | 593 | ||
584 | sk->sk_write_space = unix_write_space; | 594 | sk->sk_write_space = unix_write_space; |
585 | sk->sk_max_ack_backlog = sysctl_unix_max_dgram_qlen; | 595 | sk->sk_max_ack_backlog = sysctl_unix_max_dgram_qlen; |
@@ -1045,7 +1055,7 @@ restart: | |||
1045 | goto out_unlock; | 1055 | goto out_unlock; |
1046 | } | 1056 | } |
1047 | 1057 | ||
1048 | unix_state_wlock(sk); | 1058 | unix_state_wlock_nested(sk); |
1049 | 1059 | ||
1050 | if (sk->sk_state != st) { | 1060 | if (sk->sk_state != st) { |
1051 | unix_state_wunlock(sk); | 1061 | unix_state_wunlock(sk); |