@@ -815,7 +815,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
815
815
struct ib_uverbs_create_qp cmd ;
816
816
struct ib_uverbs_create_qp_resp resp ;
817
817
struct ib_udata udata ;
818
- struct ib_uevent_object * uobj ;
818
+ struct ib_uqp_object * uobj ;
819
819
struct ib_pd * pd ;
820
820
struct ib_cq * scq , * rcq ;
821
821
struct ib_srq * srq ;
@@ -866,10 +866,11 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
866
866
attr .cap .max_recv_sge = cmd .max_recv_sge ;
867
867
attr .cap .max_inline_data = cmd .max_inline_data ;
868
868
869
- uobj -> uobject .user_handle = cmd .user_handle ;
870
- uobj -> uobject .context = file -> ucontext ;
871
- uobj -> events_reported = 0 ;
872
- INIT_LIST_HEAD (& uobj -> event_list );
869
+ uobj -> uevent .uobject .user_handle = cmd .user_handle ;
870
+ uobj -> uevent .uobject .context = file -> ucontext ;
871
+ uobj -> uevent .events_reported = 0 ;
872
+ INIT_LIST_HEAD (& uobj -> uevent .event_list );
873
+ INIT_LIST_HEAD (& uobj -> mcast_list );
873
874
874
875
qp = pd -> device -> create_qp (pd , & attr , & udata );
875
876
if (IS_ERR (qp )) {
@@ -882,7 +883,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
882
883
qp -> send_cq = attr .send_cq ;
883
884
qp -> recv_cq = attr .recv_cq ;
884
885
qp -> srq = attr .srq ;
885
- qp -> uobject = & uobj -> uobject ;
886
+ qp -> uobject = & uobj -> uevent . uobject ;
886
887
qp -> event_handler = attr .event_handler ;
887
888
qp -> qp_context = attr .qp_context ;
888
889
qp -> qp_type = attr .qp_type ;
@@ -901,14 +902,14 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
901
902
goto err_destroy ;
902
903
}
903
904
904
- ret = idr_get_new (& ib_uverbs_qp_idr , qp , & uobj -> uobject .id );
905
+ ret = idr_get_new (& ib_uverbs_qp_idr , qp , & uobj -> uevent . uobject .id );
905
906
906
907
if (ret == - EAGAIN )
907
908
goto retry ;
908
909
if (ret )
909
910
goto err_destroy ;
910
911
911
- resp .qp_handle = uobj -> uobject .id ;
912
+ resp .qp_handle = uobj -> uevent . uobject .id ;
912
913
resp .max_recv_sge = attr .cap .max_recv_sge ;
913
914
resp .max_send_sge = attr .cap .max_send_sge ;
914
915
resp .max_recv_wr = attr .cap .max_recv_wr ;
@@ -922,15 +923,15 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
922
923
}
923
924
924
925
down (& file -> mutex );
925
- list_add_tail (& uobj -> uobject .list , & file -> ucontext -> qp_list );
926
+ list_add_tail (& uobj -> uevent . uobject .list , & file -> ucontext -> qp_list );
926
927
up (& file -> mutex );
927
928
928
929
up (& ib_uverbs_idr_mutex );
929
930
930
931
return in_len ;
931
932
932
933
err_idr :
933
- idr_remove (& ib_uverbs_qp_idr , uobj -> uobject .id );
934
+ idr_remove (& ib_uverbs_qp_idr , uobj -> uevent . uobject .id );
934
935
935
936
err_destroy :
936
937
ib_destroy_qp (qp );
@@ -1032,7 +1033,7 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file,
1032
1033
struct ib_uverbs_destroy_qp cmd ;
1033
1034
struct ib_uverbs_destroy_qp_resp resp ;
1034
1035
struct ib_qp * qp ;
1035
- struct ib_uevent_object * uobj ;
1036
+ struct ib_uqp_object * uobj ;
1036
1037
int ret = - EINVAL ;
1037
1038
1038
1039
if (copy_from_user (& cmd , buf , sizeof cmd ))
@@ -1046,7 +1047,12 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file,
1046
1047
if (!qp || qp -> uobject -> context != file -> ucontext )
1047
1048
goto out ;
1048
1049
1049
- uobj = container_of (qp -> uobject , struct ib_uevent_object , uobject );
1050
+ uobj = container_of (qp -> uobject , struct ib_uqp_object , uevent .uobject );
1051
+
1052
+ if (!list_empty (& uobj -> mcast_list )) {
1053
+ ret = - EBUSY ;
1054
+ goto out ;
1055
+ }
1050
1056
1051
1057
ret = ib_destroy_qp (qp );
1052
1058
if (ret )
@@ -1055,12 +1061,12 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file,
1055
1061
idr_remove (& ib_uverbs_qp_idr , cmd .qp_handle );
1056
1062
1057
1063
down (& file -> mutex );
1058
- list_del (& uobj -> uobject .list );
1064
+ list_del (& uobj -> uevent . uobject .list );
1059
1065
up (& file -> mutex );
1060
1066
1061
- ib_uverbs_release_uevent (file , uobj );
1067
+ ib_uverbs_release_uevent (file , & uobj -> uevent );
1062
1068
1063
- resp .events_reported = uobj -> events_reported ;
1069
+ resp .events_reported = uobj -> uevent . events_reported ;
1064
1070
1065
1071
kfree (uobj );
1066
1072
@@ -1542,6 +1548,8 @@ ssize_t ib_uverbs_attach_mcast(struct ib_uverbs_file *file,
1542
1548
{
1543
1549
struct ib_uverbs_attach_mcast cmd ;
1544
1550
struct ib_qp * qp ;
1551
+ struct ib_uqp_object * uobj ;
1552
+ struct ib_uverbs_mcast_entry * mcast ;
1545
1553
int ret = - EINVAL ;
1546
1554
1547
1555
if (copy_from_user (& cmd , buf , sizeof cmd ))
@@ -1550,9 +1558,36 @@ ssize_t ib_uverbs_attach_mcast(struct ib_uverbs_file *file,
1550
1558
down (& ib_uverbs_idr_mutex );
1551
1559
1552
1560
qp = idr_find (& ib_uverbs_qp_idr , cmd .qp_handle );
1553
- if (qp && qp -> uobject -> context == file -> ucontext )
1554
- ret = ib_attach_mcast (qp , (union ib_gid * ) cmd .gid , cmd .mlid );
1561
+ if (!qp || qp -> uobject -> context != file -> ucontext )
1562
+ goto out ;
1563
+
1564
+ uobj = container_of (qp -> uobject , struct ib_uqp_object , uevent .uobject );
1565
+
1566
+ list_for_each_entry (mcast , & uobj -> mcast_list , list )
1567
+ if (cmd .mlid == mcast -> lid &&
1568
+ !memcmp (cmd .gid , mcast -> gid .raw , sizeof mcast -> gid .raw )) {
1569
+ ret = 0 ;
1570
+ goto out ;
1571
+ }
1555
1572
1573
+ mcast = kmalloc (sizeof * mcast , GFP_KERNEL );
1574
+ if (!mcast ) {
1575
+ ret = - ENOMEM ;
1576
+ goto out ;
1577
+ }
1578
+
1579
+ mcast -> lid = cmd .mlid ;
1580
+ memcpy (mcast -> gid .raw , cmd .gid , sizeof mcast -> gid .raw );
1581
+
1582
+ ret = ib_attach_mcast (qp , & mcast -> gid , cmd .mlid );
1583
+ if (!ret ) {
1584
+ uobj = container_of (qp -> uobject , struct ib_uqp_object ,
1585
+ uevent .uobject );
1586
+ list_add_tail (& mcast -> list , & uobj -> mcast_list );
1587
+ } else
1588
+ kfree (mcast );
1589
+
1590
+ out :
1556
1591
up (& ib_uverbs_idr_mutex );
1557
1592
1558
1593
return ret ? ret : in_len ;
@@ -1563,7 +1598,9 @@ ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file,
1563
1598
int out_len )
1564
1599
{
1565
1600
struct ib_uverbs_detach_mcast cmd ;
1601
+ struct ib_uqp_object * uobj ;
1566
1602
struct ib_qp * qp ;
1603
+ struct ib_uverbs_mcast_entry * mcast ;
1567
1604
int ret = - EINVAL ;
1568
1605
1569
1606
if (copy_from_user (& cmd , buf , sizeof cmd ))
@@ -1572,9 +1609,24 @@ ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file,
1572
1609
down (& ib_uverbs_idr_mutex );
1573
1610
1574
1611
qp = idr_find (& ib_uverbs_qp_idr , cmd .qp_handle );
1575
- if (qp && qp -> uobject -> context == file -> ucontext )
1576
- ret = ib_detach_mcast (qp , (union ib_gid * ) cmd .gid , cmd .mlid );
1612
+ if (!qp || qp -> uobject -> context != file -> ucontext )
1613
+ goto out ;
1614
+
1615
+ ret = ib_detach_mcast (qp , (union ib_gid * ) cmd .gid , cmd .mlid );
1616
+ if (ret )
1617
+ goto out ;
1577
1618
1619
+ uobj = container_of (qp -> uobject , struct ib_uqp_object , uevent .uobject );
1620
+
1621
+ list_for_each_entry (mcast , & uobj -> mcast_list , list )
1622
+ if (cmd .mlid == mcast -> lid &&
1623
+ !memcmp (cmd .gid , mcast -> gid .raw , sizeof mcast -> gid .raw )) {
1624
+ list_del (& mcast -> list );
1625
+ kfree (mcast );
1626
+ break ;
1627
+ }
1628
+
1629
+ out :
1578
1630
up (& ib_uverbs_idr_mutex );
1579
1631
1580
1632
return ret ? ret : in_len ;
0 commit comments