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 { struct ksmbd_session_rpc {
int id; int id;
unsigned int method; unsigned int method;
struct list_head list;
}; };
static void free_channel_list(struct ksmbd_session *sess) 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) static void ksmbd_session_rpc_clear_list(struct ksmbd_session *sess)
{ {
struct ksmbd_session_rpc *entry; struct ksmbd_session_rpc *entry;
long index;
while (!list_empty(&sess->rpc_handle_list)) { xa_for_each(&sess->rpc_handle_list, index, entry) {
entry = list_entry(sess->rpc_handle_list.next, xa_erase(&sess->rpc_handle_list, index);
struct ksmbd_session_rpc,
list);
list_del(&entry->list);
__session_rpc_close(sess, entry); __session_rpc_close(sess, entry);
} }
xa_destroy(&sess->rpc_handle_list);
} }
static int __rpc_method(char *rpc_name) 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); entry = kzalloc(sizeof(struct ksmbd_session_rpc), GFP_KERNEL);
if (!entry) if (!entry)
return -EINVAL; return -ENOMEM;
list_add(&entry->list, &sess->rpc_handle_list);
entry->method = method; entry->method = method;
entry->id = ksmbd_ipc_id_alloc(); entry->id = ksmbd_ipc_id_alloc();
if (entry->id < 0) if (entry->id < 0)
goto free_entry; goto free_entry;
xa_store(&sess->rpc_handle_list, entry->id, entry, GFP_KERNEL);
resp = ksmbd_rpc_open(sess, entry->id); resp = ksmbd_rpc_open(sess, entry->id);
if (!resp) if (!resp)
@ -117,9 +115,9 @@ int ksmbd_session_rpc_open(struct ksmbd_session *sess, char *rpc_name)
kvfree(resp); kvfree(resp);
return entry->id; return entry->id;
free_id: free_id:
xa_erase(&sess->rpc_handle_list, entry->id);
ksmbd_rpc_id_free(entry->id); ksmbd_rpc_id_free(entry->id);
free_entry: free_entry:
list_del(&entry->list);
kfree(entry); kfree(entry);
return -EINVAL; return -EINVAL;
} }
@ -128,24 +126,17 @@ void ksmbd_session_rpc_close(struct ksmbd_session *sess, int id)
{ {
struct ksmbd_session_rpc *entry; struct ksmbd_session_rpc *entry;
list_for_each_entry(entry, &sess->rpc_handle_list, list) { entry = xa_erase(&sess->rpc_handle_list, id);
if (entry->id == id) { if (entry)
list_del(&entry->list); __session_rpc_close(sess, entry);
__session_rpc_close(sess, entry);
break;
}
}
} }
int ksmbd_session_rpc_method(struct ksmbd_session *sess, int id) int ksmbd_session_rpc_method(struct ksmbd_session *sess, int id)
{ {
struct ksmbd_session_rpc *entry; struct ksmbd_session_rpc *entry;
list_for_each_entry(entry, &sess->rpc_handle_list, list) { entry = xa_load(&sess->rpc_handle_list, id);
if (entry->id == id) return entry ? entry->method : 0;
return entry->method;
}
return 0;
} }
void ksmbd_session_destroy(struct ksmbd_session *sess) 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); set_session_flag(sess, protocol);
xa_init(&sess->tree_conns); xa_init(&sess->tree_conns);
xa_init(&sess->ksmbd_chann_list); xa_init(&sess->ksmbd_chann_list);
INIT_LIST_HEAD(&sess->rpc_handle_list); xa_init(&sess->rpc_handle_list);
sess->sequence_number = 1; sess->sequence_number = 1;
ret = __init_smb2_session(sess); ret = __init_smb2_session(sess);

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

@ -52,7 +52,7 @@ struct ksmbd_session {
struct xarray ksmbd_chann_list; struct xarray ksmbd_chann_list;
struct xarray tree_conns; struct xarray tree_conns;
struct ida tree_conn_ida; struct ida tree_conn_ida;
struct list_head rpc_handle_list; struct xarray rpc_handle_list;
__u8 smb3encryptionkey[SMB3_ENC_DEC_KEY_SIZE]; __u8 smb3encryptionkey[SMB3_ENC_DEC_KEY_SIZE];
__u8 smb3decryptionkey[SMB3_ENC_DEC_KEY_SIZE]; __u8 smb3decryptionkey[SMB3_ENC_DEC_KEY_SIZE];