@@ -84,6 +84,7 @@ static void rpcrdma_rep_destroy(struct rpcrdma_rep *rep);
84
84
static void rpcrdma_reps_unmap (struct rpcrdma_xprt * r_xprt );
85
85
static void rpcrdma_mrs_create (struct rpcrdma_xprt * r_xprt );
86
86
static void rpcrdma_mrs_destroy (struct rpcrdma_xprt * r_xprt );
87
+ static void rpcrdma_ep_destroy (struct rpcrdma_xprt * r_xprt );
87
88
static struct rpcrdma_regbuf *
88
89
rpcrdma_regbuf_alloc (size_t size , enum dma_data_direction direction ,
89
90
gfp_t flags );
@@ -391,32 +392,17 @@ rpcrdma_ia_remove(struct rpcrdma_ia *ia)
391
392
{
392
393
struct rpcrdma_xprt * r_xprt = container_of (ia , struct rpcrdma_xprt ,
393
394
rx_ia );
394
- struct rpcrdma_ep * ep = & r_xprt -> rx_ep ;
395
395
396
- /* This is similar to rpcrdma_ep_destroy, but:
397
- * - Don't cancel the connect worker.
398
- * - Don't call rpcrdma_ep_disconnect, which waits
399
- * for another conn upcall, which will deadlock.
400
- * - rdma_disconnect is unneeded, the underlying
401
- * connection is already gone.
402
- */
403
- if (ia -> ri_id -> qp ) {
396
+ if (ia -> ri_id -> qp )
404
397
rpcrdma_xprt_drain (r_xprt );
405
- rdma_destroy_qp (ia -> ri_id );
406
- ia -> ri_id -> qp = NULL ;
407
- }
408
- ib_free_cq (ep -> rep_attr .recv_cq );
409
- ep -> rep_attr .recv_cq = NULL ;
410
- ib_free_cq (ep -> rep_attr .send_cq );
411
- ep -> rep_attr .send_cq = NULL ;
412
398
413
- /* The ULP is responsible for ensuring all DMA
414
- * mappings and MRs are gone.
415
- */
416
399
rpcrdma_reps_unmap (r_xprt );
417
400
rpcrdma_reqs_reset (r_xprt );
418
401
rpcrdma_mrs_destroy (r_xprt );
419
402
rpcrdma_sendctxs_destroy (r_xprt );
403
+
404
+ rpcrdma_ep_destroy (r_xprt );
405
+
420
406
ib_dealloc_pd (ia -> ri_pd );
421
407
ia -> ri_pd = NULL ;
422
408
@@ -434,11 +420,8 @@ rpcrdma_ia_remove(struct rpcrdma_ia *ia)
434
420
void
435
421
rpcrdma_ia_close (struct rpcrdma_ia * ia )
436
422
{
437
- if (ia -> ri_id != NULL && !IS_ERR (ia -> ri_id )) {
438
- if (ia -> ri_id -> qp )
439
- rdma_destroy_qp (ia -> ri_id );
423
+ if (ia -> ri_id && !IS_ERR (ia -> ri_id ))
440
424
rdma_destroy_id (ia -> ri_id );
441
- }
442
425
ia -> ri_id = NULL ;
443
426
444
427
/* If the pd is still busy, xprtrdma missed freeing a resource */
@@ -447,25 +430,19 @@ rpcrdma_ia_close(struct rpcrdma_ia *ia)
447
430
ia -> ri_pd = NULL ;
448
431
}
449
432
450
- /**
451
- * rpcrdma_ep_create - Create unconnected endpoint
452
- * @r_xprt: transport to instantiate
453
- *
454
- * Returns zero on success, or a negative errno.
455
- */
456
- int rpcrdma_ep_create (struct rpcrdma_xprt * r_xprt )
433
+ static int rpcrdma_ep_create (struct rpcrdma_xprt * r_xprt ,
434
+ struct rdma_cm_id * id )
457
435
{
458
436
struct rpcrdma_ep * ep = & r_xprt -> rx_ep ;
459
437
struct rpcrdma_ia * ia = & r_xprt -> rx_ia ;
460
438
struct rpcrdma_connect_private * pmsg = & ep -> rep_cm_private ;
461
- struct ib_cq * sendcq , * recvcq ;
462
439
int rc ;
463
440
464
441
ep -> rep_max_requests = r_xprt -> rx_xprt .max_reqs ;
465
442
ep -> rep_inline_send = xprt_rdma_max_inline_write ;
466
443
ep -> rep_inline_recv = xprt_rdma_max_inline_read ;
467
444
468
- rc = frwr_query_device (r_xprt , ia -> ri_id -> device );
445
+ rc = frwr_query_device (r_xprt , id -> device );
469
446
if (rc )
470
447
return rc ;
471
448
r_xprt -> rx_buf .rb_max_requests = cpu_to_be32 (ep -> rep_max_requests );
@@ -491,25 +468,22 @@ int rpcrdma_ep_create(struct rpcrdma_xprt *r_xprt)
491
468
init_waitqueue_head (& ep -> rep_connect_wait );
492
469
ep -> rep_receive_count = 0 ;
493
470
494
- sendcq = ib_alloc_cq_any (ia -> ri_id -> device , r_xprt ,
495
- ep -> rep_attr .cap .max_send_wr + 1 ,
496
- IB_POLL_WORKQUEUE );
497
- if (IS_ERR (sendcq )) {
498
- rc = PTR_ERR (sendcq );
499
- goto out1 ;
471
+ ep -> rep_attr . send_cq = ib_alloc_cq_any (id -> device , r_xprt ,
472
+ ep -> rep_attr .cap .max_send_wr ,
473
+ IB_POLL_WORKQUEUE );
474
+ if (IS_ERR (ep -> rep_attr . send_cq )) {
475
+ rc = PTR_ERR (ep -> rep_attr . send_cq );
476
+ goto out_destroy ;
500
477
}
501
478
502
- recvcq = ib_alloc_cq_any (ia -> ri_id -> device , NULL ,
503
- ep -> rep_attr .cap .max_recv_wr + 1 ,
504
- IB_POLL_WORKQUEUE );
505
- if (IS_ERR (recvcq )) {
506
- rc = PTR_ERR (recvcq );
507
- goto out2 ;
479
+ ep -> rep_attr . recv_cq = ib_alloc_cq_any (id -> device , NULL ,
480
+ ep -> rep_attr .cap .max_recv_wr ,
481
+ IB_POLL_WORKQUEUE );
482
+ if (IS_ERR (ep -> rep_attr . recv_cq )) {
483
+ rc = PTR_ERR (ep -> rep_attr . recv_cq );
484
+ goto out_destroy ;
508
485
}
509
486
510
- ep -> rep_attr .send_cq = sendcq ;
511
- ep -> rep_attr .recv_cq = recvcq ;
512
-
513
487
/* Initialize cma parameters */
514
488
memset (& ep -> rep_remote_cma , 0 , sizeof (ep -> rep_remote_cma ));
515
489
@@ -525,7 +499,7 @@ int rpcrdma_ep_create(struct rpcrdma_xprt *r_xprt)
525
499
/* Client offers RDMA Read but does not initiate */
526
500
ep -> rep_remote_cma .initiator_depth = 0 ;
527
501
ep -> rep_remote_cma .responder_resources =
528
- min_t (int , U8_MAX , ia -> ri_id -> device -> attrs .max_qp_rd_atom );
502
+ min_t (int , U8_MAX , id -> device -> attrs .max_qp_rd_atom );
529
503
530
504
/* Limit transport retries so client can detect server
531
505
* GID changes quickly. RPC layer handles re-establishing
@@ -540,45 +514,41 @@ int rpcrdma_ep_create(struct rpcrdma_xprt *r_xprt)
540
514
ep -> rep_remote_cma .flow_control = 0 ;
541
515
ep -> rep_remote_cma .rnr_retry_count = 0 ;
542
516
517
+ rc = rdma_create_qp (id , ia -> ri_pd , & ep -> rep_attr );
518
+ if (rc )
519
+ goto out_destroy ;
543
520
return 0 ;
544
521
545
- out2 :
546
- ib_free_cq (sendcq );
547
- out1 :
522
+ out_destroy :
523
+ rpcrdma_ep_destroy (r_xprt );
548
524
return rc ;
549
525
}
550
526
551
- /**
552
- * rpcrdma_ep_destroy - Disconnect and destroy endpoint.
553
- * @r_xprt: transport instance to shut down
554
- *
555
- */
556
- void rpcrdma_ep_destroy (struct rpcrdma_xprt * r_xprt )
527
+ static void rpcrdma_ep_destroy (struct rpcrdma_xprt * r_xprt )
557
528
{
558
529
struct rpcrdma_ep * ep = & r_xprt -> rx_ep ;
559
530
struct rpcrdma_ia * ia = & r_xprt -> rx_ia ;
560
531
561
532
if (ia -> ri_id && ia -> ri_id -> qp ) {
562
- rpcrdma_ep_disconnect (ep , ia );
563
533
rdma_destroy_qp (ia -> ri_id );
564
534
ia -> ri_id -> qp = NULL ;
565
535
}
566
536
567
537
if (ep -> rep_attr .recv_cq )
568
538
ib_free_cq (ep -> rep_attr .recv_cq );
539
+ ep -> rep_attr .recv_cq = NULL ;
569
540
if (ep -> rep_attr .send_cq )
570
541
ib_free_cq (ep -> rep_attr .send_cq );
542
+ ep -> rep_attr .send_cq = NULL ;
571
543
}
572
544
573
545
/* Re-establish a connection after a device removal event.
574
546
* Unlike a normal reconnection, a fresh PD and a new set
575
547
* of MRs and buffers is needed.
576
548
*/
577
- static int rpcrdma_ep_recreate_xprt (struct rpcrdma_xprt * r_xprt ,
578
- struct ib_qp_init_attr * qp_init_attr )
549
+ static int rpcrdma_ep_recreate_xprt (struct rpcrdma_xprt * r_xprt )
579
550
{
580
551
struct rpcrdma_ia * ia = & r_xprt -> rx_ia ;
581
- struct rpcrdma_ep * ep = & r_xprt -> rx_ep ;
582
552
int rc , err ;
583
553
584
554
trace_xprtrdma_reinsert (r_xprt );
@@ -587,39 +557,24 @@ static int rpcrdma_ep_recreate_xprt(struct rpcrdma_xprt *r_xprt,
587
557
if (rpcrdma_ia_open (r_xprt ))
588
558
goto out1 ;
589
559
590
- rc = - ENOMEM ;
591
- err = rpcrdma_ep_create (r_xprt );
592
- if (err ) {
593
- pr_err ("rpcrdma: rpcrdma_ep_create returned %d\n" , err );
594
- goto out2 ;
595
- }
596
- memcpy (qp_init_attr , & ep -> rep_attr , sizeof (* qp_init_attr ));
597
-
598
560
rc = - ENETUNREACH ;
599
- err = rdma_create_qp (ia -> ri_id , ia -> ri_pd , qp_init_attr );
600
- if (err ) {
601
- pr_err ("rpcrdma: rdma_create_qp returned %d\n" , err );
602
- goto out3 ;
603
- }
561
+ err = rpcrdma_ep_create (r_xprt , ia -> ri_id );
562
+ if (err )
563
+ goto out2 ;
604
564
return 0 ;
605
565
606
- out3 :
607
- rpcrdma_ep_destroy (r_xprt );
608
566
out2 :
609
567
rpcrdma_ia_close (ia );
610
568
out1 :
611
569
return rc ;
612
570
}
613
571
614
- static int rpcrdma_ep_reconnect (struct rpcrdma_xprt * r_xprt ,
615
- struct ib_qp_init_attr * qp_init_attr )
572
+ static int rpcrdma_ep_reconnect (struct rpcrdma_xprt * r_xprt )
616
573
{
617
574
struct rpcrdma_ia * ia = & r_xprt -> rx_ia ;
618
575
struct rdma_cm_id * id , * old ;
619
576
int err , rc ;
620
577
621
- rpcrdma_ep_disconnect (& r_xprt -> rx_ep , ia );
622
-
623
578
rc = - EHOSTUNREACH ;
624
579
id = rpcrdma_create_id (r_xprt , ia );
625
580
if (IS_ERR (id ))
@@ -640,15 +595,14 @@ static int rpcrdma_ep_reconnect(struct rpcrdma_xprt *r_xprt,
640
595
goto out_destroy ;
641
596
}
642
597
643
- err = rdma_create_qp ( id , ia -> ri_pd , qp_init_attr );
598
+ err = rpcrdma_ep_create ( r_xprt , id );
644
599
if (err )
645
600
goto out_destroy ;
646
601
647
- /* Atomically replace the transport's ID and QP . */
602
+ /* Atomically replace the transport's ID. */
648
603
rc = 0 ;
649
604
old = ia -> ri_id ;
650
605
ia -> ri_id = id ;
651
- rdma_destroy_qp (old );
652
606
653
607
out_destroy :
654
608
rdma_destroy_id (old );
@@ -665,26 +619,25 @@ rpcrdma_ep_connect(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
665
619
struct rpcrdma_xprt * r_xprt = container_of (ia , struct rpcrdma_xprt ,
666
620
rx_ia );
667
621
struct rpc_xprt * xprt = & r_xprt -> rx_xprt ;
668
- struct ib_qp_init_attr qp_init_attr ;
669
622
int rc ;
670
623
671
624
retry :
672
- memcpy (& qp_init_attr , & ep -> rep_attr , sizeof (qp_init_attr ));
673
625
switch (ep -> rep_connected ) {
674
626
case 0 :
675
- rc = rdma_create_qp (ia -> ri_id , ia -> ri_pd , & qp_init_attr );
676
- if (rc ) {
677
- rc = - ENETUNREACH ;
627
+ rc = - ENETUNREACH ;
628
+ if (rpcrdma_ep_create (r_xprt , ia -> ri_id ))
678
629
goto out_noupdate ;
679
- }
680
630
break ;
681
631
case - ENODEV :
682
- rc = rpcrdma_ep_recreate_xprt (r_xprt , & qp_init_attr );
632
+ rc = rpcrdma_ep_recreate_xprt (r_xprt );
683
633
if (rc )
684
634
goto out_noupdate ;
685
635
break ;
636
+ case 1 :
637
+ rpcrdma_ep_disconnect (ep , ia );
638
+ /* fall through */
686
639
default :
687
- rc = rpcrdma_ep_reconnect (r_xprt , & qp_init_attr );
640
+ rc = rpcrdma_ep_reconnect (r_xprt );
688
641
if (rc )
689
642
goto out ;
690
643
}
@@ -742,21 +695,29 @@ rpcrdma_ep_disconnect(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
742
695
{
743
696
struct rpcrdma_xprt * r_xprt = container_of (ep , struct rpcrdma_xprt ,
744
697
rx_ep );
698
+ struct rdma_cm_id * id = ia -> ri_id ;
745
699
int rc ;
746
700
701
+ if (!id )
702
+ goto out ;
703
+
747
704
/* returns without wait if ID is not connected */
748
- rc = rdma_disconnect (ia -> ri_id );
705
+ rc = rdma_disconnect (id );
749
706
if (!rc )
750
707
wait_event_interruptible (ep -> rep_connect_wait ,
751
708
ep -> rep_connected != 1 );
752
709
else
753
710
ep -> rep_connected = rc ;
754
711
trace_xprtrdma_disconnect (r_xprt , rc );
755
712
756
- rpcrdma_xprt_drain (r_xprt );
713
+ if (id -> qp )
714
+ rpcrdma_xprt_drain (r_xprt );
715
+ out :
757
716
rpcrdma_reqs_reset (r_xprt );
758
717
rpcrdma_mrs_destroy (r_xprt );
759
718
rpcrdma_sendctxs_destroy (r_xprt );
719
+
720
+ rpcrdma_ep_destroy (r_xprt );
760
721
}
761
722
762
723
/* Fixed-size circular FIFO queue. This implementation is wait-free and
0 commit comments