]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
smb: client: make only use of wake_up[_all]() in smbdirect.c
authorStefan Metzmacher <metze@samba.org>
Thu, 14 Aug 2025 08:06:50 +0000 (10:06 +0200)
committerSteve French <stfrench@microsoft.com>
Sun, 28 Sep 2025 23:29:48 +0000 (18:29 -0500)
wake_up_interruptible[_all]() doesn't wake up tasks waiting
with wait_event().

So we better wake_up[_all]() in order to wake up all tasks in order
to simplify the logic.

As we currently don't use any wait_event_*_exclusive() it
doesn't really matter if we use wake_up() or wake_up_all().
But in this patch I try to use wake_up() for expected situations
and wake_up_all() for situations of a broken connection.
So don't need to adjust things in future when we
may use wait_event_*_exclusive() in order to wake up
only one process that should make progress.

Changing the wait_event_*() code in order to keep
wait_event(), wait_event_interruptible() and
wait_event_interruptible_timeout() or
changing them to wait_event_killable(),
wait_event_killable_timeout(),
wait_event_killable_exclusive()
is something to think about in a future patch.

The goal here is to avoid that some tasks are not
woken and freeze forever.

Also note that this patch only changes the existing
wake_up*() calls. Adding more wake_up*() calls for
other wait queues is also deferred to a future patch.

Link: https://lore.kernel.org/linux-cifs/13851363-0dc9-465c-9ced-3ede4904eef0@samba.org/T/#t
Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Long Li <longli@microsoft.com>
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/client/smbdirect.c

