From 9515066f6edd15c1527ee5756d4dcdf22e23fa33 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 3 Jul 2006 00:25:12 -0700 Subject: [PATCH] --- yaml --- r: 31825 b: refs/heads/master c: a09785a2414afb261d9f719d544742af4300df22 h: refs/heads/master i: 31823: b86668ece16df4bdc2342c5c93257c97454aa7c4 v: v3 --- [refs] | 2 +- trunk/include/net/af_unix.h | 3 +++ trunk/net/unix/af_unix.c | 12 +++++++++++- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index 4cde954fd00d..0258576fd392 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: da21f24dd73954c2ed0cd39a698e2c9916c05d71 +refs/heads/master: a09785a2414afb261d9f719d544742af4300df22 diff --git a/trunk/include/net/af_unix.h b/trunk/include/net/af_unix.h index 5ba72d95280c..2fec827c8801 100644 --- a/trunk/include/net/af_unix.h +++ b/trunk/include/net/af_unix.h @@ -67,6 +67,9 @@ struct unix_skb_parms { #define unix_state_rlock(s) spin_lock(&unix_sk(s)->lock) #define unix_state_runlock(s) spin_unlock(&unix_sk(s)->lock) #define unix_state_wlock(s) spin_lock(&unix_sk(s)->lock) +#define unix_state_wlock_nested(s) \ + spin_lock_nested(&unix_sk(s)->lock, \ + SINGLE_DEPTH_NESTING) #define unix_state_wunlock(s) spin_unlock(&unix_sk(s)->lock) #ifdef __KERNEL__ diff --git a/trunk/net/unix/af_unix.c b/trunk/net/unix/af_unix.c index aca650109425..e9a287bc3142 100644 --- a/trunk/net/unix/af_unix.c +++ b/trunk/net/unix/af_unix.c @@ -565,6 +565,14 @@ static struct proto unix_proto = { .obj_size = sizeof(struct unix_sock), }; +/* + * AF_UNIX sockets do not interact with hardware, hence they + * dont trigger interrupts - so it's safe for them to have + * bh-unsafe locking for their sk_receive_queue.lock. Split off + * this special lock-class by reinitializing the spinlock key: + */ +static struct lock_class_key af_unix_sk_receive_queue_lock_key; + static struct sock * unix_create1(struct socket *sock) { struct sock *sk = NULL; @@ -580,6 +588,8 @@ static struct sock * unix_create1(struct socket *sock) atomic_inc(&unix_nr_socks); sock_init_data(sock,sk); + lockdep_set_class(&sk->sk_receive_queue.lock, + &af_unix_sk_receive_queue_lock_key); sk->sk_write_space = unix_write_space; sk->sk_max_ack_backlog = sysctl_unix_max_dgram_qlen; @@ -1045,7 +1055,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, goto out_unlock; } - unix_state_wlock(sk); + unix_state_wlock_nested(sk); if (sk->sk_state != st) { unix_state_wunlock(sk);