ksmbd: Implements sess->rpc_handle_list as xarray

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>
This commit is contained in:
Dawei Li 2023-01-15 18:32:05 +08:00 коммит произвёл Steve French
Родитель 1d9c417211
Коммит b685757c7b
2 изменённых файлов: 15 добавлений и 24 удалений

Просмотреть файл

@ -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);
entry = xa_erase(&sess->rpc_handle_list, id);
if (entry)
__session_rpc_close(sess, entry);
break;
}
}
}
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);

Просмотреть файл

@ -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];