[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>
This commit is contained in:
		
							parent
							
								
									d83d8461f9
								
							
						
					
					
						commit
						fbe9cc4a87
					
				| @ -13,7 +13,7 @@ extern void unix_gc(void); | ||||
| #define UNIX_HASH_SIZE	256 | ||||
| 
 | ||||
| extern struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1]; | ||||
| extern rwlock_t unix_table_lock; | ||||
| extern spinlock_t unix_table_lock; | ||||
| 
 | ||||
| extern atomic_t unix_tot_inflight; | ||||
| 
 | ||||
|  | ||||
| @ -121,7 +121,7 @@ | ||||
| int sysctl_unix_max_dgram_qlen = 10; | ||||
| 
 | ||||
| struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1]; | ||||
| DEFINE_RWLOCK(unix_table_lock); | ||||
| DEFINE_SPINLOCK(unix_table_lock); | ||||
| static atomic_t unix_nr_socks = ATOMIC_INIT(0); | ||||
| 
 | ||||
| #define unix_sockets_unbound	(&unix_socket_table[UNIX_HASH_SIZE]) | ||||
| @ -130,7 +130,7 @@ static atomic_t unix_nr_socks = ATOMIC_INIT(0); | ||||
| 
 | ||||
| /*
 | ||||
|  *  SMP locking strategy: | ||||
|  *    hash table is protected with rwlock unix_table_lock | ||||
|  *    hash table is protected with spinlock unix_table_lock | ||||
|  *    each socket state is protected by separate rwlock. | ||||
|  */ | ||||
| 
 | ||||
| @ -214,16 +214,16 @@ static void __unix_insert_socket(struct hlist_head *list, struct sock *sk) | ||||
| 
 | ||||
| static inline void unix_remove_socket(struct sock *sk) | ||||
| { | ||||
| 	write_lock(&unix_table_lock); | ||||
| 	spin_lock(&unix_table_lock); | ||||
| 	__unix_remove_socket(sk); | ||||
| 	write_unlock(&unix_table_lock); | ||||
| 	spin_unlock(&unix_table_lock); | ||||
| } | ||||
| 
 | ||||
| static inline void unix_insert_socket(struct hlist_head *list, struct sock *sk) | ||||
| { | ||||
| 	write_lock(&unix_table_lock); | ||||
| 	spin_lock(&unix_table_lock); | ||||
| 	__unix_insert_socket(list, sk); | ||||
| 	write_unlock(&unix_table_lock); | ||||
| 	spin_unlock(&unix_table_lock); | ||||
| } | ||||
| 
 | ||||
| static 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, | ||||
| { | ||||
| 	struct sock *s; | ||||
| 
 | ||||
| 	read_lock(&unix_table_lock); | ||||
| 	spin_lock(&unix_table_lock); | ||||
| 	s = __unix_find_socket_byname(sunname, len, type, hash); | ||||
| 	if (s) | ||||
| 		sock_hold(s); | ||||
| 	read_unlock(&unix_table_lock); | ||||
| 	spin_unlock(&unix_table_lock); | ||||
| 	return s; | ||||
| } | ||||
| 
 | ||||
| @ -263,7 +263,7 @@ static struct sock *unix_find_socket_byinode(struct inode *i) | ||||
| 	struct sock *s; | ||||
| 	struct hlist_node *node; | ||||
| 
 | ||||
| 	read_lock(&unix_table_lock); | ||||
| 	spin_lock(&unix_table_lock); | ||||
| 	sk_for_each(s, node, | ||||
| 		    &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) { | ||||
| 		struct dentry *dentry = unix_sk(s)->dentry; | ||||
| @ -276,7 +276,7 @@ static struct sock *unix_find_socket_byinode(struct inode *i) | ||||
| 	} | ||||
| 	s = NULL; | ||||
| found: | ||||
| 	read_unlock(&unix_table_lock); | ||||
| 	spin_unlock(&unix_table_lock); | ||||
| 	return s; | ||||
| } | ||||
| 
 | ||||
