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:
Родитель
1d9c417211
Коммит
b685757c7b
|
@ -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);
|
||||
|
|
|
@ -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];
|
||||
|
|
Загрузка…
Ссылка в новой задаче