net/smc: terminate link group if out-of-sync is received
authorUrsula Braun <ubraun@linux.vnet.ibm.com>
Thu, 21 Sep 2017 07:16:32 +0000 (09:16 +0200)
committerDavid S. Miller <davem@davemloft.net>
Thu, 21 Sep 2017 22:31:03 +0000 (15:31 -0700)
An out-of-sync condition can just be detected by the client.
If the server receives a CLC DECLINE message indicating an out-of-sync
condition for the link groups, the server must clean up the out-of-sync
link group.
There is no need for an extra third parameter in smc_clc_send_decline().

Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/smc/af_smc.c
net/smc/smc_clc.c
net/smc/smc_clc.h

index 2e8d2dabac0ca38d22c9bc4e74a91f700be379ce..745f145d4c4d43316f3cb30083066456497fec3a 100644 (file)
@@ -513,7 +513,7 @@ decline_rdma:
        /* RDMA setup failed, switch back to TCP */
        smc->use_fallback = true;
        if (reason_code && (reason_code != SMC_CLC_DECL_REPLY)) {
-               rc = smc_clc_send_decline(smc, reason_code, 0);
+               rc = smc_clc_send_decline(smc, reason_code);
                if (rc < sizeof(struct smc_clc_msg_decline))
                        goto out_err;
        }
@@ -808,8 +808,6 @@ static void smc_listen_work(struct work_struct *work)
                rc = local_contact;
                if (rc == -ENOMEM)
                        reason_code = SMC_CLC_DECL_MEM;/* insufficient memory*/
-               else if (rc == -ENOLINK)
-                       reason_code = SMC_CLC_DECL_SYNCERR; /* synchr. error */
                goto decline_rdma;
        }
        link = &new_smc->conn.lgr->lnk[SMC_SINGLE_LINK];
@@ -903,7 +901,7 @@ decline_rdma:
        smc_conn_free(&new_smc->conn);
        new_smc->use_fallback = true;
        if (reason_code && (reason_code != SMC_CLC_DECL_REPLY)) {
-               rc = smc_clc_send_decline(new_smc, reason_code, 0);
+               rc = smc_clc_send_decline(new_smc, reason_code);
                if (rc < sizeof(struct smc_clc_msg_decline))
                        goto out_err;
        }
index 3934913ab835cc791362a6a2ea816e871ce2cee1..b7dd2743fb5c0cfa11228b6c36b3a7fe3c53498e 100644 (file)
@@ -95,9 +95,10 @@ int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen,
        }
        if (clcm->type == SMC_CLC_DECLINE) {
                reason_code = SMC_CLC_DECL_REPLY;
-               if (ntohl(((struct smc_clc_msg_decline *)buf)->peer_diagnosis)
-                       == SMC_CLC_DECL_SYNCERR)
+               if (((struct smc_clc_msg_decline *)buf)->hdr.flag) {
                        smc->conn.lgr->sync_err = true;
+                       smc_lgr_terminate(smc->conn.lgr);
+               }
        }
 
 out:
@@ -105,8 +106,7 @@ out:
 }
 
 /* send CLC DECLINE message across internal TCP socket */
-int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info,
-                        u8 out_of_sync)
+int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info)
 {
        struct smc_clc_msg_decline dclc;
        struct msghdr msg;
@@ -118,7 +118,7 @@ int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info,
        dclc.hdr.type = SMC_CLC_DECLINE;
        dclc.hdr.length = htons(sizeof(struct smc_clc_msg_decline));
        dclc.hdr.version = SMC_CLC_V1;
-       dclc.hdr.flag = out_of_sync ? 1 : 0;
+       dclc.hdr.flag = (peer_diag_info == SMC_CLC_DECL_SYNCERR) ? 1 : 0;
        memcpy(dclc.id_for_peer, local_systemid, sizeof(local_systemid));
        dclc.peer_diagnosis = htonl(peer_diag_info);
        memcpy(dclc.trl.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER));
index 13db8ce177c91dd913fac15fdebb5e05875e0ec9..1c55414041d49b560dfdd89fe9c1ed122a073cea 100644 (file)
@@ -106,8 +106,7 @@ struct smc_ib_device;
 
 int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen,
                     u8 expected_type);
-int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info,
-                        u8 out_of_sync);
+int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info);
 int smc_clc_send_proposal(struct smc_sock *smc, struct smc_ib_device *smcibdev,
                          u8 ibport);
 int smc_clc_send_confirm(struct smc_sock *smc);