Skip to content

Commit 1d9c417

Browse files
Dawei Lismfrench
authored andcommitted
ksmbd: Implements sess->ksmbd_chann_list as xarray
For some ops on channel: 1. lookup_chann_list(), possibly on high frequency. 2. ksmbd_chann_del(). Connection is used as indexing key to lookup channel, in that case, linear search based on list may suffer a bit for performance. Implements sess->ksmbd_chann_list as xarray. Signed-off-by: Dawei Li <set_pte_at@outlook.com> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
1 parent 6d796c5 commit 1d9c417

File tree

3 files changed

+30
-69
lines changed

3 files changed

+30
-69
lines changed

fs/ksmbd/mgmt/user_session.c

Lines changed: 24 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,15 @@ struct ksmbd_session_rpc {
3030

3131
static void free_channel_list(struct ksmbd_session *sess)
3232
{
33-
struct channel *chann, *tmp;
33+
struct channel *chann;
34+
unsigned long index;
3435

35-
write_lock(&sess->chann_lock);
36-
list_for_each_entry_safe(chann, tmp, &sess->ksmbd_chann_list,
37-
chann_list) {
38-
list_del(&chann->chann_list);
36+
xa_for_each(&sess->ksmbd_chann_list, index, chann) {
37+
xa_erase(&sess->ksmbd_chann_list, index);
3938
kfree(chann);
4039
}
41-
write_unlock(&sess->chann_lock);
40+
41+
xa_destroy(&sess->ksmbd_chann_list);
4242
}
4343

4444
static void __session_rpc_close(struct ksmbd_session *sess,
@@ -190,21 +190,15 @@ int ksmbd_session_register(struct ksmbd_conn *conn,
190190

191191
static int ksmbd_chann_del(struct ksmbd_conn *conn, struct ksmbd_session *sess)
192192
{
193-
struct channel *chann, *tmp;
194-
195-
write_lock(&sess->chann_lock);
196-
list_for_each_entry_safe(chann, tmp, &sess->ksmbd_chann_list,
197-
chann_list) {
198-
if (chann->conn == conn) {
199-
list_del(&chann->chann_list);
200-
kfree(chann);
201-
write_unlock(&sess->chann_lock);
202-
return 0;
203-
}
204-
}
205-
write_unlock(&sess->chann_lock);
193+
struct channel *chann;
194+
195+
chann = xa_erase(&sess->ksmbd_chann_list, (long)conn);
196+
if (!chann)
197+
return -ENOENT;
206198

207-
return -ENOENT;
199+
kfree(chann);
200+
201+
return 0;
208202
}
209203

210204
void ksmbd_sessions_deregister(struct ksmbd_conn *conn)
@@ -234,7 +228,7 @@ void ksmbd_sessions_deregister(struct ksmbd_conn *conn)
234228
return;
235229

236230
sess_destroy:
237-
if (list_empty(&sess->ksmbd_chann_list)) {
231+
if (xa_empty(&sess->ksmbd_chann_list)) {
238232
xa_erase(&conn->sessions, sess->id);
239233
ksmbd_session_destroy(sess);
240234
}
@@ -320,6 +314,9 @@ static struct ksmbd_session *__session_create(int protocol)
320314
struct ksmbd_session *sess;
321315
int ret;
322316

317+
if (protocol != CIFDS_SESSION_FLAG_SMB2)
318+
return NULL;
319+
323320
sess = kzalloc(sizeof(struct ksmbd_session), GFP_KERNEL);
324321
if (!sess)
325322
return NULL;
@@ -329,30 +326,20 @@ static struct ksmbd_session *__session_create(int protocol)
329326

330327
set_session_flag(sess, protocol);
331328
xa_init(&sess->tree_conns);
332-
INIT_LIST_HEAD(&sess->ksmbd_chann_list);
329+
xa_init(&sess->ksmbd_chann_list);
333330
INIT_LIST_HEAD(&sess->rpc_handle_list);
334331
sess->sequence_number = 1;
335-
rwlock_init(&sess->chann_lock);
336-
337-
switch (protocol) {
338-
case CIFDS_SESSION_FLAG_SMB2:
339-
ret = __init_smb2_session(sess);
340-
break;
341-
default:
342-
ret = -EINVAL;
343-
break;
344-
}
345332

333+
ret = __init_smb2_session(sess);
346334
if (ret)
347335
goto error;
348336

349337
ida_init(&sess->tree_conn_ida);
350338

351-
if (protocol == CIFDS_SESSION_FLAG_SMB2) {
352-
down_write(&sessions_table_lock);
353-
hash_add(sessions_table, &sess->hlist, sess->id);
354-
up_write(&sessions_table_lock);
355-
}
339+
down_write(&sessions_table_lock);
340+
hash_add(sessions_table, &sess->hlist, sess->id);
341+
up_write(&sessions_table_lock);
342+
356343
return sess;
357344

358345
error:

fs/ksmbd/mgmt/user_session.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ struct ksmbd_file_table;
2121
struct channel {
2222
__u8 smb3signingkey[SMB3_SIGN_KEY_SIZE];
2323
struct ksmbd_conn *conn;
24-
struct list_head chann_list;
2524
};
2625

2726
struct preauth_session {
@@ -50,8 +49,7 @@ struct ksmbd_session {
5049
char sess_key[CIFS_KEY_SIZE];
5150

5251
struct hlist_node hlist;
53-
rwlock_t chann_lock;
54-
struct list_head ksmbd_chann_list;
52+
struct xarray ksmbd_chann_list;
5553
struct xarray tree_conns;
5654
struct ida tree_conn_ida;
5755
struct list_head rpc_handle_list;

fs/ksmbd/smb2pdu.c

Lines changed: 5 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,7 @@ static inline bool check_session_id(struct ksmbd_conn *conn, u64 id)
7474

7575
struct channel *lookup_chann_list(struct ksmbd_session *sess, struct ksmbd_conn *conn)
7676
{
77-
struct channel *chann;
78-
79-
list_for_each_entry(chann, &sess->ksmbd_chann_list, chann_list) {
80-
if (chann->conn == conn)
81-
return chann;
82-
}
83-
84-
return NULL;
77+
return xa_load(&sess->ksmbd_chann_list, (long)conn);
8578
}
8679

8780
/**
@@ -595,6 +588,7 @@ static void destroy_previous_session(struct ksmbd_conn *conn,
595588
struct ksmbd_session *prev_sess = ksmbd_session_lookup_slowpath(id);
596589
struct ksmbd_user *prev_user;
597590
struct channel *chann;
591+
long index;
598592

599593
if (!prev_sess)
600594
return;
@@ -608,10 +602,8 @@ static void destroy_previous_session(struct ksmbd_conn *conn,
608602
return;
609603

610604
prev_sess->state = SMB2_SESSION_EXPIRED;
611-
write_lock(&prev_sess->chann_lock);
612-
list_for_each_entry(chann, &prev_sess->ksmbd_chann_list, chann_list)
605+
xa_for_each(&prev_sess->ksmbd_chann_list, index, chann)
613606
chann->conn->status = KSMBD_SESS_EXITING;
614-
write_unlock(&prev_sess->chann_lock);
615607
}
616608

617609
/**
@@ -1519,19 +1511,14 @@ static int ntlm_authenticate(struct ksmbd_work *work)
15191511

15201512
binding_session:
15211513
if (conn->dialect >= SMB30_PROT_ID) {
1522-
read_lock(&sess->chann_lock);
15231514
chann = lookup_chann_list(sess, conn);
1524-
read_unlock(&sess->chann_lock);
15251515
if (!chann) {
15261516
chann = kmalloc(sizeof(struct channel), GFP_KERNEL);
15271517
if (!chann)
15281518
return -ENOMEM;
15291519

15301520
chann->conn = conn;
1531-
INIT_LIST_HEAD(&chann->chann_list);
1532-
write_lock(&sess->chann_lock);
1533-
list_add(&chann->chann_list, &sess->ksmbd_chann_list);
1534-
write_unlock(&sess->chann_lock);
1521+
xa_store(&sess->ksmbd_chann_list, (long)conn, chann, GFP_KERNEL);
15351522
}
15361523
}
15371524

@@ -1606,19 +1593,14 @@ static int krb5_authenticate(struct ksmbd_work *work)
16061593
}
16071594

16081595
if (conn->dialect >= SMB30_PROT_ID) {
1609-
read_lock(&sess->chann_lock);
16101596
chann = lookup_chann_list(sess, conn);
1611-
read_unlock(&sess->chann_lock);
16121597
if (!chann) {
16131598
chann = kmalloc(sizeof(struct channel), GFP_KERNEL);
16141599
if (!chann)
16151600
return -ENOMEM;
16161601

16171602
chann->conn = conn;
1618-
INIT_LIST_HEAD(&chann->chann_list);
1619-
write_lock(&sess->chann_lock);
1620-
list_add(&chann->chann_list, &sess->ksmbd_chann_list);
1621-
write_unlock(&sess->chann_lock);
1603+
xa_store(&sess->ksmbd_chann_list, (long)conn, chann, GFP_KERNEL);
16221604
}
16231605
}
16241606

@@ -8409,14 +8391,11 @@ int smb3_check_sign_req(struct ksmbd_work *work)
84098391
if (le16_to_cpu(hdr->Command) == SMB2_SESSION_SETUP_HE) {
84108392
signing_key = work->sess->smb3signingkey;
84118393
} else {
8412-
read_lock(&work->sess->chann_lock);
84138394
chann = lookup_chann_list(work->sess, conn);
84148395
if (!chann) {
8415-
read_unlock(&work->sess->chann_lock);
84168396
return 0;
84178397
}
84188398
signing_key = chann->smb3signingkey;
8419-
read_unlock(&work->sess->chann_lock);
84208399
}
84218400

84228401
if (!signing_key) {
@@ -8476,14 +8455,11 @@ void smb3_set_sign_rsp(struct ksmbd_work *work)
84768455
le16_to_cpu(hdr->Command) == SMB2_SESSION_SETUP_HE) {
84778456
signing_key = work->sess->smb3signingkey;
84788457
} else {
8479-
read_lock(&work->sess->chann_lock);
84808458
chann = lookup_chann_list(work->sess, work->conn);
84818459
if (!chann) {
8482-
read_unlock(&work->sess->chann_lock);
84838460
return;
84848461
}
84858462
signing_key = chann->smb3signingkey;
8486-
read_unlock(&work->sess->chann_lock);
84878463
}
84888464

84898465
if (!signing_key)

0 commit comments

Comments
 (0)