Browse Source

[infiniband] Maintain queue fill level as a property of a work queue

Both queue owners and drivers often need to keep track of the fill
level, so let's make it a generic property.
tags/v0.9.6
Michael Brown 16 years ago
parent
commit
0de5f7af6d
3 changed files with 110 additions and 70 deletions
  1. 4
    11
      src/drivers/net/ipoib.c
  2. 15
    59
      src/include/gpxe/infiniband.h
  3. 91
    0
      src/net/infiniband.c

+ 4
- 11
src/drivers/net/ipoib.c View File

@@ -57,8 +57,6 @@ struct ipoib_queue_set {
57 57
 	struct ib_completion_queue *cq;
58 58
 	/** Queue pair */
59 59
 	struct ib_queue_pair *qp;
60
-	/** Receive work queue fill level */
61
-	unsigned int recv_fill;
62 60
 	/** Receive work queue maximum fill level */
63 61
 	unsigned int recv_max_fill;
64 62
 };
@@ -565,7 +563,7 @@ static void ipoib_data_complete_recv ( struct ib_device *ibdev __unused,
565 563
 
566 564
 	if ( completion->syndrome ) {
567 565
 		netdev_rx_err ( netdev, iobuf, -EIO );
568
-		goto done;
566
+		return;
569 567
 	}
570 568
 
571 569
 	iob_put ( iobuf, completion->len );
@@ -574,7 +572,7 @@ static void ipoib_data_complete_recv ( struct ib_device *ibdev __unused,
574 572
 		       "contain GRH\n", ipoib );
575 573
 		DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
576 574
 		netdev_rx_err ( netdev, iobuf, -EIO );
577
-		goto done;
575
+		return;
578 576
 	}
579 577
 	iob_pull ( iobuf, sizeof ( struct ib_global_route_header ) );
580 578
 
@@ -583,16 +581,13 @@ static void ipoib_data_complete_recv ( struct ib_device *ibdev __unused,
583 581
 		       "contain IPoIB header\n", ipoib );
584 582
 		DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
585 583
 		netdev_rx_err ( netdev, iobuf, -EIO );
586
-		goto done;
584
+		return;
587 585
 	}
588 586
 
589 587
 	ipoib_pshdr = iob_push ( iobuf, sizeof ( *ipoib_pshdr ) );
590 588
 	/* FIXME: fill in a MAC address for the sake of AoE! */
591 589
 
592 590
 	netdev_rx ( netdev, iobuf );
593
-
594
- done:
595
-	ipoib->data.recv_fill--;
596 591
 }
597 592
 
598 593
 /**
@@ -732,7 +727,6 @@ static void ipoib_meta_complete_recv ( struct ib_device *ibdev __unused,
732 727
 	}
733 728
 
734 729
  done:
735
-	ipoib->meta.recv_fill--;
736 730
 	free_iob ( iobuf );
737 731
 }
738 732
 
@@ -747,7 +741,7 @@ static void ipoib_refill_recv ( struct ipoib_device *ipoib,
747 741
 	struct io_buffer *iobuf;
748 742
 	int rc;
749 743
 
750
-	while ( qset->recv_fill < qset->recv_max_fill ) {
744
+	while ( qset->qp->recv.fill < qset->recv_max_fill ) {
751 745
 		iobuf = alloc_iob ( IPOIB_PKT_LEN );
752 746
 		if ( ! iobuf )
753 747
 			break;
@@ -755,7 +749,6 @@ static void ipoib_refill_recv ( struct ipoib_device *ipoib,
755 749
 			free_iob ( iobuf );
756 750
 			break;
757 751
 		}
758
-		qset->recv_fill++;
759 752
 	}
760 753
 }
761 754
 

+ 15
- 59
src/include/gpxe/infiniband.h View File

@@ -66,6 +66,8 @@ struct ib_work_queue {
66 66
 	struct list_head list;
67 67
 	/** Number of work queue entries */
68 68
 	unsigned int num_wqes;
