Skip to content

Commit 2adce26

Browse files
committed
ksmbd: replace connection list with xarray
Replace connection list with xarray to improve lookup performance. Signed-off-by: Namjae Jeon <[email protected]>
1 parent 9631b8b commit 2adce26

File tree

6 files changed

+36
-24
lines changed

6 files changed

+36
-24
lines changed

connection.c

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ static DEFINE_MUTEX(init_lock);
2222

2323
static struct ksmbd_conn_ops default_conn_ops;
2424

25-
LIST_HEAD(conn_list);
25+
DEFINE_XARRAY(conn_list);
2626
DECLARE_RWSEM(conn_list_lock);
2727

2828
/**
@@ -36,7 +36,7 @@ DECLARE_RWSEM(conn_list_lock);
3636
void ksmbd_conn_free(struct ksmbd_conn *conn)
3737
{
3838
down_write(&conn_list_lock);
39-
list_del(&conn->conns_list);
39+
xa_erase(&conn_list, conn->inet_addr);
4040
up_write(&conn_list_lock);
4141

4242
xa_destroy(&conn->sessions);
@@ -53,9 +53,10 @@ void ksmbd_conn_free(struct ksmbd_conn *conn)
5353
*
5454
* Return: ksmbd_conn struct on success, otherwise NULL
5555
*/
56-
struct ksmbd_conn *ksmbd_conn_alloc(void)
56+
struct ksmbd_conn *ksmbd_conn_alloc(__be32 inet_addr)
5757
{
5858
struct ksmbd_conn *conn;
59+
int err;
5960

6061
conn = kzalloc(sizeof(struct ksmbd_conn), KSMBD_DEFAULT_GFP);
6162
if (!conn)
@@ -81,6 +82,7 @@ struct ksmbd_conn *ksmbd_conn_alloc(void)
8182
atomic_set(&conn->refcnt, 1);
8283
conn->total_credits = 1;
8384
conn->outstanding_credits = 0;
85+
conn->inet_addr = inet_addr;
8486

8587
init_waitqueue_head(&conn->req_running_q);
8688
init_waitqueue_head(&conn->r_count_q);
@@ -98,7 +100,14 @@ struct ksmbd_conn *ksmbd_conn_alloc(void)
98100
init_rwsem(&conn->session_lock);
99101

100102
down_write(&conn_list_lock);
101-
list_add(&conn->conns_list, &conn_list);
103+
err = xa_err(xa_store(&conn_list, inet_addr, conn, KSMBD_DEFAULT_GFP));
104+
if (err < 0) {
105+
if (IS_ENABLED(CONFIG_UNICODE))
106+
utf8_unload(conn->um);
107+
unload_nls(conn->local_nls);
108+
kfree(conn);
109+
conn = NULL;
110+
}
102111
up_write(&conn_list_lock);
103112
return conn;
104113
}
@@ -107,9 +116,10 @@ bool ksmbd_conn_lookup_dialect(struct ksmbd_conn *c)
107116
{
108117
struct ksmbd_conn *t;
109118
bool ret = false;
119+
unsigned long idx;
110120

111121
down_read(&conn_list_lock);
112-
list_for_each_entry(t, &conn_list, conns_list) {
122+
xa_for_each(&conn_list, idx, t) {
113123
if (memcmp(t->ClientGUID, c->ClientGUID, SMB2_CLIENT_GUID_SIZE))
114124
continue;
115125

@@ -181,9 +191,10 @@ void ksmbd_conn_unlock(struct ksmbd_conn *conn)
181191
void ksmbd_all_conn_set_status(u64 sess_id, u32 status)
182192
{
183193
struct ksmbd_conn *conn;
194+
unsigned long idx;
184195

185196
down_read(&conn_list_lock);
186-
list_for_each_entry(conn, &conn_list, conns_list) {
197+
xa_for_each(&conn_list, idx, conn) {
187198
if (conn->binding || xa_load(&conn->sessions, sess_id))
188199
WRITE_ONCE(conn->status, status);
189200
}
@@ -198,6 +209,7 @@ void ksmbd_conn_wait_idle(struct ksmbd_conn *conn)
198209
int ksmbd_conn_wait_idle_sess_id(struct ksmbd_conn *curr_conn, u64 sess_id)
199210
{
200211
struct ksmbd_conn *conn;
212+
unsigned long idx;
201213
int rc, retry_count = 0, max_timeout = 120;
202214
int rcount = 1;
203215

@@ -206,7 +218,7 @@ int ksmbd_conn_wait_idle_sess_id(struct ksmbd_conn *curr_conn, u64 sess_id)
206218
return -EIO;
207219

208220
down_read(&conn_list_lock);
209-
list_for_each_entry(conn, &conn_list, conns_list) {
221+
xa_for_each(&conn_list, idx, conn) {
210222
if (conn->binding || xa_load(&conn->sessions, sess_id)) {
211223
if (conn == curr_conn)
212224
rcount = 2;
@@ -532,10 +544,11 @@ static void stop_sessions(void)
532544
{
533545
struct ksmbd_conn *conn;
534546
struct ksmbd_transport *t;
547+
unsigned long idx;
535548

536549
again:
537550
down_read(&conn_list_lock);
538-
list_for_each_entry(conn, &conn_list, conns_list) {
551+
xa_for_each(&conn_list, idx, conn) {
539552
t = conn->transport;
540553
ksmbd_conn_set_exiting(conn);
541554
if (t->ops->shutdown) {
@@ -546,7 +559,7 @@ static void stop_sessions(void)
546559
}
547560
up_read(&conn_list_lock);
548561

549-
if (!list_empty(&conn_list)) {
562+
if (!xa_empty(&conn_list)) {
550563
msleep(100);
551564
goto again;
552565
}

connection.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,13 +146,13 @@ struct ksmbd_transport {
146146
#define KSMBD_TCP_SEND_TIMEOUT (5 * HZ)
147147
#define KSMBD_TCP_PEER_SOCKADDR(c) ((struct sockaddr *)&((c)->peer_addr))
148148

149-
extern struct list_head conn_list;
149+
extern struct xarray conn_list;
150150
extern struct rw_semaphore conn_list_lock;
151151

152152
bool ksmbd_conn_alive(struct ksmbd_conn *conn);
153153
void ksmbd_conn_wait_idle(struct ksmbd_conn *conn);
154154
int ksmbd_conn_wait_idle_sess_id(struct ksmbd_conn *curr_conn, u64 sess_id);
155-
struct ksmbd_conn *ksmbd_conn_alloc(void);
155+
struct ksmbd_conn *ksmbd_conn_alloc(__be32 inet_addr);
156156
void ksmbd_conn_free(struct ksmbd_conn *conn);
157157
bool ksmbd_conn_lookup_dialect(struct ksmbd_conn *c);
158158
int ksmbd_conn_write(struct ksmbd_work *work);

smb1pdu.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1658,6 +1658,7 @@ int smb_locking_andx(struct ksmbd_work *work)
16581658
int locked, timeout;
16591659
const unsigned long long loff_max = ~0;
16601660
struct ksmbd_conn *conn;
1661+
unsigned long idx;
16611662

16621663
timeout = le32_to_cpu(req->Timeout);
16631664
ksmbd_debug(SMB, "got oplock brk for fid %d lock type = 0x%x, timeout: %d\n",
@@ -1782,7 +1783,7 @@ int smb_locking_andx(struct ksmbd_work *work)
17821783
list_del(&smb_lock->llist);
17831784
/* check locks in connections */
17841785
down_read(&conn_list_lock);
1785-
list_for_each_entry(conn, &conn_list, conns_list) {
1786+
xa_each_each(&conn_list, idx, conn) {
17861787
spin_lock(&conn->llist_lock);
17871788
list_for_each_entry_safe(cmp_lock, tmp2, &conn->lock_list, clist) {
17881789
if (file_inode(cmp_lock->fl->fl_file) !=
@@ -1948,7 +1949,7 @@ int smb_locking_andx(struct ksmbd_work *work)
19481949

19491950
locked = 0;
19501951
up_read(&conn_list_lock);
1951-
list_for_each_entry(conn, &conn_list, conns_list) {
1952+
xa_each_each(&conn_list, idx, conn) {
19521953
spin_lock(&conn->llist_lock);
19531954
list_for_each_entry(cmp_lock, &conn->lock_list, clist) {
19541955
if (file_inode(cmp_lock->fl->fl_file) !=

smb2pdu.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7901,6 +7901,7 @@ int smb2_lock(struct ksmbd_work *work)
79017901
struct ksmbd_file *fp = NULL;
79027902
struct file_lock *flock = NULL;
79037903
struct file *filp = NULL;
7904+
unsigned long idx;
79047905
int lock_count;
79057906
int flags = 0;
79067907
int cmd = 0;
@@ -8026,7 +8027,7 @@ int smb2_lock(struct ksmbd_work *work)
80268027
nolock = 1;
80278028
/* check locks in connection list */
80288029
down_read(&conn_list_lock);
8029-
list_for_each_entry(conn, &conn_list, conns_list) {
8030+
xa_for_each(&conn_list, idx, conn) {
80308031
spin_lock(&conn->llist_lock);
80318032
list_for_each_entry_safe(cmp_lock, tmp2, &conn->lock_list, clist) {
80328033
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 9, 0)

transport_rdma.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ static struct smb_direct_transport *alloc_transport(struct rdma_cm_id *cm_id)
371371
INIT_WORK(&t->send_immediate_work, smb_direct_send_immediate_work);
372372
INIT_WORK(&t->disconnect_work, smb_direct_disconnect_rdma_work);
373373

374-
conn = ksmbd_conn_alloc();
374+
conn = ksmbd_conn_alloc(0);
375375
if (!conn)
376376
goto err;
377377
conn->transport = KSMBD_TRANS(t);

transport_tcp.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -109,13 +109,12 @@ static struct tcp_transport *alloc_transport(struct socket *client_sk)
109109
return NULL;
110110
t->sock = client_sk;
111111

112-
conn = ksmbd_conn_alloc();
112+
conn = ksmbd_conn_alloc(inet_sk(client_sk->sk)->inet_daddr);
113113
if (!conn) {
114114
kfree(t);
115115
return NULL;
116116
}
117117

118-
conn->inet_addr = inet_sk(client_sk->sk)->inet_daddr;
119118
conn->transport = KSMBD_TRANS(t);
120119
KSMBD_TRANS(t)->conn = conn;
121120
KSMBD_TRANS(t)->ops = &ksmbd_tcp_transport_ops;
@@ -284,14 +283,12 @@ static int ksmbd_kthread_fn(void *p)
284283
*/
285284
csk_inet = inet_sk(client_sk->sk);
286285
down_read(&conn_list_lock);
287-
list_for_each_entry(conn, &conn_list, conns_list)
288-
if (csk_inet->inet_daddr == conn->inet_addr) {
289-
ret = -EAGAIN;
290-
break;
291-
}
292-
up_read(&conn_list_lock);
293-
if (ret == -EAGAIN)
286+
conn = xa_load(&conn_list, csk_inet->inet_daddr);
287+
if (conn) {
288+
up_read(&conn_list_lock);
294289
continue;
290+
}
291+
up_read(&conn_list_lock);
295292

296293
if (server_conf.max_connections &&
297294
atomic_inc_return(&active_num_conn) >= server_conf.max_connections) {

0 commit comments

Comments
 (0)