浏览代码

[infiniband] Poll completion queues automatically

Currently, all Infiniband users must create a process for polling
their completion queues (or rely on a regular hook such as
netdev_poll() in ipoib.c).

Move instead to a model whereby the Infiniband core maintains a single
process calling ib_poll_eq(), and polling the event queue triggers
polls of the applicable completion queues.  (At present, the
Infiniband core simply polls all of the device's completion queues.)
Polling a completion queue will now implicitly refill all attached
receive work queues; this is analogous to the way that netdev_poll()
implicitly refills the RX ring.

Infiniband users no longer need to create a process just to poll their
completion queues and refill their receive rings.
tags/v0.9.8
Michael Brown 16 年前
父节点
当前提交
887d296b88

+ 3
- 6
src/drivers/net/ipoib.c 查看文件

743
 	struct ipoib_device *ipoib = netdev->priv;
743
 	struct ipoib_device *ipoib = netdev->priv;
744
 	struct ib_device *ibdev = ipoib->ibdev;
744
 	struct ib_device *ibdev = ipoib->ibdev;
745
 
745
 
746
-	ib_poll_cq ( ibdev, ipoib->meta.cq );
747
-	ib_poll_cq ( ibdev, ipoib->data.cq );
748
-	ib_qset_refill_recv ( ibdev, &ipoib->meta );
749
-	ib_qset_refill_recv ( ibdev, &ipoib->data );
746
+	ib_poll_eq ( ibdev );
750
 }
747
 }
751
 
748
 
752
 /**
749
 /**
861
 	mac->qpn = htonl ( ipoib->data.qp->qpn );
858
 	mac->qpn = htonl ( ipoib->data.qp->qpn );
862
 
859
 
863
 	/* Fill receive rings */
860
 	/* Fill receive rings */
864
-	ib_qset_refill_recv ( ibdev, &ipoib->meta );
865
-	ib_qset_refill_recv ( ibdev, &ipoib->data );
861
+	ib_refill_recv ( ibdev, ipoib->meta.qp );
862
+	ib_refill_recv ( ibdev, ipoib->data.qp );
866
 
863
 
867
 	/* Join broadcast group */
864
 	/* Join broadcast group */
868
 	if ( ( rc = ipoib_join_broadcast_group ( ipoib ) ) != 0 ) {
865
 	if ( ( rc = ipoib_join_broadcast_group ( ipoib ) ) != 0 ) {

+ 0
- 4
src/include/gpxe/ib_qset.h 查看文件

18
 	struct ib_completion_queue *cq;
18
 	struct ib_completion_queue *cq;
19
 	/** Queue pair */
19
 	/** Queue pair */
20
 	struct ib_queue_pair *qp;
20
 	struct ib_queue_pair *qp;
21
-	/** Receive work queue maximum fill level */
22
-	unsigned int recv_max_fill;
23
 };
21
 };
24
 
22
 
25
 extern int ib_create_qset ( struct ib_device *ibdev,
23
 extern int ib_create_qset ( struct ib_device *ibdev,
27
 			    struct ib_completion_queue_operations *cq_op,
25
 			    struct ib_completion_queue_operations *cq_op,
28
 			    unsigned int num_send_wqes,
26
 			    unsigned int num_send_wqes,
29
 			    unsigned int num_recv_wqes, unsigned long qkey );
27
 			    unsigned int num_recv_wqes, unsigned long qkey );
30
-extern void ib_qset_refill_recv ( struct ib_device *ibdev,
31
-				  struct ib_queue_set *qset );
32
 extern void ib_destroy_qset ( struct ib_device *ibdev,
28
 extern void ib_destroy_qset ( struct ib_device *ibdev,
33
 			      struct ib_queue_set *qset );
29
 			      struct ib_queue_set *qset );
34
 
30
 

+ 0
- 3
src/include/gpxe/ib_sma.h 查看文件

10
 FILE_LICENCE ( GPL2_OR_LATER );
10
 FILE_LICENCE ( GPL2_OR_LATER );