| @ -642,12 +642,12 @@ retry: | ||||
| 	addr->len = sprintf(addr->name->sun_path+1, "%05x", ordernum) + 1 + sizeof(short); | ||||
| 	addr->hash = unix_hash_fold(csum_partial((void*)addr->name, addr->len, 0)); | ||||
| 
 | ||||
| 	write_lock(&unix_table_lock); | ||||
| 	spin_lock(&unix_table_lock); | ||||
| 	ordernum = (ordernum+1)&0xFFFFF; | ||||
| 
 | ||||
| 	if (__unix_find_socket_byname(addr->name, addr->len, sock->type, | ||||
| 				      addr->hash)) { | ||||
| 		write_unlock(&unix_table_lock); | ||||
| 		spin_unlock(&unix_table_lock); | ||||
| 		/* Sanity yield. It is unusual case, but yet... */ | ||||
| 		if (!(ordernum&0xFF)) | ||||
| 			yield(); | ||||
| @ -658,7 +658,7 @@ retry: | ||||
| 	__unix_remove_socket(sk); | ||||
| 	u->addr = addr; | ||||
| 	__unix_insert_socket(&unix_socket_table[addr->hash], sk); | ||||
| 	write_unlock(&unix_table_lock); | ||||
| 	spin_unlock(&unix_table_lock); | ||||
| 	err = 0; | ||||
| 
 | ||||
| out:	up(&u->readsem); | ||||
| @ -791,7 +791,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | ||||
| 		addr->hash = UNIX_HASH_SIZE; | ||||
| 	} | ||||
| 
 | ||||
| 	write_lock(&unix_table_lock); | ||||
| 	spin_lock(&unix_table_lock); | ||||
| 
 | ||||
| 	if (!sunaddr->sun_path[0]) { | ||||
| 		err = -EADDRINUSE; | ||||
| @ -814,7 +814,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | ||||
| 	__unix_insert_socket(list, sk); | ||||
| 
 | ||||
| out_unlock: | ||||
| 	write_unlock(&unix_table_lock); | ||||
| 	spin_unlock(&unix_table_lock); | ||||
| out_up: | ||||
| 	up(&u->readsem); | ||||
| out: | ||||
| @ -1916,7 +1916,7 @@ static struct sock *unix_seq_idx(int *iter, loff_t pos) | ||||
| 
 | ||||
| static void *unix_seq_start(struct seq_file *seq, loff_t *pos) | ||||
| { | ||||
| 	read_lock(&unix_table_lock); | ||||
| 	spin_lock(&unix_table_lock); | ||||
| 	return *pos ? unix_seq_idx(seq->private, *pos - 1) : ((void *) 1); | ||||
| } | ||||
| 
 | ||||
| @ -1931,7 +1931,7 @@ static void *unix_seq_next(struct seq_file *seq, void *v, loff_t *pos) | ||||
| 
 | ||||
| static void unix_seq_stop(struct seq_file *seq, void *v) | ||||
| { | ||||
| 	read_unlock(&unix_table_lock); | ||||
| 	spin_unlock(&unix_table_lock); | ||||
| } | ||||
| 
 | ||||
| static int unix_seq_show(struct seq_file *seq, void *v) | ||||
|  | ||||
| @ -182,7 +182,7 @@ void unix_gc(void) | ||||
| 	if (down_trylock(&unix_gc_sem)) | ||||
| 		return; | ||||
| 
 | ||||
| 	read_lock(&unix_table_lock); | ||||
| 	spin_lock(&unix_table_lock); | ||||
| 
 | ||||
| 	forall_unix_sockets(i, s) | ||||
| 	{ | ||||
| @ -301,7 +301,7 @@ void unix_gc(void) | ||||
| 		} | ||||
| 		u->gc_tree = GC_ORPHAN; | ||||
| 	} | ||||
| 	read_unlock(&unix_table_lock); | ||||
| 	spin_unlock(&unix_table_lock); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 *	Here we are. Hitlist is filled. Die. | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user