Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fbe9cc4a authored by David S. Miller's avatar David S. Miller Committed by David S. Miller
Browse files

[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: default avatarDavid S. Miller <davem@davemloft.net>
parent d83d8461
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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;

+17 −17
Original line number Diff line number Diff line
@@ -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 @@ static int unix_autobind(struct socket *sock)
	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 @@ static int unix_autobind(struct socket *sock)
	__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)
+2 −2
Original line number Diff line number Diff line
@@ -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.