Просмотр исходного кода

Unicasts seem to be working. :)

tags/v0.9.3
Michael Brown 16 лет назад
Родитель
Сommit
ab191e45db
3 измененных файлов: 129 добавлений и 42 удалений
  1. 111
    30
      src/drivers/net/ipoib.c
  2. 7
    7
      src/drivers/net/mlx_ipoib/mt25218.c
  3. 11
    5
      src/include/gpxe/infiniband.h

+ 111
- 30
src/drivers/net/ipoib.c Просмотреть файл

@@ -86,6 +86,32 @@ struct ipoib_device {
86 86
 	struct ipoib_queue_set meta;
87 87
 };
88 88
 
89
+/**
90
+ * IPoIB path cache entry
91
+ *
92
+ * This serves a similar role to the ARP cache for Ethernet.  (ARP
93
+ * *is* used on IPoIB; we have two caches to maintain.)
94
+ */
95
+struct ipoib_cached_path {
96
+	/** Destination GID */
97
+	struct ib_gid gid;
98
+	/** Destination LID */
99
+	unsigned int dlid;
100
+	/** Service level */
101
+	unsigned int sl;
102
+	/** Rate */
103
+	unsigned int rate;
104
+};
105
+
106
+/** Number of IPoIB path cache entries */
107
+#define IPOIB_NUM_CACHED_PATHS 2
108
+
109
+/** IPoIB path cache */
110
+static struct ipoib_cached_path ipoib_path_cache[IPOIB_NUM_CACHED_PATHS];
111
+
112
+/** Oldest IPoIB path cache entry index */
113
+static unsigned int ipoib_path_cache_idx = 0;
114
+
89 115
 /****************************************************************************
90 116
  *
91 117
  * IPoIB link layer
@@ -165,15 +191,15 @@ static int ipoib_rx ( struct io_buffer *iobuf, struct net_device *netdev ) {
165 191
  * @ret string	Link-layer address in human-readable format
166 192
  */
167 193
 const char * ipoib_ntoa ( const void *ll_addr ) {
168
-	static char buf[61];
169
-	const uint8_t *ipoib_addr = ll_addr;
170
-	unsigned int i;
171
-	char *p = buf;
172
-
173
-	for ( i = 0 ; i < IPOIB_ALEN ; i++ ) {
174
-		p += sprintf ( p, ":%02x", ipoib_addr[i] );
175
-	}
176
-	return ( buf + 1 );
194
+	static char buf[45];
195
+	const struct ipoib_mac *mac = ll_addr;
196
+
197
+	snprintf ( buf, sizeof ( buf ), "%08lx:%08lx:%08lx:%08lx:%08lx",
198
+		   htonl ( mac->qpn ), htonl ( mac->gid.u.dwords[0] ),
199
+		   htonl ( mac->gid.u.dwords[1] ),
200
+		   htonl ( mac->gid.u.dwords[2] ),
201
+		   htonl ( mac->gid.u.dwords[3] ) );
202
+	return buf;
177 203
 }
178 204
 
179 205
 /** IPoIB protocol */
@@ -258,6 +284,28 @@ static int ipoib_create_qset ( struct ipoib_device *ipoib,
258 284
 	return rc;
259 285
 }
260 286
 
287
+/**
288
+ * Find path cache entry by GID
289
+ *
290
+ * @v gid		GID
291
+ * @ret entry		Path cache entry, or NULL
292
+ */
293
+static struct ipoib_cached_path *
294
+ipoib_find_cached_path ( struct ib_gid *gid ) {
295
+	struct ipoib_cached_path *path;
296
+	unsigned int i;
297
+
298
+	for ( i = 0 ; i < IPOIB_NUM_CACHED_PATHS ; i++ ) {
299
+		path = &ipoib_path_cache[i];
300
+		if ( memcmp ( &path->gid, gid, sizeof ( *gid ) ) == 0 )
301
+			return path;
302
+	}
303
+	DBG ( "IPoIB %08lx:%08lx:%08lx:%08lx cache miss\n",
304
+	      htonl ( gid->u.dwords[0] ), htonl ( gid->u.dwords[1] ),
305
+	      htonl ( gid->u.dwords[2] ), htonl ( gid->u.dwords[3] ) );
306
+	return NULL;
307
+}
308
+
261 309
 /**
262 310
  * Transmit path record request
263 311
  *
@@ -274,17 +322,15 @@ static int ipoib_get_path_record ( struct ipoib_device *ipoib,
274 322
  	static uint32_t tid = 0;
275 323
 	int rc;
276 324
 
277
-#if 0
278
-	DBG ( "get_path_record():\n" );
279 325
 	int get_path_record(struct ib_gid *dgid, uint16_t *dlid_p,
280 326
 			    uint8_t *sl_p, uint8_t *rate_p);
281 327
 	uint16_t tmp_dlid;
282 328
 	uint8_t tmp_sl;
283 329
 	uint8_t tmp_rate;
284 330
 	get_path_record ( gid, &tmp_dlid, &tmp_sl, &tmp_rate );
331
+	DBG ( "get_path_record() gives dlid = %04x, sl = %02x, rate = %02x\n",
332
+	      tmp_dlid, tmp_sl, tmp_rate );
285 333
 
286
-	DBG ( "ipoib_get_path_record():\n" );
287
-#endif
288 334
 
289 335
 	/* Allocate I/O buffer */
