Procházet zdrojové kódy

[infiniband] Parse MLID, rate, and SL from multicast membership record

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown před 8 roky
rodič
revize
14ad9cbd67
3 změnil soubory, kde provedl 74 přidání a 62 odebrání
  1. 38
    22
      src/drivers/net/ipoib.c
  2. 6
    13
      src/include/ipxe/ib_mcast.h
  3. 30
    27
      src/net/infiniband/ib_mcast.c

+ 38
- 22
src/drivers/net/ipoib.c Zobrazit soubor

@@ -73,6 +73,16 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
73 73
 /** Number of IPoIB completion entries */
74 74
 #define IPOIB_NUM_CQES 8
75 75
 
76
+/** An IPoIB broadcast address */
77
+struct ipoib_broadcast {
78
+	/** MAC address */
79
+	struct ipoib_mac mac;
80
+	/** Address vector */
81
+	struct ib_address_vector av;
82
+	/** Multicast group membership */
83
+	struct ib_mc_membership membership;
84
+};
85
+
76 86
 /** An IPoIB device */
77 87
 struct ipoib_device {
78 88
 	/** Network device */
@@ -87,10 +97,8 @@ struct ipoib_device {
87 97
 	struct ib_queue_pair *qp;
88 98
 	/** Local MAC */
89 99
 	struct ipoib_mac mac;
90
-	/** Broadcast MAC */
91
-	struct ipoib_mac broadcast;
92
-	/** IPv4 broadcast multicast group membership */
93
-	struct ib_mc_membership membership;
100
+	/** Broadcast address */
101
+	struct ipoib_broadcast broadcast;
94 102
 	/** REMAC cache */
95 103
 	struct list_head peers;
96 104
 };
@@ -149,7 +157,7 @@ static struct ipoib_mac * ipoib_find_remac ( struct ipoib_device *ipoib,
149 157
 	 * multicasts as broadcasts for simplicity.
150 158
 	 */
151 159
 	if ( is_multicast_ether_addr ( remac ) )
152
-		return &ipoib->broadcast;
160
+		return &ipoib->broadcast.mac;
153 161
 
154 162
 	/* Try to find via REMAC cache */
155 163
 	list_for_each_entry ( peer, &ipoib->peers, list ) {
@@ -559,6 +567,7 @@ static int ipoib_transmit ( struct net_device *netdev,
559 567
 	/* Construct address vector */
560 568
 	memset ( &dest, 0, sizeof ( dest ) );
561 569
 	dest.qpn = ( ntohl ( mac->flags__qpn ) & IB_QPN_MASK );
570
+	dest.qkey = ipoib->broadcast.av.qkey;
562 571
 	dest.gid_present = 1;
563 572
 	memcpy ( &dest.gid, &mac->gid, sizeof ( dest.gid ) );
564 573
 	if ( ( rc = ib_resolve_path ( ibdev, &dest ) ) != 0 ) {
@@ -650,8 +659,9 @@ static void ipoib_complete_recv ( struct ib_device *ibdev __unused,
650 659
 	ethhdr->h_protocol = net_proto;
651 660
 
652 661
 	/* Construct destination address */
653
-	if ( dest->gid_present && ( memcmp ( &dest->gid, &ipoib->broadcast.gid,
654
-					     sizeof ( dest->gid ) ) == 0 ) ) {
662
+	if ( dest->gid_present &&
663
+	     ( memcmp ( &dest->gid, &ipoib->broadcast.mac.gid,
664
+			sizeof ( dest->gid ) ) == 0 ) ) {
655 665
 		/* Broadcast GID; use the Ethernet broadcast address */
656 666
 		memcpy ( &ethhdr->h_dest, eth_broadcast,
657 667
 			 sizeof ( ethhdr->h_dest ) );
@@ -726,18 +736,13 @@ static void ipoib_poll ( struct net_device *netdev ) {
726 736
 /**
727 737
  * Handle IPv4 broadcast multicast group join completion
728 738
  *
729
- * @v ibdev		Infiniband device
730
- * @v qp		Queue pair
731 739
  * @v membership	Multicast group membership
732 740
  * @v rc		Status code
733
- * @v mad		Response MAD (or NULL on error)
734 741
  */
735
-void ipoib_join_complete ( struct ib_device *ibdev __unused,
736
-			   struct ib_queue_pair *qp __unused,
737
-			   struct ib_mc_membership *membership, int rc,
738
-			   union ib_mad *mad __unused ) {
739
-	struct ipoib_device *ipoib =
740
-		container_of ( membership, struct ipoib_device, membership );
742
+void ipoib_join_complete ( struct ib_mc_membership *membership, int rc ) {
743
+	struct ipoib_device *ipoib = container_of ( membership,
744
+						    struct ipoib_device,
745
+						    broadcast.membership );
741 746
 
742 747
 	/* Record join status as link status */
743 748
 	netdev_link_err ( ipoib->netdev, rc );
@@ -752,8 +757,10 @@ void ipoib_join_complete ( struct ib_device *ibdev __unused,
752 757
 static int ipoib_join_broadcast_group ( struct ipoib_device *ipoib ) {
753 758
 	int rc;
754 759
 
760
+	/* Join multicast group */
755 761
 	if ( ( rc = ib_mcast_join ( ipoib->ibdev, ipoib->qp,
756
-				    &ipoib->membership, &ipoib->broadcast.gid,
762
+				    &ipoib->broadcast.membership,
763
+				    &ipoib->broadcast.av,
757 764
 				    ipoib_join_complete ) ) != 0 ) {
758 765
 		DBGC ( ipoib, "IPoIB %p could not join broadcast group: %s\n",
759 766
 		       ipoib, strerror ( rc ) );
@@ -770,7 +777,9 @@ static int ipoib_join_broadcast_group ( struct ipoib_device *ipoib ) {
770 777
  */
771 778
 static void ipoib_leave_broadcast_group ( struct ipoib_device *ipoib ) {
772 779
 
773
-	ib_mcast_leave ( ipoib->ibdev, ipoib->qp, &ipoib->membership );
780
+	/* Leave multicast group */
781
+	ib_mcast_leave ( ipoib->ibdev, ipoib->qp,
782
+			 &ipoib->broadcast.membership );
774 783
 }
775 784
 
776 785
 /**
@@ -791,10 +800,17 @@ static void ipoib_link_state_changed ( struct ipoib_device *ipoib ) {
791 800
 	memcpy ( &ipoib->mac.gid.s.prefix, &ibdev->gid.s.prefix,
792 801
 		 sizeof ( ipoib->mac.gid.s.prefix ) );
793 802
 
794
-	/* Update broadcast GID based on potentially-new partition key */
795
-	ipoib->broadcast.gid.words[2] =
803
+	/* Update broadcast MAC GID based on potentially-new partition key */
804
+	ipoib->broadcast.mac.gid.words[2] =
796 805
 		htons ( ibdev->pkey | IB_PKEY_FULL );
797 806
 
807
+	/* Construct broadcast address vector from broadcast MAC address */
808
+	memset ( &ipoib->broadcast.av, 0, sizeof ( ipoib->broadcast.av ) );
809
+	ipoib->broadcast.av.qpn = IB_QPN_BROADCAST;
810
+	ipoib->broadcast.av.gid_present = 1;
811
+	memcpy ( &ipoib->broadcast.av.gid, &ipoib->broadcast.mac.gid,
812
+		 sizeof ( ipoib->broadcast.av.gid ) );
813
+
798 814
 	/* Set net device link state to reflect Infiniband link state */
799 815
 	rc = ib_link_rc ( ibdev );
800 816
 	netdev_link_err ( netdev, ( rc ? rc : -EINPROGRESS_JOINING ) );
@@ -936,8 +952,8 @@ static int ipoib_probe ( struct ib_device *ibdev ) {
936 952
 		 sizeof ( ipoib->mac.gid.s.guid ) );
937 953
 
938 954
 	/* Set default broadcast MAC address */
939
-	memcpy ( &ipoib->broadcast, &ipoib_broadcast,
940
-		 sizeof ( ipoib->broadcast ) );
955
+	memcpy ( &ipoib->broadcast.mac, &ipoib_broadcast,
956
+		 sizeof ( ipoib->broadcast.mac ) );
941 957
 
942 958
 	/* Add to list of IPoIB devices */
943 959
 	list_add_tail ( &ipoib->list, &ipoib_devices );

+ 6
- 13
src/include/ipxe/ib_mcast.h Zobrazit soubor

@@ -17,32 +17,25 @@ struct ib_mad_transaction;
17 17
 struct ib_mc_membership {
18 18
 	/** Queue pair */
19 19
 	struct ib_queue_pair *qp;
20
-	/** Multicast GID */
21
-	union ib_gid gid;
20
+	/** Address vector */
21
+	struct ib_address_vector *av;
22 22
 	/** Attached to multicast GID */
23 23
 	int attached;
24 24
 	/** Multicast group join transaction */
25 25
 	struct ib_mad_transaction *madx;
26 26
 	/** Handle join success/failure
27 27
 	 *
28
-	 * @v ibdev		Infiniband device
29
-	 * @v qp		Queue pair
30 28
 	 * @v membership	Multicast group membership
31 29
 	 * @v rc		Status code
32
-	 * @v mad		Response MAD (or NULL on error)
33 30
 	 */
34
-	void ( * complete ) ( struct ib_device *ibdev, struct ib_queue_pair *qp,
35
-			      struct ib_mc_membership *membership, int rc,
36
-			      union ib_mad *mad );
31
+	void ( * complete ) ( struct ib_mc_membership *membership, int rc );
37 32
 };
38 33
 
39 34
 extern int ib_mcast_join ( struct ib_device *ibdev, struct ib_queue_pair *qp,
40 35
 			   struct ib_mc_membership *membership,
41
-			   union ib_gid *gid,
42
-			   void ( * joined ) ( struct ib_device *ibdev,
43
-					       struct ib_queue_pair *qp,
44
-					       struct ib_mc_membership *memb,
45
-					       int rc, union ib_mad *mad ) );
36
+			   struct ib_address_vector *av,
37
+			   void ( * joined ) ( struct ib_mc_membership *memb,
38
+					       int rc ) );
46 39
 
47 40
 extern void ib_mcast_leave ( struct ib_device *ibdev, struct ib_queue_pair *qp,
48 41
 			     struct ib_mc_membership *membership );

+ 30
- 27
src/net/infiniband/ib_mcast.c Zobrazit soubor

@@ -42,11 +42,12 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
42 42
  * Generate multicast membership MAD
43 43
  *
44 44
  * @v ibdev		Infiniband device
45
- * @v gid		Multicast GID
45
+ * @v av		Address vector
46 46
  * @v join		Join (rather than leave) group
47 47
  * @v mad		MAD to fill in
48 48
  */
49
-static void ib_mcast_mad ( struct ib_device *ibdev, union ib_gid *gid,
49
+static void ib_mcast_mad ( struct ib_device *ibdev,
50
+			   struct ib_address_vector *av,
50 51
 			   int join, union ib_mad *mad ) {
51 52
 	struct ib_mad_sa *sa = &mad->sa;
52 53
 
@@ -61,7 +62,7 @@ static void ib_mcast_mad ( struct ib_device *ibdev, union ib_gid *gid,
61 62
 		htonl ( IB_SA_MCMEMBER_REC_MGID | IB_SA_MCMEMBER_REC_PORT_GID |
62 63
 			IB_SA_MCMEMBER_REC_JOIN_STATE );
63 64
 	sa->sa_data.mc_member_record.scope__join_state = 1;
64
-	memcpy ( &sa->sa_data.mc_member_record.mgid, gid,
65
+	memcpy ( &sa->sa_data.mc_member_record.mgid, &av->gid,
65 66
 		 sizeof ( sa->sa_data.mc_member_record.mgid ) );
66 67
 	memcpy ( &sa->sa_data.mc_member_record.port_gid, &ibdev->gid,
67 68
 		 sizeof ( sa->sa_data.mc_member_record.port_gid ) );
@@ -75,20 +76,19 @@ static void ib_mcast_mad ( struct ib_device *ibdev, union ib_gid *gid,
75 76
  * @v madx		Management transaction
76 77
  * @v rc		Status code
77 78
  * @v mad		Received MAD (or NULL on error)
78
- * @v av		Source address vector (or NULL on error)
79
+ * @v src		Source address vector (or NULL on error)
79 80
  */
80 81
 static void ib_mcast_complete ( struct ib_device *ibdev,
81 82
 				struct ib_mad_interface *mi __unused,
82 83
 				struct ib_mad_transaction *madx,
83 84
 				int rc, union ib_mad *mad,
84
-				struct ib_address_vector *av __unused ) {
85
+				struct ib_address_vector *src __unused ) {
85 86
 	struct ib_mc_membership *membership = ib_madx_get_ownerdata ( madx );
86 87
 	struct ib_queue_pair *qp = membership->qp;
87
-	union ib_gid *gid = &membership->gid;
88
+	struct ib_address_vector *av = membership->av;
88 89
 	struct ib_mc_member_record *mc_member_record =
89 90
 		&mad->sa.sa_data.mc_member_record;
90 91
 	int joined;
91
-	unsigned long qkey;
92 92
 
93 93
 	/* Report failures */
94 94
 	if ( ( rc == 0 ) && ( mad->hdr.status != htons ( IB_MGMT_STATUS_OK ) ))
@@ -101,13 +101,17 @@ static void ib_mcast_complete ( struct ib_device *ibdev,
101 101
 
102 102
 	/* Extract values from MAD */
103 103
 	joined = ( mad->hdr.method == IB_MGMT_METHOD_GET_RESP );
104
-	qkey = ntohl ( mc_member_record->qkey );
105
-	DBGC ( ibdev, "IBDEV %s QPN %#lx %s " IB_GID_FMT " qkey %lx\n",
104
+	av->qkey = ntohl ( mc_member_record->qkey );
105
+	av->lid = ntohs ( mc_member_record->mlid );
106
+	av->rate = ( mc_member_record->rate_selector__rate & 0x3f );
107
+	av->sl = ( ( ntohl ( mc_member_record->sl__flow_label__hop_limit )
108
+		     >> 28 ) & 0x0f );
109
+	DBGC ( ibdev, "IBDEV %s QPN %#lx %s " IB_GID_FMT " qkey %#lx\n",
106 110
 	       ibdev->name, qp->qpn, ( joined ? "joined" : "left" ),
107
-	       IB_GID_ARGS ( gid ), qkey );
111
+	       IB_GID_ARGS ( &av->gid ), av->qkey );
108 112
 
109 113
 	/* Set queue key */
110
-	qp->qkey = qkey;
114
+	qp->qkey = av->qkey;
111 115
 	if ( ( rc = ib_modify_qp ( ibdev, qp ) ) != 0 ) {
112 116
 		DBGC ( ibdev, "IBDEV %s QPN %#lx could not modify qkey: %s\n",
113 117
 		       ibdev->name, qp->qpn, strerror ( rc ) );
@@ -120,7 +124,7 @@ static void ib_mcast_complete ( struct ib_device *ibdev,
120 124
 	membership->madx = NULL;
121 125
 
122 126
 	/* Hand off to upper completion handler */
123
-	membership->complete ( ibdev, qp, membership, rc, mad );
127
+	membership->complete ( membership, rc );
124 128
 }
125 129
 
126 130
 /** Multicast membership management transaction completion operations */
@@ -134,21 +138,20 @@ static struct ib_mad_transaction_operations ib_mcast_op = {
134 138
  * @v ibdev		Infiniband device
135 139
  * @v qp		Queue pair
136 140
  * @v membership	Multicast group membership
137
- * @v gid		Multicast GID to join
141
+ * @v av		Address vector to fill in
138 142
  * @v joined		Join completion handler
139 143
  * @ret rc		Return status code
140 144
  */
141 145
 int ib_mcast_join ( struct ib_device *ibdev, struct ib_queue_pair *qp,
142
-		    struct ib_mc_membership *membership, union ib_gid *gid,
143
-		    void ( * complete ) ( struct ib_device *ibdev,
144
-					  struct ib_queue_pair *qp,
145
-					  struct ib_mc_membership *membership,
146
-					  int rc, union ib_mad *mad ) ) {
146
+		    struct ib_mc_membership *membership,
147
+		    struct ib_address_vector *av,
148
+		    void ( * complete ) ( struct ib_mc_membership *membership,
149
+					  int rc ) ) {
147 150
 	union ib_mad mad;
148 151
 	int rc;
149 152
 
150 153
 	DBGC ( ibdev, "IBDEV %s QPN %#lx joining " IB_GID_FMT "\n",
151
-	       ibdev->name, qp->qpn, IB_GID_ARGS ( gid ) );
154
+	       ibdev->name, qp->qpn, IB_GID_ARGS ( &av->gid ) );
152 155
 
153 156
 	/* Sanity checks */
154 157
 	assert ( qp != NULL );
@@ -156,11 +159,11 @@ int ib_mcast_join ( struct ib_device *ibdev, struct ib_queue_pair *qp,
156 159
 
157 160
 	/* Initialise structure */
158 161
 	membership->qp = qp;
159
-	memcpy ( &membership->gid, gid, sizeof ( membership->gid ) );
162
+	membership->av = av;
160 163
 	membership->complete = complete;
161 164
 
162 165
 	/* Attach queue pair to multicast GID */
163
-	if ( ( rc = ib_mcast_attach ( ibdev, qp, gid ) ) != 0 ) {
166
+	if ( ( rc = ib_mcast_attach ( ibdev, qp, &av->gid ) ) != 0 ) {
164 167
 		DBGC ( ibdev, "IBDEV %s QPN %#lx could not attach: %s\n",
165 168
 		       ibdev->name, qp->qpn, strerror ( rc ) );
166 169
 		goto err_mcast_attach;
@@ -168,7 +171,7 @@ int ib_mcast_join ( struct ib_device *ibdev, struct ib_queue_pair *qp,
168 171
 	membership->attached = 1;
169 172
 
170 173
 	/* Initiate multicast membership join */
171
-	ib_mcast_mad ( ibdev, gid, 1, &mad );
174
+	ib_mcast_mad ( ibdev, av, 1, &mad );
172 175
 	membership->madx = ib_create_madx ( ibdev, ibdev->gsi, &mad, NULL,
173 176
 					    &ib_mcast_op );
174 177
 	if ( ! membership->madx ) {
@@ -183,7 +186,7 @@ int ib_mcast_join ( struct ib_device *ibdev, struct ib_queue_pair *qp,
183 186
 
184 187
 	ib_destroy_madx ( ibdev, ibdev->gsi, membership->madx );
185 188
  err_create_madx:
186
-	ib_mcast_detach ( ibdev, qp, gid );
189
+	ib_mcast_detach ( ibdev, qp, &av->gid );
187 190
 	membership->attached = 0;
188 191
  err_mcast_attach:
189 192
 	return rc;
@@ -198,7 +201,7 @@ int ib_mcast_join ( struct ib_device *ibdev, struct ib_queue_pair *qp,
198 201
  */
199 202
 void ib_mcast_leave ( struct ib_device *ibdev, struct ib_queue_pair *qp,
200 203
 		      struct ib_mc_membership *membership ) {
201
-	union ib_gid *gid = &membership->gid;
204
+	struct ib_address_vector *av = membership->av;
202 205
 	union ib_mad mad;
203 206
 	int rc;
204 207
 
@@ -207,13 +210,13 @@ void ib_mcast_leave ( struct ib_device *ibdev, struct ib_queue_pair *qp,
207 210
 		return;
208 211
 
209 212
 	DBGC ( ibdev, "IBDEV %s QPN %#lx leaving " IB_GID_FMT "\n",
210
-	       ibdev->name, qp->qpn, IB_GID_ARGS ( gid ) );
213
+	       ibdev->name, qp->qpn, IB_GID_ARGS ( &av->gid ) );
211 214
 
212 215
 	/* Sanity check */
213 216
 	assert ( qp != NULL );
214 217
 
215 218
 	/* Detach from multicast GID */
216
-	ib_mcast_detach ( ibdev, qp, &membership->gid );
219
+	ib_mcast_detach ( ibdev, qp, &av->gid );
217 220
 	membership->attached = 0;
218 221
 
219 222
 	/* Cancel multicast membership join, if applicable */
@@ -223,7 +226,7 @@ void ib_mcast_leave ( struct ib_device *ibdev, struct ib_queue_pair *qp,
223 226
 	}
224 227
 
225 228
 	/* Send a single group leave MAD */
226
-	ib_mcast_mad ( ibdev, &membership->gid, 0, &mad );
229
+	ib_mcast_mad ( ibdev, av, 0, &mad );
227 230
 	if ( ( rc = ib_mi_send ( ibdev, ibdev->gsi, &mad, NULL ) ) != 0 ) {
228 231
 		DBGC ( ibdev, "IBDEV %s QPN %#lx could not send leave request: "
229 232
 		       "%s\n", ibdev->name, qp->qpn, strerror ( rc ) );

Načítá se…
Zrušit
Uložit