69
+	/** Number of occupied work queue entries */
70
+	unsigned int fill;
69 71
 	/** Next work queue entry index
70 72
 	 *
71 73
 	 * This is the index of the next entry to be filled (i.e. the
@@ -355,70 +357,24 @@ extern void ib_destroy_qp ( struct ib_device *ibdev,
355 357
 			    struct ib_queue_pair *qp );
356 358
 extern struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
357 359
 					   unsigned long qpn, int is_send );
360
+extern int ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
361
+			  struct ib_address_vector *av,
362
+			  struct io_buffer *iobuf );
363
+extern int ib_post_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
364
+			  struct io_buffer *iobuf );
365
+extern void ib_complete_send ( struct ib_device *ibdev,
366
+			       struct ib_queue_pair *qp,
367
+			       struct ib_completion *completion,
368
+			       struct io_buffer *iobuf );
369
+extern void ib_complete_recv ( struct ib_device *ibdev,
370
+			       struct ib_queue_pair *qp,
371
+			       struct ib_completion *completion,
372
+			       struct io_buffer *iobuf );
358 373
 extern struct ib_device * alloc_ibdev ( size_t priv_size );
359 374
 extern int register_ibdev ( struct ib_device *ibdev );
360 375
 extern void unregister_ibdev ( struct ib_device *ibdev );
361 376
 extern void ib_link_state_changed ( struct ib_device *ibdev );
362 377
 
363
-/**
364
- * Post send work queue entry
365
- *
366
- * @v ibdev		Infiniband device
367
- * @v qp		Queue pair
368
- * @v av		Address vector
369
- * @v iobuf		I/O buffer
370
- * @ret rc		Return status code
371
- */
372
-static inline __attribute__ (( always_inline )) int
373
-ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
374
-	       struct ib_address_vector *av, struct io_buffer *iobuf ) {
375
-	return ibdev->op->post_send ( ibdev, qp, av, iobuf );
376
-}
377
-
378
-/**
379
- * Post receive work queue entry
380
- *
381
- * @v ibdev		Infiniband device
382
- * @v qp		Queue pair
383
- * @v iobuf		I/O buffer
384
- * @ret rc		Return status code
385
- */
386
-static inline __attribute__ (( always_inline )) int
387
-ib_post_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
388
-	       struct io_buffer *iobuf ) {
389
-	return ibdev->op->post_recv ( ibdev, qp, iobuf );
390
-}
391
-
392
-/**
393
- * Complete send work queue entry
394
- *
395
- * @v ibdev		Infiniband device
396
- * @v qp		Queue pair
397
- * @v completion	Completion
398
- * @v iobuf		I/O buffer
399
- */
400
-static inline __attribute__ (( always_inline )) void
401
-ib_complete_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
402
-		   struct ib_completion *completion,
403
-		   struct io_buffer *iobuf ) {
404
-	return qp->send.cq->complete_send ( ibdev, qp, completion, iobuf );
405
-}
406
-
407
-/**
408
- * Complete receive work queue entry
409
- *
410
- * @v ibdev		Infiniband device
411
- * @v qp		Queue pair
412
- * @v completion	Completion
413
- * @v iobuf		I/O buffer
414
- */
415
-static inline __attribute__ (( always_inline )) void
416
-ib_complete_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
417
-		   struct ib_completion *completion,
418
-		   struct io_buffer *iobuf ) {
419
-	return qp->recv.cq->complete_recv ( ibdev, qp, completion, iobuf );
420
-}
421
-
422 378
 /**
423 379
  * Poll completion queue
424 380
  *

+ 91
- 0
src/net/infiniband.c View File

@@ -244,6 +244,97 @@ struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
244 244
 	return NULL;
245 245
 }
246 246
 
247
+/**
248
+ * Post send work queue entry
249
+ *
250
+ * @v ibdev		Infiniband device
251
+ * @v qp		Queue pair
252
+ * @v av		Address vector
253
+ * @v iobuf		I/O buffer
254
+ * @ret rc		Return status code
255
+ */
256
+int ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
257
+		   struct ib_address_vector *av, struct io_buffer *iobuf ) {
258
+	int rc;
259
+
260
+	/* Check queue fill level */
261
+	if ( qp->send.fill >= qp->send.num_wqes ) {
262
+		DBGC ( ibdev, "IBDEV %p QPN %#lx send queue full\n",
263
+		       ibdev, qp->qpn );
264
+		return -ENOBUFS;
265
+	}
266
+
267
+	/* Post to hardware */
268
+	if ( ( rc = ibdev->op->post_send ( ibdev, qp, av, iobuf ) ) != 0 ) {
269
+		DBGC ( ibdev, "IBDEV %p QPN %#lx could not post send WQE: "
270
+		       "%s\n", ibdev, qp->qpn, strerror ( rc ) );
271
+		return rc;
272
+	}
273
+
274
+	qp->send.fill++;
275
+	return 0;
276
+}
277
+
278
+/**
279
+ * Post receive work queue entry
280
+ *
281
+ * @v ibdev		Infiniband device
282
+ * @v qp		Queue pair
283
+ * @v iobuf		I/O buffer
284
+ * @ret rc		Return status code
285
+ */
286
+int ib_post_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
287
+		   struct io_buffer *iobuf ) {
288
+	int rc;
289
+
290
+	/* Check queue fill level */
291
+	if ( qp->recv.fill >= qp->recv.num_wqes ) {
292
+		DBGC ( ibdev, "IBDEV %p QPN %#lx receive queue full\n",
293
+		       ibdev, qp->qpn );
294
+		return -ENOBUFS;
295
+	}
296
+
297
+	/* Post to hardware */
298
+	if ( ( rc = ibdev->op->post_recv ( ibdev, qp, iobuf ) ) != 0 ) {
299
+		DBGC ( ibdev, "IBDEV %p QPN %#lx could not post receive WQE: "
300
+		       "%s\n", ibdev, qp->qpn, strerror ( rc ) );
301
+		return rc;
302
+	}
303
+
304
+	qp->recv.fill++;
305
+	return 0;
306
+}
307
+
308
+/**
309
+ * Complete send work queue entry
310
+ *
311
+ * @v ibdev		Infiniband device
312
+ * @v qp		Queue pair
313
+ * @v completion	Completion
314
+ * @v iobuf		I/O buffer
315
+ */
316
+void ib_complete_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
317
+			struct ib_completion *completion,
318
+			struct io_buffer *iobuf ) {
319
+	qp->send.cq->complete_send ( ibdev, qp, completion, iobuf );
320
+	qp->send.fill--;
321
+}
322
+
323
+/**
324
+ * Complete receive work queue entry
325
+ *
326
+ * @v ibdev		Infiniband device
327
+ * @v qp		Queue pair
328
+ * @v completion	Completion
329
+ * @v iobuf		I/O buffer
330
+ */
331
+void ib_complete_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
332
+			struct ib_completion *completion,
333
+			struct io_buffer *iobuf ) {
334
+	qp->recv.cq->complete_recv ( ibdev, qp, completion, iobuf );
335
+	qp->recv.fill--;
336
+}
337
+
247 338
 /***************************************************************************
248 339
  *
249 340
  * Management datagram operations

Loading…
Cancel
Save