290 336
 	iobuf = alloc_iob ( sizeof ( *path_record ) );
@@ -307,13 +353,11 @@ static int ipoib_get_path_record ( struct ipoib_device *ipoib,
307 353
 	memcpy ( &path_record->sgid, &ibdev->port_gid,
308 354
 		 sizeof ( path_record->sgid ) );
309 355
 
310
-	//	DBG_HD ( path_record, sizeof ( *path_record ) );
311
-
312 356
 	/* Construct address vector */
313 357
 	memset ( &av, 0, sizeof ( av ) );
314 358
 	av.dlid = ibdev->sm_lid;
315 359
 	av.dest_qp = IB_SA_QPN;
316
-	av.qkey = IB_SA_QKEY;
360
+	av.qkey = IB_GLOBAL_QKEY;
317 361
 
318 362
 	/* Post send request */
319 363
 	if ( ( rc = ib_post_send ( ibdev, ipoib->meta.qp, &av,
@@ -339,6 +383,8 @@ static int ipoib_transmit ( struct net_device *netdev,
339 383
 	struct ipoib_device *ipoib = netdev->priv;
340 384
 	struct ib_device *ibdev = ipoib->ibdev;
341 385
 	struct ipoib_pseudo_hdr *ipoib_pshdr = iobuf->data;
386
+	struct ib_address_vector av;
387
+	struct ipoib_cached_path *path;
342 388
 	int rc;
343 389
 
344 390
 	if ( iob_len ( iobuf ) < sizeof ( *ipoib_pshdr ) ) {
@@ -346,18 +392,32 @@ static int ipoib_transmit ( struct net_device *netdev,
346 392
 		return -EINVAL;
347 393
 	}
348 394
 
349
-	DBG ( "TX pseudo-header:\n" );
350
-	DBG_HD ( ipoib_pshdr, sizeof ( *ipoib_pshdr ) );
351
-	if ( ipoib_pshdr->peer.qpn != htonl ( IPOIB_BROADCAST_QPN ) ) {
352
-		DBG ( "Get path record\n" );
353
-		rc = ipoib_get_path_record ( ipoib, &ipoib_pshdr->peer.gid );
354
-		free_iob ( iobuf );
355
-		return 0;
395
+	/* Construct address vector */
396
+	memset ( &av, 0, sizeof ( av ) );
397
+	if ( ipoib_pshdr->peer.qpn == htonl ( IPOIB_BROADCAST_QPN ) ) {
398
+		/* Broadcast address */
399
+		memcpy ( &av, &hack_ipoib_bcast_av, sizeof ( av ) );
400
+	} else {
401
+		/* Unicast - look in path cache */
402
+		path = ipoib_find_cached_path ( &ipoib_pshdr->peer.gid );
403
+		if ( ! path ) {
404
+			/* No path entry - get path record */
405
+			rc = ipoib_get_path_record ( ipoib,
406
+						     &ipoib_pshdr->peer.gid );
407
+			free_iob ( iobuf );
408
+			return rc;
409
+		}
410
+		av.dest_qp = ntohl ( ipoib_pshdr->peer.qpn );
411
+		av.qkey = IB_GLOBAL_QKEY;
412
+		av.dlid = path->dlid;
413
+		av.rate = path->rate;
414
+		av.sl = path->sl;
415
+		av.gid_present = 1;
416
+		memcpy ( &av.gid, &ipoib_pshdr->peer.gid, sizeof ( av.gid ) );
356 417
 	}
357 418
 
358 419
 	iob_pull ( iobuf, ( sizeof ( *ipoib_pshdr ) ) );
359
-	return ib_post_send ( ibdev, ipoib->data.qp,
360
-			      &hack_ipoib_bcast_av, iobuf );
420
+	return ib_post_send ( ibdev, ipoib->data.qp, &av, iobuf );
361 421
 }
362 422
 
363 423
 /**
@@ -392,14 +452,13 @@ static void ipoib_data_complete_recv ( struct ib_device *ibdev __unused,
392 452
 				       struct io_buffer *iobuf ) {
393 453
 	struct net_device *netdev = qp->owner_priv;
394 454
 	struct ipoib_device *ipoib = netdev->priv;
395
-	struct ib_global_route_header *grh = iobuf->data;
396 455
 	struct ipoib_pseudo_hdr *ipoib_pshdr;
397 456
 
398 457
 	if ( completion->syndrome ) {
399 458
 		netdev_rx_err ( netdev, iobuf, -EIO );
400 459
 	} else {
401 460
 		iob_put ( iobuf, completion->len );
402
-		iob_pull ( iobuf, ( sizeof ( *grh ) -
461
+		iob_pull ( iobuf, ( sizeof ( struct ib_global_route_header ) -
403 462
 				    sizeof ( *ipoib_pshdr ) ) );
404 463
 		/* FIXME: fill in a MAC address for the sake of AoE! */
405 464
 		netdev_rx ( netdev, iobuf );
@@ -444,16 +503,38 @@ static void ipoib_meta_complete_recv ( struct ib_device *ibdev __unused,
444 503
 				       struct io_buffer *iobuf ) {
445 504
 	struct net_device *netdev = qp->owner_priv;
446 505
 	struct ipoib_device *ipoib = netdev->priv;
447
-
448
-	DBG ( "***************** META RX!!!!!! ********\n" );
506
+	struct ib_mad_path_record *path_record;
507
+	struct ipoib_cached_path *path;
449 508
 
450 509
 	if ( completion->syndrome ) {
451 510
 		DBGC ( ipoib, "IPoIB %p metadata RX completion error %x\n",
452 511
 		       ipoib, completion->syndrome );
453 512
 	} else {
513
+		/* Update path cache */
454 514
 		iob_put ( iobuf, completion->len );
515
+		iob_pull ( iobuf, sizeof ( struct ib_global_route_header ) );
516
+
455 517
 		DBG ( "Metadata RX:\n" );
456 518
 		DBG_HD ( iobuf->data, iob_len ( iobuf ) );
519
+
520
+		path_record = iobuf->data;
521
+		path = &ipoib_path_cache[ipoib_path_cache_idx];
522
+		memcpy ( &path->gid, &path_record->dgid,
523
+			 sizeof ( path->gid ) );
524
+		path->dlid = ntohs ( path_record->dlid );
525
+		path->sl = ( path_record->reserved__sl & 0x0f );
526
+		path->rate = ( path_record->rate_selector__rate & 0x3f );
527
+		DBG ( "IPoIB %08lx:%08lx:%08lx:%08lx dlid %x sl %x rate %x\n",
528
+		      htonl ( path->gid.u.dwords[0] ),
529
+		      htonl ( path->gid.u.dwords[1] ),
530
+		      htonl ( path->gid.u.dwords[2] ),
531
+		      htonl ( path->gid.u.dwords[3] ),
532
+		      path->dlid, path->sl, path->rate );
533
+
534
+		/* Update path cache index */
535
+		ipoib_path_cache_idx++;
536
+		if ( ipoib_path_cache_idx == IPOIB_NUM_CACHED_PATHS )
537
+			ipoib_path_cache_idx = 0;
457 538
 	}
458 539
 
459 540
 	ipoib->meta.recv_fill--;
@@ -590,7 +671,7 @@ int ipoib_probe ( struct ib_device *ibdev ) {
590 671
 					IPOIB_META_NUM_CQES,
591 672
 					IPOIB_META_NUM_SEND_WQES,
592 673
 					IPOIB_META_NUM_RECV_WQES,
593
-					IB_SA_QKEY ) ) != 0 ) {
674
+					IB_GLOBAL_QKEY ) ) != 0 ) {
594 675
 		DBGC ( ipoib, "IPoIB %p could not allocate metadata QP: %s\n",
595 676
 		       ipoib, strerror ( rc ) );
596 677
 		goto err_create_meta_qset;

+ 7
- 7
src/drivers/net/mlx_ipoib/mt25218.c Просмотреть файл

@@ -749,7 +749,7 @@ static void arbel_ring_doorbell ( struct arbel *arbel,
749 749
 
750 750
 /** GID used for GID-less send work queue entries */
751 751
 static const struct ib_gid arbel_no_gid = {
752
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }
752
+	{ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 } }
753 753
 };
754 754
 
755 755
 /**
@@ -1238,12 +1238,12 @@ static int arbel_get_port_gid ( struct arbel *arbel,
1238 1238
 	/* Port info gives us the first half of the port GID */
1239 1239
 	if ( ( rc = arbel_get_port_info ( arbel, &u.port_info ) ) != 0 )
1240 1240
 		return rc;
1241
-	memcpy ( &port_gid->bytes[0], u.port_info.gid_prefix, 8 );
1242
-
1241
+	memcpy ( &port_gid->u.bytes[0], u.port_info.gid_prefix, 8 );
1242
+	
1243 1243
 	/* GUID info gives us the second half of the port GID */
1244 1244
 	if ( ( rc = arbel_get_guid_info ( arbel, &u.guid_info ) ) != 0 )
1245 1245
 		return rc;
1246
-	memcpy ( &port_gid->bytes[8], u.guid_info.gid_local, 8 );
1246
+	memcpy ( &port_gid->u.bytes[8], u.guid_info.gid_local, 8 );
1247 1247
 
1248 1248
 	return 0;
1249 1249
 }
@@ -1262,8 +1262,8 @@ static int arbel_get_sm_lid ( struct arbel *arbel,
1262 1262
 static int arbel_get_broadcast_gid ( struct arbel *arbel,
1263 1263
 				     struct ib_gid *broadcast_gid ) {
1264 1264
 	static const struct ib_gid ipv4_broadcast_gid = {
1265
-		{ 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00,
1266
-		  0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff }
1265
+		{ { 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00,
1266
+		    0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff } }
1267 1267
 	};
1268 1268
 	struct ib_mad_pkey_table pkey_table;
1269 1269
 	int rc;
@@ -1275,7 +1275,7 @@ static int arbel_get_broadcast_gid ( struct arbel *arbel,
1275 1275
 	/* Add partition key */
1276 1276
 	if ( ( rc = arbel_get_pkey_table ( arbel, &pkey_table ) ) != 0 )
1277 1277
 		return rc;
1278
-	memcpy ( &broadcast_gid->bytes[4], &pkey_table.pkey[0][0],
1278
+	memcpy ( &broadcast_gid->u.bytes[4], &pkey_table.pkey[0][0],
1279 1279
 		 sizeof ( pkey_table.pkey[0][0] ) );
1280 1280
 
1281 1281
 	return 0;

+ 11
- 5
src/include/gpxe/infiniband.h Просмотреть файл

@@ -14,11 +14,14 @@
14 14
 #define IB_SA_QPN	1
15 15
 
16 16
 /** Subnet administrator queue key */
17
-#define IB_SA_QKEY	0x80010000UL
17
+#define IB_GLOBAL_QKEY	0x80010000UL
18 18
 
19 19
 /** An Infiniband Global Identifier */
20 20
 struct ib_gid {
21
-	uint8_t bytes[16];
21
+	union {
22
+		uint8_t bytes[16];
23
+		uint32_t dwords[4];
24
+	} u;
22 25
 };
23 26
 
24 27
 /** An Infiniband Global Route Header */
@@ -136,7 +139,7 @@ struct ib_address_vector {
136 139
 	/** Destination Queue Pair */
137 140
 	unsigned int dest_qp;
138 141
 	/** Queue key */
139
-	unsigned int qkey;
142
+	unsigned long qkey;
140 143
 	/** Destination Local ID */
141 144
 	unsigned int dlid;
142 145
 	/** Rate */
@@ -530,9 +533,12 @@ struct ib_mad_path_record {
530 533
 	uint16_t slid;
531 534
 	uint32_t hop_limit__flow_label__raw_traffic;
532 535
 	uint32_t pkey__numb_path__reversible__tclass;
533
-	uint32_t rate__rate_selector__mtu__mtu_selector__sl__reserved;
536
+	uint8_t reserved1;
537
+	uint8_t reserved__sl;
538
+	uint8_t mtu_selector__mtu;
539
+	uint8_t rate_selector__rate;
534 540
 	uint32_t preference__packet_lifetime__packet_lifetime_selector;
535
-	uint32_t reserved1[35];
541
+	uint32_t reserved2[35];
536 542
 } __attribute__ (( packed ));
537 543
 
538 544
 union ib_mad {

Загрузка…
Отмена
Сохранить