net/smc: save state of last sent CDC message
authorKarsten Graul <kgraul@linux.ibm.com>
Mon, 4 May 2020 12:18:37 +0000 (14:18 +0200)
committerDavid S. Miller <davem@davemloft.net>
Mon, 4 May 2020 17:54:39 +0000 (10:54 -0700)
When a link goes down and all connections of this link need to be
switched to an other link then the producer cursor and the sequence of
the last successfully sent CDC message must be known. Add the two fields
to the SMC connection and update it in the tx completion handler.
And to allow matching of sequences in error cases reset the seqno to the
old value in smc_cdc_msg_send() when the actual send failed.

Signed-off-by: Karsten Graul <kgraul@linux.ibm.com>
Reviewed-by: Ursula Braun <ubraun@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/smc/smc.h
net/smc/smc_cdc.c

index 1a084afa7372bfb8c2bcc295fed9443078ee5d3c..1e911377160091cb8d5cd2351f335a7ef140778a 100644 (file)
@@ -143,6 +143,9 @@ struct smc_connection {
                                                 * .prod cf. TCP snd_nxt
                                                 * .cons cf. TCP sends ack
                                                 */
+       union smc_host_cursor   local_tx_ctrl_fin;
+                                               /* prod crsr - confirmed by peer
+                                                */
        union smc_host_cursor   tx_curs_prep;   /* tx - prepared data
                                                 * snd_max..wmem_alloc
                                                 */
@@ -154,6 +157,7 @@ struct smc_connection {
                                                 */
        atomic_t                sndbuf_space;   /* remaining space in sndbuf */
        u16                     tx_cdc_seq;     /* sequence # for CDC send */
+       u16                     tx_cdc_seq_fin; /* sequence # - tx completed */
        spinlock_t              send_lock;      /* protect wr_sends */
        struct delayed_work     tx_work;        /* retry of smc_cdc_msg_send */
        u32                     tx_off;         /* base offset in peer rmb */
index f64589d823aa05bcd57d06b57e67f435992f1b3c..c5e33296e55c3789698fc421d5d0e2d8cac55f57 100644 (file)
@@ -47,6 +47,9 @@ static void smc_cdc_tx_handler(struct smc_wr_tx_pend_priv *pnd_snd,
                /* guarantee 0 <= sndbuf_space <= sndbuf_desc->len */
                smp_mb__after_atomic();
                smc_curs_copy(&conn->tx_curs_fin, &cdcpend->cursor, conn);
+               smc_curs_copy(&conn->local_tx_ctrl_fin, &cdcpend->p_cursor,
+                             conn);
+               conn->tx_cdc_seq_fin = cdcpend->ctrl_seq;
        }
        smc_tx_sndbuf_nonfull(smc);
        bh_unlock_sock(&smc->sk);
@@ -104,6 +107,9 @@ int smc_cdc_msg_send(struct smc_connection *conn,
        if (!rc) {
                smc_curs_copy(&conn->rx_curs_confirmed, &cfed, conn);
                conn->local_rx_ctrl.prod_flags.cons_curs_upd_req = 0;
+       } else {
+               conn->tx_cdc_seq--;
+               conn->local_tx_ctrl.seqno = conn->tx_cdc_seq;
        }
 
        return rc;