11
 
11
 
12
 #include <gpxe/infiniband.h>
12
 #include <gpxe/infiniband.h>
13
-#include <gpxe/process.h>
14
 
13
 
15
 /** Infiniband Subnet Management Agent operations */
14
 /** Infiniband Subnet Management Agent operations */
16
 struct ib_sma_operations {
15
 struct ib_sma_operations {
33
 	struct ib_completion_queue *cq;
32
 	struct ib_completion_queue *cq;
34
 	/** SMA queue pair */
33
 	/** SMA queue pair */
35
 	struct ib_queue_pair *qp;
34
 	struct ib_queue_pair *qp;
36
-	/** Poll process */
37
-	struct process poll;
38
 };
35
 };
39
 
36
 
40
 /** SMA number of send WQEs
37
 /** SMA number of send WQEs

+ 11
- 11
src/include/gpxe/infiniband.h 查看文件

154
 
154
 
155
 /** An Infiniband Completion Queue */
155
 /** An Infiniband Completion Queue */
156
 struct ib_completion_queue {
156
 struct ib_completion_queue {
157
+	/** Containing Infiniband device */
158
+	struct ib_device *ibdev;
159
+	/** List of completion queues on this Infiniband device */
160
+	struct list_head list;
157
 	/** Completion queue number */
161
 	/** Completion queue number */
158
 	unsigned long cqn;
162
 	unsigned long cqn;
159
 	/** Number of completion queue entries */
163
 	/** Number of completion queue entries */
310
 	struct list_head list;
314
 	struct list_head list;
311
 	/** Underlying device */
315
 	/** Underlying device */
312
 	struct device *dev;
316
 	struct device *dev;
317
+	/** List of completion queues */
318
+	struct list_head cqs;
313
 	/** List of queue pairs */
319
 	/** List of queue pairs */
314
 	struct list_head qps;
320
 	struct list_head qps;
315
 	/** Infiniband operations */
321
 	/** Infiniband operations */
350
 	       struct ib_completion_queue_operations *op );
356
 	       struct ib_completion_queue_operations *op );
351
 extern void ib_destroy_cq ( struct ib_device *ibdev,
357
 extern void ib_destroy_cq ( struct ib_device *ibdev,
352
 			    struct ib_completion_queue *cq );
358
 			    struct ib_completion_queue *cq );
359
+extern void ib_poll_cq ( struct ib_device *ibdev,
360
+			 struct ib_completion_queue *cq );
353
 extern struct ib_queue_pair *
361
 extern struct ib_queue_pair *
354
 ib_create_qp ( struct ib_device *ibdev, unsigned int num_send_wqes,
362
 ib_create_qp ( struct ib_device *ibdev, unsigned int num_send_wqes,
355
 	       struct ib_completion_queue *send_cq, unsigned int num_recv_wqes,
363
 	       struct ib_completion_queue *send_cq, unsigned int num_recv_wqes,
376
 			       struct ib_queue_pair *qp,
384
 			       struct ib_queue_pair *qp,
377
 			       struct ib_address_vector *av,
385
 			       struct ib_address_vector *av,
378
 			       struct io_buffer *iobuf, int rc );
386
 			       struct io_buffer *iobuf, int rc );
387
+extern void ib_refill_recv ( struct ib_device *ibdev,
388
+			     struct ib_queue_pair *qp );
379
 extern int ib_open ( struct ib_device *ibdev );
389
 extern int ib_open ( struct ib_device *ibdev );
380
 extern void ib_close ( struct ib_device *ibdev );
390
 extern void ib_close ( struct ib_device *ibdev );
