From: Stefan Metzmacher Date: Fri, 15 Aug 2025 10:53:35 +0000 (+0200) Subject: smb: client: send empty packets via send_immediate_work X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1b2c46cdb7c0127711cd72028072d85f6ebd1b53;p=thirdparty%2Fkernel%2Fstable.git smb: client: send empty packets via send_immediate_work This is what the server already does and it makes refactoring for common structures and functions much easier. Cc: Steve French Cc: Tom Talpey Cc: Long Li Cc: linux-cifs@vger.kernel.org Cc: samba-technical@lists.samba.org Acked-by: Namjae Jeon Signed-off-by: Stefan Metzmacher Signed-off-by: Steve French --- diff --git a/fs/smb/client/smbdirect.c b/fs/smb/client/smbdirect.c index b910d62d66c58..d53e39e91e105 100644 --- a/fs/smb/client/smbdirect.c +++ b/fs/smb/client/smbdirect.c @@ -173,6 +173,7 @@ static void smbd_disconnect_rdma_work(struct work_struct *work) disable_work(&sc->disconnect_work); disable_work(&sc->recv_io.posted.refill_work); disable_work(&info->mr_recovery_work); + disable_work(&info->send_immediate_work); disable_delayed_work(&info->idle_timer_work); switch (sc->status) { @@ -569,8 +570,8 @@ static void smbd_post_send_credits(struct work_struct *work) /* Promptly send an immediate packet as defined in [MS-SMBD] 3.1.1.1 */ if (atomic_read(&sc->recv_io.credits.count) < sc->recv_io.credits.target - 1) { - log_keep_alive(INFO, "send an empty message\n"); - smbd_post_send_empty(info); + log_keep_alive(INFO, "schedule send of an empty message\n"); + queue_work(info->workqueue, &info->send_immediate_work); } } @@ -1455,6 +1456,19 @@ static void destroy_receive_buffers(struct smbd_connection *info) mempool_free(response, sc->recv_io.mem.pool); } +static void send_immediate_empty_message(struct work_struct *work) +{ + struct smbd_connection *info = + container_of(work, struct smbd_connection, send_immediate_work); + struct smbdirect_socket *sc = &info->socket; + + if (sc->status != SMBDIRECT_SOCKET_CONNECTED) + return; + + log_keep_alive(INFO, "send an empty message\n"); + smbd_post_send_empty(info); +} + /* Implement idle connection timer [MS-SMBD] 3.1.6.2 */ static void idle_connection_timer(struct work_struct *work) { @@ -1472,8 +1486,8 @@ static void idle_connection_timer(struct work_struct *work) return; } - log_keep_alive(INFO, "about to send an empty idle message\n"); - smbd_post_send_empty(info); + log_keep_alive(INFO, "schedule send of empty idle message\n"); + queue_work(info->workqueue, &info->send_immediate_work); /* Setup the next idle timeout work */ queue_delayed_work(info->workqueue, &info->idle_timer_work, @@ -1520,6 +1534,8 @@ void smbd_destroy(struct TCP_Server_Info *server) log_rdma_event(INFO, "cancelling idle timer\n"); disable_delayed_work_sync(&info->idle_timer_work); + log_rdma_event(INFO, "cancelling send immediate work\n"); + disable_work_sync(&info->send_immediate_work); /* It's not possible for upper layer to get to reassembly */ log_rdma_event(INFO, "drain the reassembly queue\n"); @@ -1863,6 +1879,7 @@ static struct smbd_connection *_smbd_get_connection( goto allocate_cache_failed; } + INIT_WORK(&info->send_immediate_work, send_immediate_empty_message); INIT_DELAYED_WORK(&info->idle_timer_work, idle_connection_timer); queue_delayed_work(info->workqueue, &info->idle_timer_work, msecs_to_jiffies(sp->keepalive_interval_msec)); diff --git a/fs/smb/client/smbdirect.h b/fs/smb/client/smbdirect.h index 1bb9b9412685b..07c7fba2f340b 100644 --- a/fs/smb/client/smbdirect.h +++ b/fs/smb/client/smbdirect.h @@ -71,6 +71,7 @@ struct smbd_connection { wait_queue_head_t wait_for_mr_cleanup; struct workqueue_struct *workqueue; + struct work_struct send_immediate_work; struct delayed_work idle_timer_work; /* for debug purposes */