Skip to content

Commit e6b4b87

Browse files
q2venkuba-moo
authored andcommitted
af_unix: Save hash in sk_hash.
To replace unix_table_lock with per-hash locks in the next patch, we need to save a hash in each socket because /proc/net/unix or BPF prog iterate sockets while holding a hash table lock and release it later in a different function. Currently, we store a real/pseudo hash in struct unix_address. However, we do not allocate it to unbound sockets, nor should we do just for that. For this purpose, we can use sk_hash. Then, we no longer use the hash field in struct unix_address and can remove it. Also, this patch does - rename unix_insert_socket() to unix_insert_unbound_socket() - remove the redundant list argument from __unix_insert_socket() and unix_insert_unbound_socket() - use 'unsigned int' instead of 'unsigned' in __unix_set_addr_hash() - remove 'inline' from unix_remove_socket() and unix_insert_unbound_socket(). Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.co.jp> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent f452be4 commit e6b4b87

File tree

2 files changed

+23
-20
lines changed

2 files changed

+23
-20
lines changed

include/net/af_unix.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ extern struct hlist_head unix_socket_table[2 * UNIX_HASH_SIZE];
2626
struct unix_address {
2727
refcount_t refcnt;
2828
int len;
29-
unsigned int hash;
3029
struct sockaddr_un name[];
3130
};
3231

net/unix/af_unix.c

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -280,31 +280,33 @@ static void __unix_remove_socket(struct sock *sk)
280280
sk_del_node_init(sk);
281281
}
282282

283-
static void __unix_insert_socket(struct hlist_head *list, struct sock *sk)
283+
static void __unix_insert_socket(struct sock *sk)
284284
{
285285
WARN_ON(!sk_unhashed(sk));
286-
sk_add_node(sk, list);
286+
sk_add_node(sk, &unix_socket_table[sk->sk_hash]);
287287
}
288288

289-
static void __unix_set_addr(struct sock *sk, struct unix_address *addr,
290-
unsigned hash)
289+
static void __unix_set_addr_hash(struct sock *sk, struct unix_address *addr,
290+
unsigned int hash)
291291
{
292292
__unix_remove_socket(sk);
293293
smp_store_release(&unix_sk(sk)->addr, addr);
294-
__unix_insert_socket(&unix_socket_table[hash], sk);
294+
295+
sk->sk_hash = hash;
296+
__unix_insert_socket(sk);
295297
}
296298

297-
static inline void unix_remove_socket(struct sock *sk)
299+
static void unix_remove_socket(struct sock *sk)
298300
{
299301
spin_lock(&unix_table_lock);
300302
__unix_remove_socket(sk);
301303
spin_unlock(&unix_table_lock);
302304
}
303305

304-
static inline void unix_insert_socket(struct hlist_head *list, struct sock *sk)
306+
static void unix_insert_unbound_socket(struct sock *sk)
305307
{
306308
spin_lock(&unix_table_lock);
307-
__unix_insert_socket(list, sk);
309+
__unix_insert_socket(sk);
308310
spin_unlock(&unix_table_lock);
309311
}
310312

