2022-07-25 9:48 GMT+09:00, Hyunchul Lee <hyc.lee@xxxxxxxxx>: > 2022년 7월 22일 (금) 오후 12:04, Namjae Jeon <linkinjeon@xxxxxxxxxx>님이 작성: >> >> ksmbd threads eating masses of cputime when connection is disconnected. >> If connection is disconnected, ksmbd thread waits for pending requests >> to be processed using schedule_timeout. schedule_timeout() incorrectly >> is used, and it is more efficient to use wait_event/wake_up than to check >> r_count every time with timeout. >> >> Signed-off-by: Namjae Jeon <linkinjeon@xxxxxxxxxx> >> --- >> fs/ksmbd/connection.c | 6 +++--- >> fs/ksmbd/connection.h | 1 + >> fs/ksmbd/oplock.c | 21 ++++++++++----------- >> fs/ksmbd/server.c | 1 + >> 4 files changed, 15 insertions(+), 14 deletions(-) >> >> diff --git a/fs/ksmbd/connection.c b/fs/ksmbd/connection.c >> index ce23cc89046e..756ad631c019 100644 >> --- a/fs/ksmbd/connection.c >> +++ b/fs/ksmbd/connection.c >> @@ -66,6 +66,7 @@ struct ksmbd_conn *ksmbd_conn_alloc(void) >> conn->outstanding_credits = 0; >> >> init_waitqueue_head(&conn->req_running_q); >> + init_waitqueue_head(&conn->r_count_q); >> INIT_LIST_HEAD(&conn->conns_list); >> INIT_LIST_HEAD(&conn->requests); >> INIT_LIST_HEAD(&conn->async_requests); >> @@ -165,7 +166,6 @@ int ksmbd_conn_write(struct ksmbd_work *work) >> struct kvec iov[3]; >> int iov_idx = 0; >> >> - ksmbd_conn_try_dequeue_request(work); >> if (!work->response_buf) { >> pr_err("NULL response header\n"); >> return -EINVAL; >> @@ -347,8 +347,8 @@ int ksmbd_conn_handler_loop(void *p) >> >> out: >> /* Wait till all reference dropped to the Server object*/ >> - while (atomic_read(&conn->r_count) > 0) >> - schedule_timeout(HZ); >> + wait_event(conn->r_count_q, atomic_read(&conn->r_count) == 0); >> + >> >> unload_nls(conn->local_nls); >> if (default_conn_ops.terminate_fn) >> diff --git a/fs/ksmbd/connection.h b/fs/ksmbd/connection.h >> index 5b39f0bdeff8..2e4730457c92 100644 >> --- a/fs/ksmbd/connection.h >> +++ b/fs/ksmbd/connection.h >> @@ -65,6 +65,7 @@ struct ksmbd_conn { >> unsigned int outstanding_credits; >> spinlock_t credits_lock; >> wait_queue_head_t req_running_q; >> + wait_queue_head_t r_count_q; >> /* Lock to protect requests list*/ >> spinlock_t request_lock; >> struct list_head requests; >> diff --git a/fs/ksmbd/oplock.c b/fs/ksmbd/oplock.c >> index 8b5560574d4c..9bb4fb8b80de 100644 >> --- a/fs/ksmbd/oplock.c >> +++ b/fs/ksmbd/oplock.c >> @@ -615,18 +615,13 @@ static void __smb2_oplock_break_noti(struct >> work_struct *wk) >> struct ksmbd_file *fp; >> >> fp = ksmbd_lookup_durable_fd(br_info->fid); >> - if (!fp) { >> - atomic_dec(&conn->r_count); >> - ksmbd_free_work_struct(work); >> - return; >> - } >> + if (!fp) >> + goto out; >> >> if (allocate_oplock_break_buf(work)) { >> pr_err("smb2_allocate_rsp_buf failed! "); >> - atomic_dec(&conn->r_count); >> ksmbd_fd_put(work, fp); >> - ksmbd_free_work_struct(work); >> - return; >> + goto out; >> } >> >> rsp_hdr = smb2_get_msg(work->response_buf); >> @@ -667,8 +662,11 @@ static void __smb2_oplock_break_noti(struct >> work_struct *wk) >> >> ksmbd_fd_put(work, fp); >> ksmbd_conn_write(work); >> + >> +out: >> ksmbd_free_work_struct(work); >> atomic_dec(&conn->r_count); >> + wake_up_all(&conn->r_count_q); > > I think calling wake_up_all is better if atomic_dec_return(&conn->r_count) > == 0. Are there cases where r_count inc/dec doesn't pair? > Otherwise, Looks good to me. > >> } >> >> /** >> @@ -731,9 +729,7 @@ static void __smb2_lease_break_noti(struct work_struct >> *wk) >> >> if (allocate_oplock_break_buf(work)) { >> ksmbd_debug(OPLOCK, "smb2_allocate_rsp_buf failed! "); >> - ksmbd_free_work_struct(work); >> - atomic_dec(&conn->r_count); >> - return; >> + goto out; >> } >> >> rsp_hdr = smb2_get_msg(work->response_buf); >> @@ -771,8 +767,11 @@ static void __smb2_lease_break_noti(struct >> work_struct *wk) >> inc_rfc1001_len(work->response_buf, 44); >> >> ksmbd_conn_write(work); >> + >> +out: >> ksmbd_free_work_struct(work); >> atomic_dec(&conn->r_count); >> + wake_up_all(&conn->r_count_q); >> } >> >> /** >> diff --git a/fs/ksmbd/server.c b/fs/ksmbd/server.c >> index 4cd03d661df0..dfddc8dc1919 100644 >> --- a/fs/ksmbd/server.c >> +++ b/fs/ksmbd/server.c >> @@ -262,6 +262,7 @@ static void handle_ksmbd_work(struct work_struct *wk) >> ksmbd_conn_try_dequeue_request(work); >> ksmbd_free_work_struct(work); >> atomic_dec(&conn->r_count); >> + wake_up_all(&conn->r_count_q); >> } >> >> /** >> -- >> 2.25.1 >> > > > -- > Thanks, > Hyunchul >