31
31
32
32
#include "smc.h"
33
33
#include "smc_clc.h"
34
+ #include "smc_core.h"
34
35
#include "smc_ib.h"
35
36
#include "smc_pnet.h"
36
37
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
+
37
47
static void smc_tcp_listen_work (struct work_struct * );
38
48
39
49
static void smc_set_keepalive (struct sock * sk , int val )
@@ -235,11 +245,31 @@ int smc_netinfo_by_tcpsk(struct socket *clcsock,
235
245
return rc ;
236
246
}
237
247
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
+
238
264
/* setup for RDMA connection of client */
239
265
static int smc_connect_rdma (struct smc_sock * smc )
240
266
{
267
+ struct sockaddr_in * inaddr = (struct sockaddr_in * )smc -> addr ;
241
268
struct smc_clc_msg_accept_confirm aclc ;
269
+ int local_contact = SMC_FIRST_CONTACT ;
242
270
struct smc_ib_device * smcibdev ;
271
+ struct smc_link * link ;
272
+ u8 srv_first_contact ;
243
273
int reason_code = 0 ;
244
274
int rc = 0 ;
245
275
u8 ibport ;
@@ -278,26 +308,43 @@ static int smc_connect_rdma(struct smc_sock *smc)
278
308
if (reason_code > 0 )
279
309
goto decline_rdma ;
280
310
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 ];
284
324
325
+ smc_conn_save_peer_info (smc , & aclc );
326
+ if (local_contact == SMC_FIRST_CONTACT )
327
+ smc_link_save_peer_info (link , & aclc );
285
328
/* tbd in follow-on patch: more steps to setup RDMA communcication,
286
329
* create rmbs, map rmbs, rtoken_handling, modify_qp
287
330
*/
288
331
289
332
rc = smc_clc_send_confirm (smc );
290
333
if (rc )
291
- goto out_err ;
334
+ goto out_err_unlock ;
292
335
293
336
/* tbd in follow-on patch: llc_confirm */
294
337
338
+ mutex_unlock (& smc_create_lgr_pending );
295
339
out_connected :
296
340
smc_copy_sock_settings_to_clc (smc );
297
341
smc -> sk .sk_state = SMC_ACTIVE ;
298
342
299
- return rc ;
343
+ return rc ? rc : local_contact ;
300
344
345
+ decline_rdma_unlock :
346
+ mutex_unlock (& smc_create_lgr_pending );
347
+ smc_conn_free (& smc -> conn );
301
348
decline_rdma :
302
349
/* RDMA setup failed, switch back to TCP */
303
350
smc -> use_fallback = true;
@@ -308,6 +355,9 @@ static int smc_connect_rdma(struct smc_sock *smc)
308
355
}
309
356
goto out_connected ;
310
357
358
+ out_err_unlock :
359
+ mutex_unlock (& smc_create_lgr_pending );
360
+ smc_conn_free (& smc -> conn );
311
361
out_err :
312
362
return rc ;
313
363
}
@@ -476,10 +526,12 @@ static void smc_listen_work(struct work_struct *work)
476
526
struct socket * newclcsock = new_smc -> clcsock ;
477
527
struct smc_sock * lsmc = new_smc -> listen_smc ;
478
528
struct smc_clc_msg_accept_confirm cclc ;
529
+ int local_contact = SMC_REUSE_CONTACT ;
479
530
struct sock * newsmcsk = & new_smc -> sk ;
480
531
struct smc_clc_msg_proposal pclc ;
481
532
struct smc_ib_device * smcibdev ;
482
533
struct sockaddr_in peeraddr ;
534
+ struct smc_link * link ;
483
535
int reason_code = 0 ;
484
536
int rc = 0 , len ;
485
537
__be32 subnet ;
@@ -527,15 +579,30 @@ static void smc_listen_work(struct work_struct *work)
527
579
/* get address of the peer connected to the internal TCP socket */
528
580
kernel_getpeername (newclcsock , (struct sockaddr * )& peeraddr , & len );
529
581
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 ];
533
600
534
601
/* tbd in follow-on patch: more steps to setup RDMA communcication,
535
602
* create rmbs, map rmbs
536
603
*/
537
604
538
- rc = smc_clc_send_accept (new_smc );
605
+ rc = smc_clc_send_accept (new_smc , local_contact );
539
606
if (rc )
540
607
goto out_err ;
541
608
@@ -546,6 +613,9 @@ static void smc_listen_work(struct work_struct *work)
546
613
goto out_err ;
547
614
if (reason_code > 0 )
548
615
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 );
549
619
550
620
/* tbd in follow-on patch: more steps to setup RDMA communcication,
551
621
* rtoken_handling, modify_qp
@@ -555,6 +625,8 @@ static void smc_listen_work(struct work_struct *work)
555
625
sk_refcnt_debug_inc (newsmcsk );
556
626
newsmcsk -> sk_state = SMC_ACTIVE ;
557
627
enqueue :
628
+ if (local_contact == SMC_FIRST_CONTACT )
629
+ mutex_unlock (& smc_create_lgr_pending );
558
630
lock_sock (& lsmc -> sk );
559
631
if (lsmc -> sk .sk_state == SMC_LISTEN ) {
560
632
smc_accept_enqueue (& lsmc -> sk , newsmcsk );
@@ -570,6 +642,7 @@ static void smc_listen_work(struct work_struct *work)
570
642
571
643
decline_rdma :
572
644
/* RDMA setup failed, switch back to TCP */
645
+ smc_conn_free (& new_smc -> conn );
573
646
new_smc -> use_fallback = true;
574
647
if (reason_code && (reason_code != SMC_CLC_DECL_REPLY )) {
575
648
rc = smc_clc_send_decline (new_smc , reason_code , 0 );
@@ -1024,6 +1097,17 @@ static int __init smc_init(void)
1024
1097
1025
1098
static void __exit smc_exit (void )
1026
1099
{
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
+ }
1027
1111
smc_ib_unregister_client ();
1028
1112
sock_unregister (PF_SMC );
1029
1113
proto_unregister (& smc_proto );
0 commit comments