@@ -893,6 +895,7 @@ static struct sock *unix_create1(struct net *net, struct socket *sock, int kern,
893895

894896
sock_init_data(sock, sk);
895897

898+
sk->sk_hash = unix_unbound_hash(sk);
896899
sk->sk_allocation = GFP_KERNEL_ACCOUNT;
897900
sk->sk_write_space = unix_write_space;
898901
sk->sk_max_ack_backlog = net->unx.sysctl_max_dgram_qlen;
@@ -908,7 +911,7 @@ static struct sock *unix_create1(struct net *net, struct socket *sock, int kern,
908911
init_waitqueue_head(&u->peer_wait);
909912
init_waitqueue_func_entry(&u->peer_wake, unix_dgram_peer_wake_relay);
910913
memset(&u->scm_stat, 0, sizeof(struct scm_stat));
911-
unix_insert_socket(&unix_socket_table[unix_unbound_hash(sk)], sk);
914+
unix_insert_unbound_socket(sk);
912915

913916
sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
914917

@@ -1054,6 +1057,7 @@ static int unix_autobind(struct sock *sk)
10541057
struct unix_address *addr;
10551058
unsigned int retries = 0;
10561059
static u32 ordernum = 1;
1060+
unsigned int new_hash;
10571061
int err;
10581062

10591063
err = mutex_lock_interruptible(&u->bindlock);
@@ -1075,13 +1079,13 @@ static int unix_autobind(struct sock *sk)
10751079
retry:
10761080
addr->len = sprintf(addr->name->sun_path + 1, "%05x", ordernum) +
10771081
offsetof(struct sockaddr_un, sun_path) + 1;
1078-
addr->hash = unix_abstract_hash(addr->name, addr->len, sk->sk_type);
10791082

1083+
new_hash = unix_abstract_hash(addr->name, addr->len, sk->sk_type);
10801084
spin_lock(&unix_table_lock);
10811085
ordernum = (ordernum+1)&0xFFFFF;
10821086

10831087
if (__unix_find_socket_byname(sock_net(sk), addr->name, addr->len,
1084-
addr->hash)) {
1088+
new_hash)) {
10851089
spin_unlock(&unix_table_lock);
10861090
/*
10871091
* __unix_find_socket_byname() may take long time if many names
@@ -1097,7 +1101,7 @@ static int unix_autobind(struct sock *sk)
10971101
goto retry;
10981102
}
10991103

1100-
__unix_set_addr(sk, addr, addr->hash);
1104+
__unix_set_addr_hash(sk, addr, new_hash);
11011105
spin_unlock(&unix_table_lock);
11021106
err = 0;
11031107

@@ -1113,9 +1117,9 @@ static int unix_bind_bsd(struct sock *sk, struct sockaddr_un *sunaddr,
11131117
struct unix_sock *u = unix_sk(sk);
11141118
struct user_namespace *ns; // barf...
11151119
struct unix_address *addr;
1120+
unsigned int new_hash;
11161121
struct dentry *dentry;
11171122
struct path parent;
1118-
unsigned int hash;
11191123
int err;
11201124

11211125
unix_mkname_bsd(sunaddr, addr_len);
@@ -1151,12 +1155,11 @@ static int unix_bind_bsd(struct sock *sk, struct sockaddr_un *sunaddr,
11511155
if (u->addr)
11521156
goto out_unlock;
11531157

1154-
addr->hash = UNIX_HASH_SIZE;
1155-
hash = unix_bsd_hash(d_backing_inode(dentry));
1158+
new_hash = unix_bsd_hash(d_backing_inode(dentry));
11561159
spin_lock(&unix_table_lock);
11571160
u->path.mnt = mntget(parent.mnt);
11581161
u->path.dentry = dget(dentry);
1159-
__unix_set_addr(sk, addr, hash);
1162+
__unix_set_addr_hash(sk, addr, new_hash);
11601163
spin_unlock(&unix_table_lock);
11611164
mutex_unlock(&u->bindlock);
11621165
done_path_create(&parent, dentry);
@@ -1180,6 +1183,7 @@ static int unix_bind_abstract(struct sock *sk, struct sockaddr_un *sunaddr,
11801183
{
11811184
struct unix_sock *u = unix_sk(sk);
11821185
struct unix_address *addr;
1186+
unsigned int new_hash;
11831187
int err;
11841188

11851189
addr = unix_create_addr(sunaddr, addr_len);
@@ -1195,14 +1199,14 @@ static int unix_bind_abstract(struct sock *sk, struct sockaddr_un *sunaddr,
11951199
goto out_mutex;
11961200
}
11971201

1198-
addr->hash = unix_abstract_hash(addr->name, addr->len, sk->sk_type);
1202+
new_hash = unix_abstract_hash(addr->name, addr->len, sk->sk_type);
11991203
spin_lock(&unix_table_lock);
12001204

12011205
if (__unix_find_socket_byname(sock_net(sk), addr->name, addr->len,
1202-
addr->hash))
1206+
new_hash))
12031207
goto out_spin;
12041208

1205-
__unix_set_addr(sk, addr, addr->hash);
1209+
__unix_set_addr_hash(sk, addr, new_hash);
12061210
spin_unlock(&unix_table_lock);
12071211
mutex_unlock(&u->bindlock);
12081212
return 0;

0 commit comments

Comments
 (0)