3131
3232#include "smc.h"
3333#include "smc_clc.h"
34+ #include "smc_core.h"
3435#include "smc_ib.h"
3536#include "smc_pnet.h"
3637
38+ static DEFINE_MUTEX (smc_create_lgr_pending ); /* serialize link group
39+ * creation
40+ */
41+
42+ struct smc_lgr_list smc_lgr_list = { /* established link groups */
43+ .lock = __SPIN_LOCK_UNLOCKED (smc_lgr_list .lock ),
44+ .list = LIST_HEAD_INIT (smc_lgr_list .list ),
45+ };
46+
3747static void smc_tcp_listen_work (struct work_struct * );
3848
3949static void smc_set_keepalive (struct sock * sk , int val )
@@ -235,11 +245,31 @@ int smc_netinfo_by_tcpsk(struct socket *clcsock,
235245 return rc ;
236246}
237247
248+ static void smc_conn_save_peer_info (struct smc_sock * smc ,
249+ struct smc_clc_msg_accept_confirm * clc )
250+ {
251+ smc -> conn .peer_conn_idx = clc -> conn_idx ;
252+ }
253+
254+ static void smc_link_save_peer_info (struct smc_link * link ,
255+ struct smc_clc_msg_accept_confirm * clc )
256+ {
257+ link -> peer_qpn = ntoh24 (clc -> qpn );
258+ memcpy (link -> peer_gid , clc -> lcl .gid , SMC_GID_SIZE );
259+ memcpy (link -> peer_mac , clc -> lcl .mac , sizeof (link -> peer_mac ));
260+ link -> peer_psn = ntoh24 (clc -> psn );
261+ link -> peer_mtu = clc -> qp_mtu ;
262+ }
263+
238264/* setup for RDMA connection of client */
239265static int smc_connect_rdma (struct smc_sock * smc )
240266{
267+ struct sockaddr_in * inaddr = (struct sockaddr_in * )smc -> addr ;
241268 struct smc_clc_msg_accept_confirm aclc ;
269+ int local_contact = SMC_FIRST_CONTACT ;
242270 struct smc_ib_device * smcibdev ;
271+ struct smc_link * link ;
272+ u8 srv_first_contact ;
243273 int reason_code = 0 ;
244274 int rc = 0 ;
245275 u8 ibport ;
@@ -278,26 +308,43 @@ static int smc_connect_rdma(struct smc_sock *smc)
278308 if (reason_code > 0 )
279309 goto decline_rdma ;
280310
281- /* tbd in follow-on patch: more steps to setup RDMA communcication,
282- * create connection, link group, link
283- */
311+ srv_first_contact = aclc .hdr .flag ;
312+ mutex_lock (& smc_create_lgr_pending );
313+ local_contact = smc_conn_create (smc , inaddr -> sin_addr .s_addr , smcibdev ,
314+ ibport , & aclc .lcl , srv_first_contact );
315+ if (local_contact < 0 ) {
316+ rc = local_contact ;
317+ if (rc == - ENOMEM )
318+ reason_code = SMC_CLC_DECL_MEM ;/* insufficient memory*/
319+ else if (rc == - ENOLINK )
320+ reason_code = SMC_CLC_DECL_SYNCERR ; /* synchr. error */
321+ goto decline_rdma_unlock ;
322+ }
323+ link = & smc -> conn .lgr -> lnk [SMC_SINGLE_LINK ];
284324
325+ smc_conn_save_peer_info (smc , & aclc );
326+ if (local_contact == SMC_FIRST_CONTACT )
327+ smc_link_save_peer_info (link , & aclc );
285328 /* tbd in follow-on patch: more steps to setup RDMA communcication,
286329 * create rmbs, map rmbs, rtoken_handling, modify_qp
287330 */
288331
289332 rc = smc_clc_send_confirm (smc );
290333 if (rc )
291- goto out_err ;
334+ goto out_err_unlock ;
292335
293336 /* tbd in follow-on patch: llc_confirm */
294337
338+ mutex_unlock (& smc_create_lgr_pending );
295339out_connected :
296340 smc_copy_sock_settings_to_clc (smc );
297341 smc -> sk .sk_state = SMC_ACTIVE ;
298342
299- return rc ;
343+ return rc ? rc : local_contact ;
300344
345+ decline_rdma_unlock :
346+ mutex_unlock (& smc_create_lgr_pending );
347+ smc_conn_free (& smc -> conn );
301348decline_rdma :
302349 /* RDMA setup failed, switch back to TCP */
303350 smc -> use_fallback = true;
@@ -308,6 +355,9 @@ static int smc_connect_rdma(struct smc_sock *smc)
308355 }
309356 goto out_connected ;
310357
358+ out_err_unlock :
359+ mutex_unlock (& smc_create_lgr_pending );
360+ smc_conn_free (& smc -> conn );
311361out_err :
312362 return rc ;
313363}
@@ -476,10 +526,12 @@ static void smc_listen_work(struct work_struct *work)
476526 struct socket * newclcsock = new_smc -> clcsock ;
477527 struct smc_sock * lsmc = new_smc -> listen_smc ;
478528 struct smc_clc_msg_accept_confirm cclc ;
529+ int local_contact = SMC_REUSE_CONTACT ;
479530 struct sock * newsmcsk = & new_smc -> sk ;
480531 struct smc_clc_msg_proposal pclc ;
481532 struct smc_ib_device * smcibdev ;
482533 struct sockaddr_in peeraddr ;
534+ struct smc_link * link ;
483535 int reason_code = 0 ;
484536 int rc = 0 , len ;
485537 __be32 subnet ;
@@ -527,15 +579,30 @@ static void smc_listen_work(struct work_struct *work)
527579 /* get address of the peer connected to the internal TCP socket */
528580 kernel_getpeername (newclcsock , (struct sockaddr * )& peeraddr , & len );
529581
530- /* tbd in follow-on patch: more steps to setup RDMA communcication,
531- * create connection, link_group, link
532- */
582+ /* allocate connection / link group */
583+ mutex_lock (& smc_create_lgr_pending );
584+ local_contact = smc_conn_create (new_smc , peeraddr .sin_addr .s_addr ,
585+ smcibdev , ibport , & pclc .lcl , 0 );
586+ if (local_contact == SMC_REUSE_CONTACT )
587+ /* lock no longer needed, free it due to following
588+ * smc_clc_wait_msg() call
589+ */
590+ mutex_unlock (& smc_create_lgr_pending );
591+ if (local_contact < 0 ) {
592+ rc = local_contact ;
593+ if (rc == - ENOMEM )
594+ reason_code = SMC_CLC_DECL_MEM ;/* insufficient memory*/
595+ else if (rc == - ENOLINK )
596+ reason_code = SMC_CLC_DECL_SYNCERR ; /* synchr. error */
597+ goto decline_rdma ;
598+ }
599+ link = & new_smc -> conn .lgr -> lnk [SMC_SINGLE_LINK ];
533600
534601 /* tbd in follow-on patch: more steps to setup RDMA communcication,
535602 * create rmbs, map rmbs
536603 */
537604
538- rc = smc_clc_send_accept (new_smc );
605+ rc = smc_clc_send_accept (new_smc , local_contact );
539606 if (rc )
540607 goto out_err ;
541608
@@ -546,6 +613,9 @@ static void smc_listen_work(struct work_struct *work)
546613 goto out_err ;
547614 if (reason_code > 0 )
548615 goto decline_rdma ;
616+ smc_conn_save_peer_info (new_smc , & cclc );
617+ if (local_contact == SMC_FIRST_CONTACT )
618+ smc_link_save_peer_info (link , & cclc );
549619
550620 /* tbd in follow-on patch: more steps to setup RDMA communcication,
551621 * rtoken_handling, modify_qp
@@ -555,6 +625,8 @@ static void smc_listen_work(struct work_struct *work)
555625 sk_refcnt_debug_inc (newsmcsk );
556626 newsmcsk -> sk_state = SMC_ACTIVE ;
557627enqueue :
628+ if (local_contact == SMC_FIRST_CONTACT )
629+ mutex_unlock (& smc_create_lgr_pending );
558630 lock_sock (& lsmc -> sk );
559631 if (lsmc -> sk .sk_state == SMC_LISTEN ) {
560632 smc_accept_enqueue (& lsmc -> sk , newsmcsk );
@@ -570,6 +642,7 @@ static void smc_listen_work(struct work_struct *work)
570642
571643decline_rdma :
572644 /* RDMA setup failed, switch back to TCP */
645+ smc_conn_free (& new_smc -> conn );
573646 new_smc -> use_fallback = true;
574647 if (reason_code && (reason_code != SMC_CLC_DECL_REPLY )) {
575648 rc = smc_clc_send_decline (new_smc , reason_code , 0 );
@@ -1024,6 +1097,17 @@ static int __init smc_init(void)
10241097
10251098static void __exit smc_exit (void )
10261099{
1100+ struct smc_link_group * lgr , * lg ;
1101+ LIST_HEAD (lgr_freeing_list );
1102+
1103+ spin_lock_bh (& smc_lgr_list .lock );
1104+ if (!list_empty (& smc_lgr_list .list ))
1105+ list_splice_init (& smc_lgr_list .list , & lgr_freeing_list );
1106+ spin_unlock_bh (& smc_lgr_list .lock );
1107+ list_for_each_entry_safe (lgr , lg , & lgr_freeing_list , list ) {
1108+ list_del_init (& lgr -> list );
1109+ smc_lgr_free (lgr ); /* free link group */
1110+ }
10271111 smc_ib_unregister_client ();
10281112 sock_unregister (PF_SMC );
10291113 proto_unregister (& smc_proto );
0 commit comments