#include "smc_rx.h"
 #include "smc_close.h"
 
-static DEFINE_MUTEX(smc_create_lgr_pending);   /* serialize link group
-                                                * creation
+static DEFINE_MUTEX(smc_server_lgr_pending);   /* serialize link group
+                                                * creation on server
+                                                */
+static DEFINE_MUTEX(smc_client_lgr_pending);   /* serialize link group
+                                                * creation on client
                                                 */
 
 static void smc_tcp_listen_work(struct work_struct *);
 {
        if (local_contact == SMC_FIRST_CONTACT)
                smc_lgr_forget(smc->conn.lgr);
-       mutex_unlock(&smc_create_lgr_pending);
+       if (smc->conn.lgr->is_smcd)
+               /* there is only one lgr role for SMC-D; use server lock */
+               mutex_unlock(&smc_server_lgr_pending);
+       else
+               mutex_unlock(&smc_client_lgr_pending);
+
        smc_conn_free(&smc->conn);
        return reason_code;
 }
        struct smc_link *link;
        int reason_code = 0;
 
-       mutex_lock(&smc_create_lgr_pending);
+       mutex_lock(&smc_client_lgr_pending);
        local_contact = smc_conn_create(smc, false, aclc->hdr.flag, ibdev,
                                        ibport, ntoh24(aclc->qpn), &aclc->lcl,
                                        NULL, 0);
                        reason_code = SMC_CLC_DECL_SYNCERR; /* synchr. error */
                else
                        reason_code = SMC_CLC_DECL_INTERR; /* other error */
-               return smc_connect_abort(smc, reason_code, 0);
+               mutex_unlock(&smc_client_lgr_pending);
+               return reason_code;
        }
        link = &smc->conn.lgr->lnk[SMC_SINGLE_LINK];
 
                        return smc_connect_abort(smc, reason_code,
                                                 local_contact);
        }
-       mutex_unlock(&smc_create_lgr_pending);
+       mutex_unlock(&smc_client_lgr_pending);
 
        smc_copy_sock_settings_to_clc(smc);
        if (smc->sk.sk_state == SMC_INIT)
        int local_contact = SMC_FIRST_CONTACT;
        int rc = 0;
 
-       mutex_lock(&smc_create_lgr_pending);
+       /* there is only one lgr role for SMC-D; use server lock */
+       mutex_lock(&smc_server_lgr_pending);
        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);
+       if (local_contact < 0) {
+               mutex_unlock(&smc_server_lgr_pending);
+               return SMC_CLC_DECL_MEM;
+       }
 
        /* Create send and receive buffers */
        if (smc_buf_create(smc, true))
        rc = smc_clc_send_confirm(smc);
        if (rc)
                return smc_connect_abort(smc, rc, local_contact);
-       mutex_unlock(&smc_create_lgr_pending);
+       mutex_unlock(&smc_server_lgr_pending);
 
        smc_copy_sock_settings_to_clc(smc);
        if (smc->sk.sk_state == SMC_INIT)
                return;
        }
 
-       mutex_lock(&smc_create_lgr_pending);
+       mutex_lock(&smc_server_lgr_pending);
        smc_close_init(new_smc);
        smc_rx_init(new_smc);
        smc_tx_init(new_smc);
                                  &local_contact) ||
             smc_listen_rdma_reg(new_smc, local_contact))) {
                /* SMC not supported, decline */
-               mutex_unlock(&smc_create_lgr_pending);
+               mutex_unlock(&smc_server_lgr_pending);
                smc_listen_decline(new_smc, SMC_CLC_DECL_MODEUNSUPP,
                                   local_contact);
                return;
        /* send SMC Accept CLC message */
        rc = smc_clc_send_accept(new_smc, local_contact);
        if (rc) {
-               mutex_unlock(&smc_create_lgr_pending);
+               mutex_unlock(&smc_server_lgr_pending);
                smc_listen_decline(new_smc, rc, local_contact);
                return;
        }
 
        /* SMC-D does not need this lock any more */
        if (ism_supported)
-               mutex_unlock(&smc_create_lgr_pending);
+               mutex_unlock(&smc_server_lgr_pending);
 
        /* receive SMC Confirm CLC message */
        reason_code = smc_clc_wait_msg(new_smc, &cclc, sizeof(cclc),
                                       SMC_CLC_CONFIRM, CLC_WAIT_TIME);
        if (reason_code) {
                if (!ism_supported)
-                       mutex_unlock(&smc_create_lgr_pending);
+                       mutex_unlock(&smc_server_lgr_pending);
                smc_listen_decline(new_smc, reason_code, local_contact);
                return;
        }
        /* finish worker */
        if (!ism_supported) {
                rc = smc_listen_rdma_finish(new_smc, &cclc, local_contact);
-               mutex_unlock(&smc_create_lgr_pending);
+               mutex_unlock(&smc_server_lgr_pending);
                if (rc)
                        return;
        }