aboutsummaryrefslogtreecommitdiffstats
path: root/net/unix
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2005-12-14 02:26:29 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-01-03 16:10:59 -0500
commitfbe9cc4a87030d5cad5f944ffaef6af7efd119e4 (patch)
treef4e9ce6608e1b8b7e160e44e68853a2b6e5e84d5 /net/unix
parentd83d8461f902c672bc1bd8fbc6a94e19f092da97 (diff)
[AF_UNIX]: Use spinlock for unix_table_lock
This lock is actually taken mostly as a writer, so using a rwlock actually just makes performance worse especially on chips like the Intel P4. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/unix')
-rw-r--r--net/unix/af_unix.c34
-rw-r--r--net/unix/garbage.c4
2 files changed, 19 insertions, 19 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 1dc3685048f3..04e850e04e3d 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -121,7 +121,7 @@
121int sysctl_unix_max_dgram_qlen = 10; 121int sysctl_unix_max_dgram_qlen = 10;
122 122
123struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1]; 123struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
124DEFINE_RWLOCK(unix_table_lock); 124DEFINE_SPINLOCK(unix_table_lock);
125static atomic_t unix_nr_socks = ATOMIC_INIT(0); 125static atomic_t unix_nr_socks = ATOMIC_INIT(0);
126 126
127#define unix_sockets_unbound (&unix_socket_table[UNIX_HASH_SIZE]) 127#define unix_sockets_unbound (&unix_socket_table[UNIX_HASH_SIZE])
@@ -130,7 +130,7 @@ static atomic_t unix_nr_socks = ATOMIC_INIT(0);
130 130
131/* 131/*
132 * SMP locking strategy: 132 * SMP locking strategy:
133 * hash table is protected with rwlock unix_table_lock 133 * hash table is protected with spinlock unix_table_lock
134 * each socket state is protected by separate rwlock. 134 * each socket state is protected by separate rwlock.
135 */ 135 */
136 136
@@ -214,16 +214,16 @@ static void __unix_insert_socket(struct hlist_head *list, struct sock *sk)
214 214
215static inline void unix_remove_socket(struct sock *sk) 215static inline void unix_remove_socket(struct sock *sk)
216{ 216{
217 write_lock(&unix_table_lock); 217 spin_lock(&unix_table_lock);
218 __unix_remove_socket(sk); 218 __unix_remove_socket(sk);
219 write_unlock(&unix_table_lock); 219 spin_unlock(&unix_table_lock);
220} 220}
221 221
222static inline void unix_insert_socket(struct hlist_head *list, struct sock *sk) 222static inline void unix_insert_socket(struct hlist_head *list, struct sock *sk)
223{ 223{
224 write_lock(&unix_table_lock); 224 spin_lock(&unix_table_lock);
225 __unix_insert_socket(list, sk); 225 __unix_insert_socket(list, sk);
226 write_unlock(&unix_table_lock); 226 spin_unlock(&unix_table_lock);
227} 227}
228 228
229static struct sock *__unix_find_socket_byname(struct sockaddr_un *sunname, 229static struct sock *__unix_find_socket_byname(struct sockaddr_un *sunname,
@@ -250,11 +250,11 @@ static inline struct sock *unix_find_socket_byname(struct sockaddr_un *sunname,
250{ 250{
251 struct sock *s; 251 struct sock *s;
252 252
253 read_lock(&unix_table_lock); 253 spin_lock(&unix_table_lock);
254 s = __unix_find_socket_byname(sunname, len, type, hash); 254 s = __unix_find_socket_byname(sunname, len, type, hash);
255 if (s) 255 if (s)
256 sock_hold(s); 256 sock_hold(s);
257 read_unlock(&unix_table_lock); 257 spin_unlock(&unix_table_lock);
258 return s; 258 return s;
259} 259}
260 260
@@ -263,7 +263,7 @@ static struct sock *unix_find_socket_byinode(struct inode *i)
263 struct sock *s; 263 struct sock *s;
264 struct hlist_node *node; 264 struct hlist_node *node;
265 265
266 read_lock(&unix_table_lock); 266 spin_lock(&unix_table_lock);
267 sk_for_each(s, node, 267 sk_for_each(s, node,
268 &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) { 268 &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) {
269 struct dentry *dentry = unix_sk(s)->dentry; 269 struct dentry *dentry = unix_sk(s)->dentry;
@@ -276,7 +276,7 @@ static struct sock *unix_find_socket_byinode(struct inode *i)
276 } 276 }
277 s = NULL; 277 s = NULL;
278found: 278found:
279 read_unlock(&unix_table_lock); 279 spin_unlock(&unix_table_lock);
280 return s; 280 return s;
281} 281}
282 282
@@ -642,12 +642,12 @@ retry:
642 addr->len = sprintf(addr->name->sun_path+1, "%05x", ordernum) + 1 + sizeof(short); 642 addr->len = sprintf(addr->name->sun_path+1, "%05x", ordernum) + 1 + sizeof(short);
643 addr->hash = unix_hash_fold(csum_partial((void*)addr->name, addr->len, 0)); 643 addr->hash = unix_hash_fold(csum_partial((void*)addr->name, addr->len, 0));
644 644
645 write_lock(&unix_table_lock); 645 spin_lock(&unix_table_lock);
646 ordernum = (ordernum+1)&0xFFFFF; 646 ordernum = (ordernum+1)&0xFFFFF;
647 647
648 if (__unix_find_socket_byname(addr->name, addr->len, sock->type, 648 if (__unix_find_socket_byname(addr->name, addr->len, sock->type,
649 addr->hash)) { 649 addr->hash)) {
650 write_unlock(&unix_table_lock); 650 spin_unlock(&unix_table_lock);
651 /* Sanity yield. It is unusual case, but yet... */ 651 /* Sanity yield. It is unusual case, but yet... */
652 if (!(ordernum&0xFF)) 652 if (!(ordernum&0xFF))
653 yield(); 653 yield();
@@ -658,7 +658,7 @@ retry:
658 __unix_remove_socket(sk); 658 __unix_remove_socket(sk);
659 u->addr = addr; 659 u->addr = addr;
660 __unix_insert_socket(&unix_socket_table[addr->hash], sk); 660 __unix_insert_socket(&unix_socket_table[addr->hash], sk);
661 write_unlock(&unix_table_lock); 661 spin_unlock(&unix_table_lock);
662 err = 0; 662 err = 0;
663 663
664out: up(&u->readsem); 664out: up(&u->readsem);
@@ -791,7 +791,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
791 addr->hash = UNIX_HASH_SIZE; 791 addr->hash = UNIX_HASH_SIZE;
792 } 792 }
793 793
794 write_lock(&unix_table_lock); 794 spin_lock(&unix_table_lock);
795 795
796 if (!sunaddr->sun_path[0]) { 796 if (!sunaddr->sun_path[0]) {
797 err = -EADDRINUSE; 797 err = -EADDRINUSE;
@@ -814,7 +814,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
814 __unix_insert_socket(list, sk); 814 __unix_insert_socket(list, sk);
815 815
816out_unlock: 816out_unlock:
817 write_unlock(&unix_table_lock); 817 spin_unlock(&unix_table_lock);
818out_up: 818out_up:
819 up(&u->readsem); 819 up(&u->readsem);
820out: 820out:
@@ -1916,7 +1916,7 @@ static struct sock *unix_seq_idx(int *iter, loff_t pos)
1916 1916
1917static void *unix_seq_start(struct seq_file *seq, loff_t *pos) 1917static void *unix_seq_start(struct seq_file *seq, loff_t *pos)
1918{ 1918{
1919 read_lock(&unix_table_lock); 1919 spin_lock(&unix_table_lock);
1920 return *pos ? unix_seq_idx(seq->private, *pos - 1) : ((void *) 1); 1920 return *pos ? unix_seq_idx(seq->private, *pos - 1) : ((void *) 1);
1921} 1921}
1922 1922
@@ -1931,7 +1931,7 @@ static void *unix_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1931 1931
1932static void unix_seq_stop(struct seq_file *seq, void *v) 1932static void unix_seq_stop(struct seq_file *seq, void *v)
1933{ 1933{
1934 read_unlock(&unix_table_lock); 1934 spin_unlock(&unix_table_lock);
1935} 1935}
1936 1936
1937static int unix_seq_show(struct seq_file *seq, void *v) 1937static int unix_seq_show(struct seq_file *seq, void *v)
diff --git a/net/unix/garbage.c b/net/unix/garbage.c
index 6ffc64e1712d..411802bd4d37 100644
--- a/net/unix/garbage.c
+++ b/net/unix/garbage.c
@@ -182,7 +182,7 @@ void unix_gc(void)
182 if (down_trylock(&unix_gc_sem)) 182 if (down_trylock(&unix_gc_sem))
183 return; 183 return;
184 184
185 read_lock(&unix_table_lock); 185 spin_lock(&unix_table_lock);
186 186
187 forall_unix_sockets(i, s) 187 forall_unix_sockets(i, s)
188 { 188 {
@@ -301,7 +301,7 @@ void unix_gc(void)
301 } 301 }
302 u->gc_tree = GC_ORPHAN; 302 u->gc_tree = GC_ORPHAN;
303 } 303 }
304 read_unlock(&unix_table_lock); 304 spin_unlock(&unix_table_lock);
305 305
306 /* 306 /*
307 * Here we are. Hitlist is filled. Die. 307 * Here we are. Hitlist is filled. Die.