@@ -48,6 +48,7 @@
#define SMC_CLC_DECL_RELEASEERR 0x03030009 /* release version negotiate failed */
#define SMC_CLC_DECL_MAXCONNERR 0x0303000a /* max connections negotiate failed */
#define SMC_CLC_DECL_MAXLINKERR 0x0303000b /* max links negotiate failed */
+#define SMC_CLC_DECL_REQLGR 0x0303000c /* required create link grou */
#define SMC_CLC_DECL_MODEUNSUPP 0x03040000 /* smc modes do not match (R or D)*/
#define SMC_CLC_DECL_RMBE_EC 0x03050000 /* peer has eyecatcher in RMBE */
#define SMC_CLC_DECL_OPTUNSUPP 0x03060000 /* fastopen sockopt not supported */
@@ -1863,8 +1863,7 @@ static bool smcd_lgr_match(struct smc_link_group *lgr,
return lgr->peer_gid == peer_gid && lgr->smcd == smcismdev;
}
-/* create a new SMC connection (and a new link group if necessary) */
-int smc_conn_create(struct smc_sock *smc, struct smc_init_info *ini)
+static int __smc_conn_create(struct smc_sock *smc, struct smc_init_info *ini, bool create_lgr)
{
struct smc_connection *conn = &smc->conn;
struct net *net = sock_net(&smc->sk);
@@ -1927,6 +1926,8 @@ int smc_conn_create(struct smc_sock *smc, struct smc_init_info *ini)
create:
if (ini->first_contact_local) {
+ if (!create_lgr)
+ return SMC_CLC_DECL_REQLGR;
rc = smc_lgr_create(smc, ini);
if (rc)
goto out;
@@ -1962,6 +1963,29 @@ int smc_conn_create(struct smc_sock *smc, struct smc_init_info *ini)
return rc;
}
+/* create a new SMC connection (and a new link group if necessary) */
+int smc_conn_create(struct smc_sock *smc, struct smc_init_info *ini)
+{
+ int rc;
+
+ /* make no impact on SMCD */
+ if (ini->is_smcd)
+ goto locked;
+
+ /* try create conn without create lgr first */
+ rc = __smc_conn_create(smc, ini, /* disallow create lgr */ false);
+ if (!rc) {
+ /* not rely on new lgr, unlock lgr pending lock in advance. */
+ smc_lgr_pending_unlock(ini, ini->mutex);
+ return 0;
+ } else if (rc != SMC_CLC_DECL_REQLGR) {
+ /* that's unexcepted error */
+ return rc;
+ }
+locked:
+ return __smc_conn_create(smc, ini, /* create lgr if needed */ true);
+}
+
#define SMCD_DMBE_SIZES 6 /* 0 -> 16KB, 1 -> 32KB, .. 6 -> 1MB */
#define SMCR_RMBE_SIZES 5 /* 0 -> 16KB, 1 -> 32KB, .. 5 -> 512KB */