ソースを参照

[infiniband] Allow for sending MADs via GMA without retransmission

tags/v0.9.8
Michael Brown 15年前
コミット
3c77fe73a5
3個のファイルの変更54行の追加30行の削除
  1. 1
    1
      src/include/gpxe/ib_gma.h
  2. 52
    28
      src/net/infiniband/ib_gma.c
  3. 1
    1
      src/net/infiniband/ib_pathrec.c

+ 1
- 1
src/include/gpxe/ib_gma.h ファイルの表示

@@ -63,7 +63,7 @@ struct ib_gma {
63 63
 };
64 64
 
65 65
 extern int ib_gma_request ( struct ib_gma *gma, union ib_mad *mad,
66
-			    struct ib_address_vector *av );
66
+			    struct ib_address_vector *av, int retry );
67 67
 extern int ib_create_gma ( struct ib_gma *gma, struct ib_device *ibdev,
68 68
 			   unsigned long qkey );
69 69
 extern void ib_destroy_gma ( struct ib_gma *gma );

+ 52
- 28
src/net/infiniband/ib_gma.c ファイルの表示

@@ -237,29 +237,16 @@ static struct ib_completion_queue_operations ib_gma_completion_ops = {
237 237
 };
238 238
 
239 239
 /**
240
- * Handle MAD request timer expiry
240
+ * Transmit MAD request
241 241
  *
242
- * @v timer		Retry timer
243
- * @v expired		Failure indicator
242
+ * @v gma		General management agent
243
+ * @v request		MAD request
244
+ * @ret rc		Return status code
244 245
  */