381
 extern int ib_mcast_attach ( struct ib_device *ibdev, struct ib_queue_pair *qp,
391
 extern int ib_mcast_attach ( struct ib_device *ibdev, struct ib_queue_pair *qp,
388
 extern int register_ibdev ( struct ib_device *ibdev );
398
 extern int register_ibdev ( struct ib_device *ibdev );
389
 extern void unregister_ibdev ( struct ib_device *ibdev );
399
 extern void unregister_ibdev ( struct ib_device *ibdev );
390
 extern void ib_link_state_changed ( struct ib_device *ibdev );
400
 extern void ib_link_state_changed ( struct ib_device *ibdev );
401
+extern void ib_poll_eq ( struct ib_device *ibdev );
391
 extern struct list_head ib_devices;
402
 extern struct list_head ib_devices;
392
 
403
 
393
 /** Iterate over all network devices */
404
 /** Iterate over all network devices */
394
 #define for_each_ibdev( ibdev ) \
405
 #define for_each_ibdev( ibdev ) \
395
 	list_for_each_entry ( (ibdev), &ib_devices, list )
406
 	list_for_each_entry ( (ibdev), &ib_devices, list )
396
 
407
 
397
-/**
398
- * Poll completion queue
399
- *
400
- * @v ibdev		Infiniband device
401
- * @v cq		Completion queue
402
- */
403
-static inline __always_inline void
404
-ib_poll_cq ( struct ib_device *ibdev, struct ib_completion_queue *cq ) {
405
-	ibdev->op->poll_cq ( ibdev, cq );
406
-}
407
-
408
 /**
408
 /**
409
  * Check link state
409
  * Check link state
410
  *
410
  *

+ 109
- 3
src/net/infiniband.c 查看文件

43
 /** List of Infiniband devices */
43
 /** List of Infiniband devices */
44
 struct list_head ib_devices = LIST_HEAD_INIT ( ib_devices );
44
 struct list_head ib_devices = LIST_HEAD_INIT ( ib_devices );
45
 
45
 
46
+/***************************************************************************
47
+ *
48
+ * Completion queues
49
+ *
50
+ ***************************************************************************
51
+ */
52
+
46
 /**
53
 /**
47
  * Create completion queue
54
  * Create completion queue
48
  *
55
  *
63
 	cq = zalloc ( sizeof ( *cq ) );
70
 	cq = zalloc ( sizeof ( *cq ) );
64
 	if ( ! cq )
71
 	if ( ! cq )
65
 		goto err_alloc_cq;
72
 		goto err_alloc_cq;
73
+	cq->ibdev = ibdev;
74
+	list_add ( &cq->list, &ibdev->cqs );
66
 	cq->num_cqes = num_cqes;
75
 	cq->num_cqes = num_cqes;
67
 	INIT_LIST_HEAD ( &cq->work_queues );
76
 	INIT_LIST_HEAD ( &cq->work_queues );
68
 	cq->op = op;
77
 	cq->op = op;
81
 
90
 
82
 	ibdev->op->destroy_cq ( ibdev, cq );
91
 	ibdev->op->destroy_cq ( ibdev, cq );
83
  err_dev_create_cq:
92
  err_dev_create_cq:
93
+	list_del ( &cq->list );
84
 	free ( cq );
94
 	free ( cq );
85
  err_alloc_cq:
95
  err_alloc_cq:
86
 	return NULL;
96
 	return NULL;
98
 	       ibdev, cq->cqn );
108
 	       ibdev, cq->cqn );
99
 	assert ( list_empty ( &cq->work_queues ) );
109
 	assert ( list_empty ( &cq->work_queues ) );
100
 	ibdev->op->destroy_cq ( ibdev, cq );
110
 	ibdev->op->destroy_cq ( ibdev, cq );
111
+	list_del ( &cq->list );
101
 	free ( cq );
112
 	free ( cq );
102
 }
113
 }
103
 
114
 
115
+/**
116
+ * Poll completion queue
117
+ *
118
+ * @v ibdev		Infiniband device
119
+ * @v cq		Completion queue
120
+ */
121
+void ib_poll_cq ( struct ib_device *ibdev,
122
+		  struct ib_completion_queue *cq ) {
123
+	struct ib_work_queue *wq;
124
+
125
+	/* Poll completion queue */
126
+	ibdev->op->poll_cq ( ibdev, cq );
127
+
128
+	/* Refill receive work queues */
129
+	list_for_each_entry ( wq, &cq->work_queues, list ) {
130
+		if ( ! wq->is_send )
131
+			ib_refill_recv ( ibdev, wq->qp );
132
+	}
133
+}
134
+
135
+/***************************************************************************
136
+ *
137
+ * Work queues
138
+ *
139
+ ***************************************************************************
140
+ */
141
+
104
 /**
142
 /**
105
  * Create queue pair
143
  * Create queue pair
106
  *
144
  *
400
 	qp->recv.fill--;
438
 	qp->recv.fill--;
401
 }
439
 }
402
 
440
 
441
+/**
442
+ * Refill receive work queue
443
+ *
444
+ * @v ibdev		Infiniband device
445
+ * @v qp		Queue pair
446
+ */
447
+void ib_refill_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp ) {
448
+	struct io_buffer *iobuf;
449
+	int rc;
450
+
451
+	/* Keep filling while unfilled entries remain */
452
+	while ( qp->recv.fill < qp->recv.num_wqes ) {
453
+
454
+		/* Allocate I/O buffer */
455
+		iobuf = alloc_iob ( IB_MAX_PAYLOAD_SIZE );
456
+		if ( ! iobuf ) {
457
+			/* Non-fatal; we will refill on next attempt */
458
+			return;
459
+		}
460
+
461
+		/* Post I/O buffer */
462
+		if ( ( rc = ib_post_recv ( ibdev, qp, iobuf ) ) != 0 ) {
463
+			DBGC ( ibdev, "IBDEV %p could not refill: %s\n",
464
+			       ibdev, strerror ( rc ) );
465
+			free_iob ( iobuf );
466
+			/* Give up */
467
+			return;
468
+		}
469
+	}
470
+}
471
+
472
+/***************************************************************************
473
+ *
474
+ * Link control
475
+ *
476
+ ***************************************************************************
477
+ */
478
+
403
 /**
479
 /**
404
  * Open port
480
  * Open port
405
  *
481
  *
436
 		ibdev->op->close ( ibdev );
512
 		ibdev->op->close ( ibdev );
437
 }
513
 }
438
 
514
 
515
+/***************************************************************************
516
+ *
517
+ * Multicast
518
+ *
519
+ ***************************************************************************
520
+ */
521
+
439
 /**
522
 /**
440
  * Attach to multicast group
523
  * Attach to multicast group
441
  *
524
  *
495
 	}
578
 	}
496
 }
579
 }
497
 
580
 
581
+/***************************************************************************
582
+ *
583
+ * Miscellaneous
584
+ *
585
+ ***************************************************************************
586
+ */
587
+
498
 /**
588
 /**
499
  * Get Infiniband HCA information
589
  * Get Infiniband HCA information
500
  *
590
  *
540
 	ipoib_link_state_changed ( ibdev );
630
 	ipoib_link_state_changed ( ibdev );
541
 }
631
 }
542
 
632
 
633
+/**
634
+ * Poll event queue
635
+ *
636
+ * @v ibdev		Infiniband device
637
+ */
638
+void ib_poll_eq ( struct ib_device *ibdev ) {
639
+	struct ib_completion_queue *cq;
640
+
641
+	/* Poll device's event queue */
642
+	ibdev->op->poll_eq ( ibdev );
643
+
644
+	/* Poll all completion queues */
645
+	list_for_each_entry ( cq, &ibdev->cqs, list )
646
+		ib_poll_cq ( ibdev, cq );
647
+}
648
+
543
 /**
649
 /**
544
  * Single-step the Infiniband event queue
650
  * Single-step the Infiniband event queue
545
  *
651
  *
548
 static void ib_step ( struct process *process __unused ) {
654
 static void ib_step ( struct process *process __unused ) {
549
 	struct ib_device *ibdev;
655
 	struct ib_device *ibdev;
550
 
656
 
551
-	list_for_each_entry ( ibdev, &ib_devices, list ) {
552
-		ibdev->op->poll_eq ( ibdev );
553
-	}
657
+	for_each_ibdev ( ibdev )
658
+		ib_poll_eq ( ibdev );
554
 }
659
 }
555
 
660
 
556
 /** Infiniband event queue process */
661
 /** Infiniband event queue process */
581
 	if ( ibdev ) {
686
 	if ( ibdev ) {
582
 		drv_priv = ( ( ( void * ) ibdev ) + sizeof ( *ibdev ) );
687
 		drv_priv = ( ( ( void * ) ibdev ) + sizeof ( *ibdev ) );
583
 		ib_set_drvdata ( ibdev, drv_priv );
688
 		ib_set_drvdata ( ibdev, drv_priv );
689
+		INIT_LIST_HEAD ( &ibdev->cqs );
584
 		INIT_LIST_HEAD ( &ibdev->qps );
690
 		INIT_LIST_HEAD ( &ibdev->qps );
585
 		ibdev->lid = IB_LID_NONE;
691
 		ibdev->lid = IB_LID_NONE;
586
 		ibdev->pkey = IB_PKEY_NONE;
692
 		ibdev->pkey = IB_PKEY_NONE;

+ 0
- 34
src/net/infiniband/ib_qset.c 查看文件

54
 	assert ( qset->cq == NULL );
54
 	assert ( qset->cq == NULL );
55
 	assert ( qset->qp == NULL );
55
 	assert ( qset->qp == NULL );
56
 
56
 
57
-	/* Store queue parameters */
58
-	qset->recv_max_fill = num_recv_wqes;
59
-
60
 	/* Allocate completion queue */
57
 	/* Allocate completion queue */
61
 	qset->cq = ib_create_cq ( ibdev, num_cqes, cq_op );
58
 	qset->cq = ib_create_cq ( ibdev, num_cqes, cq_op );
62
 	if ( ! qset->cq ) {
59
 	if ( ! qset->cq ) {
83
 	return rc;
80
 	return rc;
84
 }
81
 }
85
 
82
 
86
-/**
87
- * Refill IPoIB receive ring
88
- *
89
- * @v ibdev		Infiniband device
90
- * @v qset		Queue set
91
- */
92
-void ib_qset_refill_recv ( struct ib_device *ibdev,
93
-			   struct ib_queue_set *qset ) {
94
-	struct io_buffer *iobuf;
95
-	int rc;
96
-
97
-	while ( qset->qp->recv.fill < qset->recv_max_fill ) {
98
-
99
-		/* Allocate I/O buffer */
100
-		iobuf = alloc_iob ( IB_MAX_PAYLOAD_SIZE );
101
-		if ( ! iobuf ) {
102
-			/* Non-fatal; we will refill on next attempt */
103
-			return;
104
-		}
105
-
106
-		/* Post I/O buffer */
107
-		if ( ( rc = ib_post_recv ( ibdev, qset->qp, iobuf ) ) != 0 ) {
108
-			DBGC ( ibdev, "IBDEV %p could not refill: %s\n",
109
-			       ibdev, strerror ( rc ) );
110
-			free_iob ( iobuf );
111
-			/* Give up */
112
-			return;
113
-		}
114
-	}
115
-}
116
-
117
 /**
83
 /**
118
  * Destroy queue set
84
  * Destroy queue set
119
  *
85
  *

+ 1
- 52
src/net/infiniband/ib_sma.c 查看文件

27
 #include <byteswap.h>
27
 #include <byteswap.h>
28
 #include <gpxe/infiniband.h>
28
 #include <gpxe/infiniband.h>
29
 #include <gpxe/iobuf.h>
29
 #include <gpxe/iobuf.h>
30
-#include <gpxe/process.h>
31
 #include <gpxe/ib_sma.h>
30
 #include <gpxe/ib_sma.h>
32
 
31
 
33
 /**
32
 /**
348
 	return 0;
347
 	return 0;
349
 }
348
 }
350
 
349
 
351
-/**
352
- * Refill SMA receive ring
353
- *
354
- * @v sma		Subnet management agent
355
- */
356
-static void ib_sma_refill_recv ( struct ib_sma *sma ) {
357
-	struct ib_device *ibdev = sma->ibdev;
358
-	struct io_buffer *iobuf;
359
-	int rc;
360
-
361
-	while ( sma->qp->recv.fill < IB_SMA_NUM_RECV_WQES ) {
362
-
363
-		/* Allocate I/O buffer */
364
-		iobuf = alloc_iob ( IB_MAX_PAYLOAD_SIZE );
365
-		if ( ! iobuf ) {
366
-			/* Non-fatal; we will refill on next attempt */
367
-			return;
368
-		}
369
-
370
-		/* Post I/O buffer */
371
-		if ( ( rc = ib_post_recv ( ibdev, sma->qp, iobuf ) ) != 0 ) {
372
-			DBGC ( sma, "SMA %p could not refill: %s\n",
373
-			       sma, strerror ( rc ) );
374
-			free_iob ( iobuf );
375
-			/* Give up */
376
-			return;
377
-		}
378
-	}
379
-}
380
-
381
 /**
350
 /**
382
  * Complete SMA send
351
  * Complete SMA send
383
  *
352
  *
456
 	.complete_recv = ib_sma_complete_recv,
425
 	.complete_recv = ib_sma_complete_recv,
457
 };
426
 };
458
 
427
 
459
-/**
460
- * Poll SMA
461
- *
462
- * @v process		Process
463
- */
464
-static void ib_sma_step ( struct process *process ) {
465
-	struct ib_sma *sma =
466
-		container_of ( process, struct ib_sma, poll );
467
-	struct ib_device *ibdev = sma->ibdev;
468
-
469
-	/* Poll the kernel completion queue */
470
-	ib_poll_cq ( ibdev, sma->cq );
471
-
472
-	/* Refill the receive ring */
473
-	ib_sma_refill_recv ( sma );
474
-}
475
-
476
 /**
428
 /**
477
  * Create SMA
429
  * Create SMA
478
  *
430
  *
489
 	memset ( sma, 0, sizeof ( *sma ) );
441
 	memset ( sma, 0, sizeof ( *sma ) );
490
 	sma->ibdev = ibdev;
442
 	sma->ibdev = ibdev;
491
 	sma->op = op;
443
 	sma->op = op;
492
-	process_init ( &sma->poll, ib_sma_step, &ibdev->refcnt );
493
 
444
 
494
 	/* Create completion queue */
445
 	/* Create completion queue */
495
 	sma->cq = ib_create_cq ( ibdev, IB_SMA_NUM_CQES,
446
 	sma->cq = ib_create_cq ( ibdev, IB_SMA_NUM_CQES,
517
 	}
468
 	}
518
 
469
 
519
 	/* Fill receive ring */
470
 	/* Fill receive ring */
520
-	ib_sma_refill_recv ( sma );
471
+	ib_refill_recv ( ibdev, sma->qp );
521
 	return 0;
472
 	return 0;
522
 
473
 
523
  err_not_qp0:
474
  err_not_qp0:
525
  err_create_qp:
476
  err_create_qp:
526
 	ib_destroy_cq ( ibdev, sma->cq );
477
 	ib_destroy_cq ( ibdev, sma->cq );
527
  err_create_cq:
478
  err_create_cq:
528
-	process_del ( &sma->poll );
529
 	return rc;
479
 	return rc;
530
 }
480
 }
531
 
481
 
539
 
489
 
540
 	ib_destroy_qp ( ibdev, sma->qp );
490
 	ib_destroy_qp ( ibdev, sma->qp );
541
 	ib_destroy_cq ( ibdev, sma->cq );
491
 	ib_destroy_cq ( ibdev, sma->cq );
542
-	process_del ( &sma->poll );
543
 }
492
 }

正在加载...
取消
保存