diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c index cbeb5637eeb9..104658e318b6 100644 --- a/fs/smb/client/connect.c +++ b/fs/smb/client/connect.c @@ -1871,14 +1871,6 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx, * this will succeed. No need for try_module_get(). */ __module_get(THIS_MODULE); - tcp_ses->tsk = kthread_run(cifs_demultiplex_thread, - tcp_ses, "cifsd"); - if (IS_ERR(tcp_ses->tsk)) { - rc = PTR_ERR(tcp_ses->tsk); - cifs_dbg(VFS, "error %d create cifsd thread\n", rc); - module_put(THIS_MODULE); - goto out_err_crypto_release; - } tcp_ses->min_offload = ctx->min_offload; tcp_ses->retrans = ctx->retrans; /* @@ -1886,9 +1878,7 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx, * to the struct since the kernel thread not created yet * no need to spinlock this update of tcpStatus */ - spin_lock(&tcp_ses->srv_lock); tcp_ses->tcpStatus = CifsNeedNegotiate; - spin_unlock(&tcp_ses->srv_lock); if ((ctx->max_credits < 20) || (ctx->max_credits > 60000)) tcp_ses->max_credits = SMB2_MAX_CREDITS_AVAILABLE; @@ -1897,7 +1887,16 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx, tcp_ses->nr_targets = 1; tcp_ses->ignore_signature = ctx->ignore_signature; - /* thread spawned, put it on the list */ + + tcp_ses->tsk = kthread_create(cifs_demultiplex_thread, + tcp_ses, "cifsd"); + if (IS_ERR(tcp_ses->tsk)) { + rc = PTR_ERR(tcp_ses->tsk); + cifs_dbg(VFS, "error %d create cifsd thread\n", rc); + module_put(THIS_MODULE); + goto out_err_crypto_release; + } + /* thread created, put it on the list */ spin_lock(&cifs_tcp_ses_lock); list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list); spin_unlock(&cifs_tcp_ses_lock); @@ -1905,6 +1904,12 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx, /* queue echo request delayed work */ queue_delayed_work(cifsiod_wq, &tcp_ses->echo, tcp_ses->echo_interval); + /* + * Use split create/wake logic to ensure that tcp_ses is fully populated + * and tcp_ses->tsk is valid + */ + wake_up_process(tcp_ses->tsk); + return tcp_ses; out_err_crypto_release: