Commit bfbedfd3 authored by Ursula Braun's avatar Ursula Braun Committed by David S. Miller

net/smc: terminate link group if out-of-sync is received

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: default avatarUrsula Braun <ubraun@linux.vnet.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5bc11ddb
...@@ -513,7 +513,7 @@ static int smc_connect_rdma(struct smc_sock *smc) ...@@ -513,7 +513,7 @@ static int smc_connect_rdma(struct smc_sock *smc)
/* RDMA setup failed, switch back to TCP */ /* RDMA setup failed, switch back to TCP */
smc->use_fallback = true; smc->use_fallback = true;
if (reason_code && (reason_code != SMC_CLC_DECL_REPLY)) { 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)) if (rc < sizeof(struct smc_clc_msg_decline))
goto out_err; goto out_err;
} }
...@@ -808,8 +808,6 @@ static void smc_listen_work(struct work_struct *work) ...@@ -808,8 +808,6 @@ static void smc_listen_work(struct work_struct *work)
rc = local_contact; rc = local_contact;
if (rc == -ENOMEM) if (rc == -ENOMEM)
reason_code = SMC_CLC_DECL_MEM;/* insufficient memory*/ reason_code = SMC_CLC_DECL_MEM;/* insufficient memory*/
else if (rc == -ENOLINK)
reason_code = SMC_CLC_DECL_SYNCERR; /* synchr. error */
goto decline_rdma; goto decline_rdma;
} }
link = &new_smc->conn.lgr->lnk[SMC_SINGLE_LINK]; link = &new_smc->conn.lgr->lnk[SMC_SINGLE_LINK];
...@@ -903,7 +901,7 @@ static void smc_listen_work(struct work_struct *work) ...@@ -903,7 +901,7 @@ static void smc_listen_work(struct work_struct *work)
smc_conn_free(&new_smc->conn); smc_conn_free(&new_smc->conn);
new_smc->use_fallback = true; new_smc->use_fallback = true;
if (reason_code && (reason_code != SMC_CLC_DECL_REPLY)) { 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)) if (rc < sizeof(struct smc_clc_msg_decline))
goto out_err; goto out_err;
} }
......
...@@ -95,9 +95,10 @@ int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen, ...@@ -95,9 +95,10 @@ int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen,
} }
if (clcm->type == SMC_CLC_DECLINE) { if (clcm->type == SMC_CLC_DECLINE) {
reason_code = SMC_CLC_DECL_REPLY; reason_code = SMC_CLC_DECL_REPLY;
if (ntohl(((struct smc_clc_msg_decline *)buf)->peer_diagnosis) if (((struct smc_clc_msg_decline *)buf)->hdr.flag) {
== SMC_CLC_DECL_SYNCERR)
smc->conn.lgr->sync_err = true; smc->conn.lgr->sync_err = true;
smc_lgr_terminate(smc->conn.lgr);
}
} }
out: out:
...@@ -105,8 +106,7 @@ int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen, ...@@ -105,8 +106,7 @@ int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen,
} }
/* send CLC DECLINE message across internal TCP socket */ /* send CLC DECLINE message across internal TCP socket */
int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info, int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info)
u8 out_of_sync)
{ {
struct smc_clc_msg_decline dclc; struct smc_clc_msg_decline dclc;
struct msghdr msg; struct msghdr msg;
...@@ -118,7 +118,7 @@ int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info, ...@@ -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.type = SMC_CLC_DECLINE;
dclc.hdr.length = htons(sizeof(struct smc_clc_msg_decline)); dclc.hdr.length = htons(sizeof(struct smc_clc_msg_decline));
dclc.hdr.version = SMC_CLC_V1; 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)); memcpy(dclc.id_for_peer, local_systemid, sizeof(local_systemid));
dclc.peer_diagnosis = htonl(peer_diag_info); dclc.peer_diagnosis = htonl(peer_diag_info);
memcpy(dclc.trl.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER)); memcpy(dclc.trl.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER));
......
...@@ -106,8 +106,7 @@ struct smc_ib_device; ...@@ -106,8 +106,7 @@ struct smc_ib_device;
int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen, int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen,
u8 expected_type); u8 expected_type);
int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info, int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info);
u8 out_of_sync);
int smc_clc_send_proposal(struct smc_sock *smc, struct smc_ib_device *smcibdev, int smc_clc_send_proposal(struct smc_sock *smc, struct smc_ib_device *smcibdev,
u8 ibport); u8 ibport);
int smc_clc_send_confirm(struct smc_sock *smc); int smc_clc_send_confirm(struct smc_sock *smc);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment