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 {
|
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];
|
||||||
|
|
Загрузка…
Ссылка в новой задаче