245
-static void ib_gma_timer_expired ( struct retry_timer *timer, int expired ) {
246
-	struct ib_mad_request *request =
247
-		container_of ( timer, struct ib_mad_request, timer );
248
-	struct ib_gma *gma = request->gma;
249
-	struct ib_device *ibdev = gma->ibdev;
246
+static int ib_gma_send ( struct ib_gma *gma, struct ib_mad_request *request ) {
250 247
 	struct io_buffer *iobuf;
251 248
 	int rc;
252 249
 
253
-	/* Abandon TID if we have tried too many times */
254
-	if ( expired ) {
255
-		DBGC ( gma, "GMA %p abandoning TID %08x%08x\n",
256
-		       gma, ntohl ( request->mad.hdr.tid[0] ),
257
-		       ntohl ( request->mad.hdr.tid[1] ) );
258
-		list_del ( &request->list );
259
-		free ( request );
260
-		return;
261
-	}
262
-
263 250
 	DBGC ( gma, "GMA %p TX TID %08x%08x (%02x,%02x,%02x,%04x)\n",
264 251
 	       gma, ntohl ( request->mad.hdr.tid[0] ),
265 252
 	       ntohl ( request->mad.hdr.tid[1] ), request->mad.hdr.mgmt_class,
@@ -267,29 +254,56 @@ static void ib_gma_timer_expired ( struct retry_timer *timer, int expired ) {
267 254
 	       ntohs ( request->mad.hdr.attr_id ) );
268 255
 	DBGC2_HDA ( gma, 0, &request->mad, sizeof ( request->mad ) );
269 256
 
270
-	/* Restart retransmission timer */
271
-	start_timer ( timer );
272
-
273 257
 	/* Construct I/O buffer */
274 258
 	iobuf = alloc_iob ( sizeof ( request->mad ) );
275 259
 	if ( ! iobuf ) {
276 260
 		DBGC ( gma, "GMA %p could not allocate buffer for TID "
277 261
 		       "%08x%08x\n", gma, ntohl ( request->mad.hdr.tid[0] ),
278 262
 		       ntohl ( request->mad.hdr.tid[1] ) );
279
-		return;
263
+		return -ENOMEM;
280 264
 	}
281 265
 	memcpy ( iob_put ( iobuf, sizeof ( request->mad ) ), &request->mad,
282 266
 		 sizeof ( request->mad ) );
283 267
 
284
-	/* Post send request */
285
-	if ( ( rc = ib_post_send ( ibdev, gma->qp, &request->av,
268
+	/* Send I/O buffer */
269
+	if ( ( rc = ib_post_send ( gma->ibdev, gma->qp, &request->av,
286 270
 				   iobuf ) ) != 0 ) {
287 271
 		DBGC ( gma, "GMA %p could not send TID %08x%08x: %s\n",
288 272
 		       gma,  ntohl ( request->mad.hdr.tid[0] ),
289 273
 		       ntohl ( request->mad.hdr.tid[1] ), strerror ( rc ) );
290 274
 		free_iob ( iobuf );
275
+		return rc;
276
+	}
277
+
278
+	return 0;
279
+}
280
+
281
+/**
282
+ * Handle MAD request timer expiry
283
+ *
284
+ * @v timer		Retry timer
285
+ * @v expired		Failure indicator
286
+ */
287
+static void ib_gma_timer_expired ( struct retry_timer *timer, int expired ) {
288
+	struct ib_mad_request *request =
289
+		container_of ( timer, struct ib_mad_request, timer );
290
+	struct ib_gma *gma = request->gma;
291
+
292
+	/* Abandon TID if we have tried too many times */
293
+	if ( expired ) {
294
+		DBGC ( gma, "GMA %p abandoning TID %08x%08x\n",
295
+		       gma, ntohl ( request->mad.hdr.tid[0] ),
296
+		       ntohl ( request->mad.hdr.tid[1] ) );
297
+		list_del ( &request->list );
298
+		free ( request );
291 299
 		return;
292 300
 	}
301
+
302
+	/* Restart retransmission timer */
303
+	start_timer ( timer );
304
+
305
+	/* Resend request */
306
+	ib_gma_send ( gma, request );
293 307
 }
294 308
 
295 309
 /**
@@ -298,10 +312,11 @@ static void ib_gma_timer_expired ( struct retry_timer *timer, int expired ) {
298 312
  * @v gma		General management agent
299 313
  * @v mad		MAD request
300 314
  * @v av		Destination address, or NULL for SM
315
+ * @v retry		Request should be retried until a response arrives
301 316
  * @ret rc		Return status code
302 317
  */
303 318
 int ib_gma_request ( struct ib_gma *gma, union ib_mad *mad,
304
-		     struct ib_address_vector *av ) {
319
+		     struct ib_address_vector *av, int retry ) {
305 320
 	struct ib_device *ibdev = gma->ibdev;
306 321
 	struct ib_mad_request *request;
307 322
 
@@ -312,7 +327,6 @@ int ib_gma_request ( struct ib_gma *gma, union ib_mad *mad,
312 327
 		return -ENOMEM;
313 328
 	}
314 329
 	request->gma = gma;
315
-	list_add ( &request->list, &gma->requests );
316 330
 	request->timer.expired = ib_gma_timer_expired;
317 331
 
318 332
 	/* Determine address vector */
@@ -332,8 +346,18 @@ int ib_gma_request ( struct ib_gma *gma, union ib_mad *mad,
332 346
 	request->mad.hdr.tid[0] = htonl ( IB_GMA_TID_MAGIC );
333 347
 	request->mad.hdr.tid[1] = htonl ( ++next_request_tid );
334 348
 
335
-	/* Start timer to initiate transmission */
336
-	start_timer_nodelay ( &request->timer );
349
+	/* Send initial request.  Ignore errors; the retry timer will
350
+	 * take care of those we care about.
351
+	 */
352
+	ib_gma_send ( gma, request );
353
+
354
+	/* Add to list and start timer if applicable */
355
+	if ( retry ) {
356
+		list_add ( &request->list, &gma->requests );
357
+		start_timer ( &request->timer );
358
+	} else {
359
+		free ( request );
360
+	}
337 361
 
338 362
 	return 0;
339 363
 }

+ 1
- 1
src/net/infiniband/ib_pathrec.c ファイルの表示

@@ -154,7 +154,7 @@ int ib_resolve_path ( struct ib_device *ibdev,
154 154
 		 sizeof ( sa->sa_data.path_record.sgid ) );
155 155
 
156 156
 	/* Issue path record request */
157
-	if ( ( rc = ib_gma_request ( &ibdev->gma, &mad, NULL ) ) != 0 ) {
157
+	if ( ( rc = ib_gma_request ( &ibdev->gma, &mad, NULL, 1 ) ) != 0 ) {
158 158
 		DBGC ( ibdev, "IBDEV %p could not get path record: %s\n",
159 159
 		       ibdev, strerror ( rc ) );
160 160
 		return rc;

読み込み中…
キャンセル
保存