index 501c515ec04f47d6a81f5faeb8c5e10c7ec5a4f9..82d36fb248fd4ffb1fa9cf13e188b57ac72a88a9 100644 (file)
@@ -217,27 +217,27 @@ static int smbd_conn_upcall(
        case RDMA_CM_EVENT_ADDR_RESOLVED:
                WARN_ON_ONCE(sc->status != SMBDIRECT_SOCKET_RESOLVE_ADDR_RUNNING);
                sc->status = SMBDIRECT_SOCKET_RESOLVE_ROUTE_NEEDED;
-               wake_up_interruptible(&sc->status_wait);
+               wake_up(&sc->status_wait);
                break;
 
        case RDMA_CM_EVENT_ROUTE_RESOLVED:
                WARN_ON_ONCE(sc->status != SMBDIRECT_SOCKET_RESOLVE_ROUTE_RUNNING);
                sc->status = SMBDIRECT_SOCKET_RDMA_CONNECT_NEEDED;
-               wake_up_interruptible(&sc->status_wait);
+               wake_up(&sc->status_wait);
                break;
 
        case RDMA_CM_EVENT_ADDR_ERROR:
                log_rdma_event(ERR, "connecting failed event=%s\n", event_name);
                WARN_ON_ONCE(sc->status != SMBDIRECT_SOCKET_RESOLVE_ADDR_RUNNING);
                sc->status = SMBDIRECT_SOCKET_RESOLVE_ADDR_FAILED;
-               wake_up_interruptible(&sc->status_wait);
+               wake_up_all(&sc->status_wait);
                break;
 
        case RDMA_CM_EVENT_ROUTE_ERROR:
                log_rdma_event(ERR, "connecting failed event=%s\n", event_name);
                WARN_ON_ONCE(sc->status != SMBDIRECT_SOCKET_RESOLVE_ROUTE_RUNNING);
                sc->status = SMBDIRECT_SOCKET_RESOLVE_ROUTE_FAILED;
-               wake_up_interruptible(&sc->status_wait);
+               wake_up_all(&sc->status_wait);
                break;
 
        case RDMA_CM_EVENT_ESTABLISHED:
@@ -323,7 +323,7 @@ static int smbd_conn_upcall(
 
                WARN_ON_ONCE(sc->status != SMBDIRECT_SOCKET_RDMA_CONNECT_RUNNING);
                sc->status = SMBDIRECT_SOCKET_NEGOTIATE_NEEDED;
-               wake_up_interruptible(&sc->status_wait);
+               wake_up(&sc->status_wait);
                break;
 
        case RDMA_CM_EVENT_CONNECT_ERROR:
@@ -332,7 +332,7 @@ static int smbd_conn_upcall(
                log_rdma_event(ERR, "connecting failed event=%s\n", event_name);
                WARN_ON_ONCE(sc->status != SMBDIRECT_SOCKET_RDMA_CONNECT_RUNNING);
                sc->status = SMBDIRECT_SOCKET_RDMA_CONNECT_FAILED;
-               wake_up_interruptible(&sc->status_wait);
+               wake_up_all(&sc->status_wait);
                break;
 
        case RDMA_CM_EVENT_DEVICE_REMOVAL:
@@ -341,14 +341,14 @@ static int smbd_conn_upcall(
                if (sc->status == SMBDIRECT_SOCKET_NEGOTIATE_FAILED) {
                        log_rdma_event(ERR, "event=%s during negotiation\n", event_name);
                        sc->status = SMBDIRECT_SOCKET_DISCONNECTED;
-                       wake_up(&sc->status_wait);
+                       wake_up_all(&sc->status_wait);
                        break;
                }
 
                sc->status = SMBDIRECT_SOCKET_DISCONNECTED;
-               wake_up_interruptible(&sc->status_wait);
-               wake_up_interruptible(&sc->recv_io.reassembly.wait_queue);
-               wake_up_interruptible_all(&info->wait_send_queue);
+               wake_up_all(&sc->status_wait);
+               wake_up_all(&sc->recv_io.reassembly.wait_queue);
+               wake_up_all(&info->wait_send_queue);
                break;
 
        default:
@@ -525,7 +525,7 @@ static void smbd_post_send_credits(struct work_struct *work)
        struct smbdirect_socket *sc = &info->socket;
 
        if (sc->status != SMBDIRECT_SOCKET_CONNECTED) {
-               wake_up(&info->wait_receive_queues);
+               wake_up_all(&info->wait_receive_queues);
                return;
        }
 
@@ -605,12 +605,14 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
                        process_negotiation_response(response, wc->byte_len);
                put_receive_buffer(info, response);
                WARN_ON_ONCE(sc->status != SMBDIRECT_SOCKET_NEGOTIATE_RUNNING);
-               if (!negotiate_done)
+               if (!negotiate_done) {
                        sc->status = SMBDIRECT_SOCKET_NEGOTIATE_FAILED;
-               else
+                       wake_up_all(&sc->status_wait);
+               } else {
                        sc->status = SMBDIRECT_SOCKET_CONNECTED;
+                       wake_up(&sc->status_wait);
+               }
 
-               wake_up_interruptible(&sc->status_wait);
                return;
 
        /* SMBD data transfer packet */
@@ -653,7 +655,7 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
                         * We have new send credits granted from remote peer
                         * If any sender is waiting for credits, unblock it
                         */
-                       wake_up_interruptible(&info->wait_send_queue);
+                       wake_up(&info->wait_send_queue);
                }
 
                log_incoming(INFO, "data flags %d data_offset %d data_length %d remaining_data_length %d\n",
@@ -675,7 +677,7 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
                 */
                if (data_length) {
                        enqueue_reassembly(info, response, data_length);
-                       wake_up_interruptible(&sc->recv_io.reassembly.wait_queue);
+                       wake_up(&sc->recv_io.reassembly.wait_queue);
                } else
                        put_receive_buffer(info, response);
 
@@ -1536,7 +1538,7 @@ void smbd_destroy(struct TCP_Server_Info *server)
         * path when sending data, and then release memory registrations.
         */
        log_rdma_event(INFO, "freeing mr list\n");
-       wake_up_interruptible_all(&info->wait_mr);
+       wake_up_all(&info->wait_mr);
        while (atomic_read(&info->mr_used_count)) {
                cifs_server_unlock(server);
                msleep(1000);
@@ -2235,7 +2237,7 @@ static void smbd_mr_recovery_work(struct work_struct *work)
                 * get_mr() from the I/O issuing CPUs
                 */
                if (atomic_inc_return(&info->mr_ready_count) == 1)
-                       wake_up_interruptible(&info->wait_mr);
+                       wake_up(&info->wait_mr);
        }
 }
 
@@ -2546,7 +2548,7 @@ int smbd_deregister_mr(struct smbd_mr *smbdirect_mr)
                        smbdirect_mr->dir);
                smbdirect_mr->state = MR_READY;
                if (atomic_inc_return(&info->mr_ready_count) == 1)
-                       wake_up_interruptible(&info->wait_mr);
+                       wake_up(&info->wait_mr);
        } else
                /*
                 * Schedule the work to do MR recovery for future I/Os MR