OSDN Git Service

net/smc: allow fallback after clc timeouts
authorUrsula Braun <ubraun@linux.ibm.com>
Thu, 22 Nov 2018 09:26:37 +0000 (10:26 +0100)
committerDavid S. Miller <davem@davemloft.net>
Sat, 24 Nov 2018 01:20:32 +0000 (17:20 -0800)
If connection initialization fails for the LLC CONFIRM LINK or the
LLC ADD LINK step, fallback to TCP should be enabled. Thus
the negative return code -EAGAIN should switch to a positive timeout
reason code in these cases, and the internal CLC socket should
not have a set sk_err.

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

index d9b1a0e..66836cf 100644 (file)
@@ -336,7 +336,7 @@ static int smc_clnt_conf_first_link(struct smc_sock *smc)
 
                rc = smc_clc_wait_msg(smc, &dclc, sizeof(dclc),
                                      SMC_CLC_DECLINE);
-               return rc;
+               return rc == -EAGAIN ? SMC_CLC_DECL_TIMEOUT_CL : rc;
        }
 
        if (link->llc_confirm_rc)
@@ -364,7 +364,7 @@ static int smc_clnt_conf_first_link(struct smc_sock *smc)
 
                rc = smc_clc_wait_msg(smc, &dclc, sizeof(dclc),
                                      SMC_CLC_DECLINE);
-               return rc;
+               return rc == -EAGAIN ? SMC_CLC_DECL_TIMEOUT_AL : rc;
        }
 
        /* send add link reject message, only one link supported for now */
@@ -966,7 +966,7 @@ static int smc_serv_conf_first_link(struct smc_sock *smc)
 
                rc = smc_clc_wait_msg(smc, &dclc, sizeof(dclc),
                                      SMC_CLC_DECLINE);
-               return rc;
+               return rc == -EAGAIN ? SMC_CLC_DECL_TIMEOUT_CL : rc;
        }
 
        if (link->llc_confirm_resp_rc)
@@ -987,7 +987,7 @@ static int smc_serv_conf_first_link(struct smc_sock *smc)
 
                rc = smc_clc_wait_msg(smc, &dclc, sizeof(dclc),
                                      SMC_CLC_DECLINE);
-               return rc;
+               return rc == -EAGAIN ? SMC_CLC_DECL_TIMEOUT_AL : rc;
        }
 
        smc_llc_link_active(link, net->ipv4.sysctl_tcp_keepalive_time);
index 7278ec0..62043d6 100644 (file)
@@ -297,7 +297,11 @@ int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen,
        }
        if (clc_sk->sk_err) {
                reason_code = -clc_sk->sk_err;
-               smc->sk.sk_err = clc_sk->sk_err;
+               if (clc_sk->sk_err == EAGAIN &&
+                   expected_type == SMC_CLC_DECLINE)
+                       clc_sk->sk_err = 0; /* reset for fallback usage */
+               else
+                       smc->sk.sk_err = clc_sk->sk_err;
                goto out;
        }
        if (!len) { /* peer has performed orderly shutdown */
@@ -306,7 +310,8 @@ int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen,
                goto out;
        }
        if (len < 0) {
-               smc->sk.sk_err = -len;
+               if (len != -EAGAIN || expected_type != SMC_CLC_DECLINE)
+                       smc->sk.sk_err = -len;
                reason_code = len;
                goto out;
        }