Patch "can: isotp: isotp_sendmsg(): fix TX state detection and wait behavior" has been added to the 6.5-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    can: isotp: isotp_sendmsg(): fix TX state detection and wait behavior

to the 6.5-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     can-isotp-isotp_sendmsg-fix-tx-state-detection-and-w.patch
and it can be found in the queue-6.5 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 551206b1d9526c1c34ca87de8629cc0fdfc4f463
Author: Lukas Magel <lukas.magel@xxxxxxxxxx>
Date:   Sun Aug 27 09:22:05 2023 +0000

    can: isotp: isotp_sendmsg(): fix TX state detection and wait behavior
    
    [ Upstream commit d9c2ba65e651467de739324d978b04ed8729f483 ]
    
    With patch [1], isotp_poll was updated to also queue the poller in the
    so->wait queue, which is used for send state changes. Since the queue
    now also contains polling tasks that are not interested in sending, the
    queue fill state can no longer be used as an indication of send
    readiness. As a consequence, nonblocking writes can lead to a race and
    lock-up of the socket if there is a second task polling the socket in
    parallel.
    
    With this patch, isotp_sendmsg does not consult wq_has_sleepers but
    instead tries to atomically set so->tx.state and waits on so->wait if it
    is unable to do so. This behavior is in alignment with isotp_poll, which
    also checks so->tx.state to determine send readiness.
    
    V2:
    - Revert direct exit to goto err_event_drop
    
    [1] https://lore.kernel.org/all/20230331125511.372783-1-michal.sojka@xxxxxxx
    
    Reported-by: Maxime Jayat <maxime.jayat@xxxxxxxxxxxxxxxxx>
    Closes: https://lore.kernel.org/linux-can/11328958-453f-447f-9af8-3b5824dfb041@xxxxxxxx/
    Signed-off-by: Lukas Magel <lukas.magel@xxxxxxxxxx>
    Reviewed-by: Oliver Hartkopp <socketcan@xxxxxxxxxxxx>
    Fixes: 79e19fa79cb5 ("can: isotp: isotp_ops: fix poll() to not report false EPOLLOUT events")
    Link: https://github.com/pylessard/python-udsoncan/issues/178#issuecomment-1743786590
    Link: https://lore.kernel.org/all/20230827092205.7908-1-lukas.magel@xxxxxxxxxx
    Signed-off-by: Marc Kleine-Budde <mkl@xxxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/net/can/isotp.c b/net/can/isotp.c
index f02b5d3e47335..d1c6f206f4295 100644
--- a/net/can/isotp.c
+++ b/net/can/isotp.c
@@ -948,21 +948,18 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
 	if (!so->bound || so->tx.state == ISOTP_SHUTDOWN)
 		return -EADDRNOTAVAIL;
 
-wait_free_buffer:
-	/* we do not support multiple buffers - for now */
-	if (wq_has_sleeper(&so->wait) && (msg->msg_flags & MSG_DONTWAIT))
-		return -EAGAIN;
+	while (cmpxchg(&so->tx.state, ISOTP_IDLE, ISOTP_SENDING) != ISOTP_IDLE) {
+		/* we do not support multiple buffers - for now */
+		if (msg->msg_flags & MSG_DONTWAIT)
+			return -EAGAIN;
 
-	/* wait for complete transmission of current pdu */
-	err = wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE);
-	if (err)
-		goto err_event_drop;
-
-	if (cmpxchg(&so->tx.state, ISOTP_IDLE, ISOTP_SENDING) != ISOTP_IDLE) {
 		if (so->tx.state == ISOTP_SHUTDOWN)
 			return -EADDRNOTAVAIL;
 
-		goto wait_free_buffer;
+		/* wait for complete transmission of current pdu */
+		err = wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE);
+		if (err)
+			goto err_event_drop;
 	}
 
 	/* PDU size > default => try max_pdu_size */



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux