net/smc: use queue pair number when matching link group
authorKarsten Graul <kgraul@linux.ibm.com>
Tue, 20 Nov 2018 15:46:40 +0000 (16:46 +0100)
committerDavid S. Miller <davem@davemloft.net>
Thu, 22 Nov 2018 00:14:56 +0000 (16:14 -0800)
When searching for an existing link group the queue pair number is also
to be taken into consideration. When the SMC server sends a new number
in a CLC packet (keeping all other values equal) then a new link group
is to be created on the SMC client side.

Signed-off-by: Karsten Graul <kgraul@linux.ibm.com>
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_core.c
net/smc/smc_core.h

index 84f67f6..5fbaf19 100644 (file)
@@ -549,7 +549,8 @@ static int smc_connect_rdma(struct smc_sock *smc,
 
        mutex_lock(&smc_create_lgr_pending);
        local_contact = smc_conn_create(smc, false, aclc->hdr.flag, ibdev,
-                                       ibport, &aclc->lcl, NULL, 0);
+                                       ibport, ntoh24(aclc->qpn), &aclc->lcl,
+                                       NULL, 0);
        if (local_contact < 0) {
                if (local_contact == -ENOMEM)
                        reason_code = SMC_CLC_DECL_MEM;/* insufficient memory*/
@@ -620,7 +621,7 @@ static int smc_connect_ism(struct smc_sock *smc,
        int rc = 0;
 
        mutex_lock(&smc_create_lgr_pending);
-       local_contact = smc_conn_create(smc, true, aclc->hdr.flag, NULL, 0,
+       local_contact = smc_conn_create(smc, true, aclc->hdr.flag, NULL, 0, 0,
                                        NULL, ismdev, aclc->gid);
        if (local_contact < 0)
                return smc_connect_abort(smc, SMC_CLC_DECL_MEM, 0);
@@ -1085,7 +1086,7 @@ static int smc_listen_rdma_init(struct smc_sock *new_smc,
                                int *local_contact)
 {
        /* allocate connection / link group */
-       *local_contact = smc_conn_create(new_smc, false, 0, ibdev, ibport,
+       *local_contact = smc_conn_create(new_smc, false, 0, ibdev, ibport, 0,
                                         &pclc->lcl, NULL, 0);
        if (*local_contact < 0) {
                if (*local_contact == -ENOMEM)
@@ -1109,7 +1110,7 @@ static int smc_listen_ism_init(struct smc_sock *new_smc,
        struct smc_clc_msg_smcd *pclc_smcd;
 
        pclc_smcd = smc_get_clc_msg_smcd(pclc);
-       *local_contact = smc_conn_create(new_smc, true, 0, NULL, 0, NULL,
+       *local_contact = smc_conn_create(new_smc, true, 0, NULL, 0, 0, NULL,
                                         ismdev, pclc_smcd->gid);
        if (*local_contact < 0) {
                if (*local_contact == -ENOMEM)
index 18daebc..3c023de 100644 (file)
@@ -559,7 +559,7 @@ out:
 
 static bool smcr_lgr_match(struct smc_link_group *lgr,
                           struct smc_clc_msg_local *lcl,
-                          enum smc_lgr_role role)
+                          enum smc_lgr_role role, u32 clcqpn)
 {
        return !memcmp(lgr->peer_systemid, lcl->id_for_peer,
                       SMC_SYSTEMID_LEN) &&
@@ -567,7 +567,9 @@ static bool smcr_lgr_match(struct smc_link_group *lgr,
                        SMC_GID_SIZE) &&
                !memcmp(lgr->lnk[SMC_SINGLE_LINK].peer_mac, lcl->mac,
                        sizeof(lcl->mac)) &&
-               lgr->role == role;
+               lgr->role == role &&
+               (lgr->role == SMC_SERV ||
+                lgr->lnk[SMC_SINGLE_LINK].peer_qpn == clcqpn);
 }
 
 static bool smcd_lgr_match(struct smc_link_group *lgr,
@@ -578,7 +580,7 @@ static bool smcd_lgr_match(struct smc_link_group *lgr,
 
 /* create a new SMC connection (and a new link group if necessary) */
 int smc_conn_create(struct smc_sock *smc, bool is_smcd, int srv_first_contact,
-                   struct smc_ib_device *smcibdev, u8 ibport,
+                   struct smc_ib_device *smcibdev, u8 ibport, u32 clcqpn,
                    struct smc_clc_msg_local *lcl, struct smcd_dev *smcd,
                    u64 peer_gid)
 {
@@ -603,7 +605,7 @@ int smc_conn_create(struct smc_sock *smc, bool is_smcd, int srv_first_contact,
        list_for_each_entry(lgr, &smc_lgr_list.list, list) {
                write_lock_bh(&lgr->conns_lock);
                if ((is_smcd ? smcd_lgr_match(lgr, smcd, peer_gid) :
-                    smcr_lgr_match(lgr, lcl, role)) &&
+                    smcr_lgr_match(lgr, lcl, role, clcqpn)) &&
                    !lgr->sync_err &&
                    lgr->vlan_id == vlan_id &&
                    (role == SMC_CLNT ||
index c156674..5bc6cba 100644 (file)
@@ -262,7 +262,7 @@ int smc_vlan_by_tcpsk(struct socket *clcsock, unsigned short *vlan_id);
 
 void smc_conn_free(struct smc_connection *conn);
 int smc_conn_create(struct smc_sock *smc, bool is_smcd, int srv_first_contact,
-                   struct smc_ib_device *smcibdev, u8 ibport,
+                   struct smc_ib_device *smcibdev, u8 ibport, u32 clcqpn,
                    struct smc_clc_msg_local *lcl, struct smcd_dev *smcd,
                    u64 peer_gid);
 void smcd_conn_free(struct smc_connection *conn);