ksmbd: Implements sess->rpc_handle_list as xarray
authorDawei Li <set_pte_at@outlook.com>
Sun, 15 Jan 2023 10:32:05 +0000 (18:32 +0800)
committerSteve French <stfrench@microsoft.com>
Mon, 30 Jan 2023 00:10:42 +0000 (18:10 -0600)
For some ops on rpc handle:
1. ksmbd_session_rpc_method(), possibly on high frequency.
2. ksmbd_session_rpc_close().

id is used as indexing key to lookup channel, in that case,
linear search based on list may suffer a bit for performance.

Implements sess->rpc_handle_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>
fs/ksmbd/mgmt/user_session.c
fs/ksmbd/mgmt/user_session.h

index a2b128dedcfcf92a3b17144d59b09cd891b2d597..1ca2aae4c2997f7ecb43c4b53b4aeb63afb0d7ee 100644 (file)
@@ -25,7 +25,6 @@ static DECLARE_RWSEM(sessions_table_lock);
 struct ksmbd_session_rpc {
        int                     id;
        unsigned int            method;
-       struct list_head        list;
 };
 
 static void free_channel_list(struct ksmbd_session *sess)
@@ -58,15 +57,14 @@ static void __session_rpc_close(struct ksmbd_session *sess,
 static void ksmbd_session_rpc_clear_list(struct ksmbd_session *sess)
 {
        struct ksmbd_session_rpc *entry;
+       long index;
 
-       while (!list_empty(&sess->rpc_handle_list)) {
-               entry = list_entry(sess->rpc_handle_list.next,
-                                  struct ksmbd_session_rpc,
-                                  list);
-
-               list_del(&entry->list);
+       xa_for_each(&sess->rpc_handle_list, index, entry) {
+               xa_erase(&sess->rpc_handle_list, index);
                __session_rpc_close(sess, entry);
        }
+
+       xa_destroy(&sess->rpc_handle_list);
 }
 
 static int __rpc_method(char *rpc_name)
@@ -102,13 +100,13 @@ int ksmbd_session_rpc_open(struct ksmbd_session *sess, char *rpc_name)
 
        entry = kzalloc(sizeof(struct ksmbd_session_rpc), GFP_KERNEL);
        if (!entry)
-               return -EINVAL;
+               return -ENOMEM;
 
-       list_add(&entry->list, &sess->rpc_handle_list);
        entry->method = method;
        entry->id = ksmbd_ipc_id_alloc();
        if (entry->id < 0)
                goto free_entry;
+       xa_store(&sess->rpc_handle_list, entry->id, entry, GFP_KERNEL);
 
        resp = ksmbd_rpc_open(sess, entry->id);
        if (!resp)
@@ -117,9 +115,9 @@ int ksmbd_session_rpc_open(struct ksmbd_session *sess, char *rpc_name)
        kvfree(resp);
        return entry->id;
 free_id:
+       xa_erase(&sess->rpc_handle_list, entry->id);
        ksmbd_rpc_id_free(entry->id);
 free_entry:
-       list_del(&entry->list);
        kfree(entry);
        return -EINVAL;
 }
@@ -128,24 +126,17 @@ void ksmbd_session_rpc_close(struct ksmbd_session *sess, int id)
 {
        struct ksmbd_session_rpc *entry;
 
-       list_for_each_entry(entry, &sess->rpc_handle_list, list) {
-               if (entry->id == id) {
-                       list_del(&entry->list);
-                       __session_rpc_close(sess, entry);
-                       break;
-               }
-       }
+       entry = xa_erase(&sess->rpc_handle_list, id);
+       if (entry)
+               __session_rpc_close(sess, entry);
 }
 
 int ksmbd_session_rpc_method(struct ksmbd_session *sess, int id)
 {
        struct ksmbd_session_rpc *entry;
 
-       list_for_each_entry(entry, &sess->rpc_handle_list, list) {
-               if (entry->id == id)
-                       return entry->method;
-       }
-       return 0;
+       entry = xa_load(&sess->rpc_handle_list, id);
+       return entry ? entry->method : 0;
 }
 
 void ksmbd_session_destroy(struct ksmbd_session *sess)
@@ -327,7 +318,7 @@ static struct ksmbd_session *__session_create(int protocol)
        set_session_flag(sess, protocol);
        xa_init(&sess->tree_conns);
        xa_init(&sess->ksmbd_chann_list);
-       INIT_LIST_HEAD(&sess->rpc_handle_list);
+       xa_init(&sess->rpc_handle_list);
        sess->sequence_number = 1;
 
        ret = __init_smb2_session(sess);
index 44a3c67b2bd9232714660df959ad098c593d07fa..b6a9e7a6aae45e18cb4ae5829e5330247acaccaa 100644 (file)
@@ -52,7 +52,7 @@ struct ksmbd_session {
        struct xarray                   ksmbd_chann_list;
        struct xarray                   tree_conns;
        struct ida                      tree_conn_ida;
-       struct list_head                rpc_handle_list;
+       struct xarray                   rpc_handle_list;
 
        __u8                            smb3encryptionkey[SMB3_ENC_DEC_KEY_SIZE];
        __u8                            smb3decryptionkey[SMB3_ENC_DEC_KEY_SIZE];