Patch "net/smc: Ensure the active closing peer first closes clcsock" has been added to the 4.14-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

    net/smc: Ensure the active closing peer first closes clcsock

to the 4.14-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:
     net-smc-ensure-the-active-closing-peer-first-closes-.patch
and it can be found in the queue-4.14 subdirectory.

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



commit a6adc93a46aea052fe7a9aa972662009ccf69829
Author: Tony Lu <tonylu@xxxxxxxxxxxxxxxxx>
Date:   Tue Nov 23 16:25:18 2021 +0800

    net/smc: Ensure the active closing peer first closes clcsock
    
    [ Upstream commit 606a63c9783a32a45bd2ef0eee393711d75b3284 ]
    
    The side that actively closed socket, it's clcsock doesn't enter
    TIME_WAIT state, but the passive side does it. It should show the same
    behavior as TCP sockets.
    
    Consider this, when client actively closes the socket, the clcsock in
    server enters TIME_WAIT state, which means the address is occupied and
    won't be reused before TIME_WAIT dismissing. If we restarted server, the
    service would be unavailable for a long time.
    
    To solve this issue, shutdown the clcsock in [A], perform the TCP active
    close progress first, before the passive closed side closing it. So that
    the actively closed side enters TIME_WAIT, not the passive one.
    
    Client                                            |  Server
    close() // client actively close                  |
      smc_release()                                   |
          smc_close_active() // PEERCLOSEWAIT1        |
              smc_close_final() // abort or closed = 1|
                  smc_cdc_get_slot_and_msg_send()     |
              [A]                                     |
                                                      |smc_cdc_msg_recv_action() // ACTIVE
                                                      |  queue_work(smc_close_wq, &conn->close_work)
                                                      |    smc_close_passive_work() // PROCESSABORT or APPCLOSEWAIT1
                                                      |      smc_close_passive_abort_received() // only in abort
                                                      |
                                                      |close() // server recv zero, close
                                                      |  smc_release() // PROCESSABORT or APPCLOSEWAIT1
                                                      |    smc_close_active()
                                                      |      smc_close_abort() or smc_close_final() // CLOSED
                                                      |        smc_cdc_get_slot_and_msg_send() // abort or closed = 1
    smc_cdc_msg_recv_action()                         |    smc_clcsock_release()
      queue_work(smc_close_wq, &conn->close_work)     |      sock_release(tcp) // actively close clc, enter TIME_WAIT
        smc_close_passive_work() // PEERCLOSEWAIT1    |    smc_conn_free()
          smc_close_passive_abort_received() // CLOSED|
          smc_conn_free()                             |
          smc_clcsock_release()                       |
            sock_release(tcp) // passive close clc    |
    
    Link: https://www.spinics.net/lists/netdev/msg780407.html
    Fixes: b38d732477e4 ("smc: socket closing and linkgroup cleanup")
    Signed-off-by: Tony Lu <tonylu@xxxxxxxxxxxxxxxxx>
    Reviewed-by: Wen Gu <guwen@xxxxxxxxxxxxxxxxx>
    Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/net/smc/smc_close.c b/net/smc/smc_close.c
index 2427a1f3d0d12..d915907ac29ae 100644
--- a/net/smc/smc_close.c
+++ b/net/smc/smc_close.c
@@ -215,6 +215,12 @@ int smc_close_active(struct smc_sock *smc)
 			/* send close request */
 			rc = smc_close_final(conn);
 			sk->sk_state = SMC_PEERCLOSEWAIT1;
+
+			/* actively shutdown clcsock before peer close it,
+			 * prevent peer from entering TIME_WAIT state.
+			 */
+			if (smc->clcsock && smc->clcsock->sk)
+				rc = kernel_sock_shutdown(smc->clcsock, SHUT_RDWR);
 		} else {
 			/* peer event has changed the state */
 			goto again;



[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