|
@@ -45,19 +45,36 @@ extern struct ib_address_vector hack_ipoib_bcast_av;
|
45
|
45
|
#define IPOIB_MTU 2048
|
46
|
46
|
|
47
|
47
|
/** Number of IPoIB send work queue entries */
|
48
|
|
-#define IPOIB_NUM_SEND_WQES 8
|
|
48
|
+#define IPOIB_DATA_NUM_SEND_WQES 4
|
49
|
49
|
|
50
|
50
|
/** Number of IPoIB receive work queue entries */
|
51
|
|
-#define IPOIB_NUM_RECV_WQES 8
|
|
51
|
+#define IPOIB_DATA_NUM_RECV_WQES 8
|
52
|
52
|
|
53
|
53
|
/** Number of IPoIB completion entries */
|
54
|
|
-#define IPOIB_NUM_CQES 8
|
|
54
|
+#define IPOIB_DATA_NUM_CQES 8
|
55
|
55
|
|
56
|
|
-struct ipoib_device {
|
57
|
|
- struct ib_device *ibdev;
|
|
56
|
+/** An IPoIB queue set */
|
|
57
|
+struct ipoib_queue_set {
|
|
58
|
+ /** Completion queue */
|
58
|
59
|
struct ib_completion_queue *cq;
|
|
60
|
+ /** Queue pair */
|
59
|
61
|
struct ib_queue_pair *qp;
|
60
|
|
- unsigned int rx_fill;
|
|
62
|
+ /** Receive work queue fill level */
|
|
63
|
+ unsigned int recv_fill;
|
|
64
|
+ /** Receive work queue maximum fill level */
|
|
65
|
+ unsigned int recv_max_fill;
|
|
66
|
+};
|
|
67
|
+
|
|
68
|
+/** An IPoIB device */
|
|
69
|
+struct ipoib_device {
|
|
70
|
+ /** Network device */
|
|
71
|
+ struct net_device *netdev;
|
|
72
|
+ /** Underlying Infiniband device */
|
|
73
|
+ struct ib_device *ibdev;
|
|
74
|
+ /** Data queue set */
|
|
75
|
+ struct ipoib_queue_set data;
|
|
76
|
+ /** Data queue set */
|
|
77
|
+ struct ipoib_queue_set meta;
|
61
|
78
|
};
|
62
|
79
|
|
63
|
80
|
/****************************************************************************
|
|
@@ -164,6 +181,69 @@ struct ll_protocol ipoib_protocol __ll_protocol = {
|
164
|
181
|
****************************************************************************
|
165
|
182
|
*/
|
166
|
183
|
|
|
184
|
+/**
|
|
185
|
+ * Destroy queue set
|
|
186
|
+ *
|
|
187
|
+ * @v ipoib IPoIB device
|
|
188
|
+ * @v qset Queue set
|
|
189
|
+ */
|
|
190
|
+static void ipoib_destroy_qset ( struct ipoib_device *ipoib,
|
|
191
|
+ struct ipoib_queue_set *qset ) {
|
|
192
|
+ struct ib_device *ibdev = ipoib->ibdev;
|
|
193
|
+
|
|
194
|
+ if ( qset->qp )
|
|
195
|
+ ib_destroy_qp ( ibdev, qset->qp );
|
|
196
|
+ if ( qset->cq )
|
|
197
|
+ ib_destroy_cq ( ibdev, qset->cq );
|
|
198
|
+ memset ( qset, 0, sizeof ( *qset ) );
|
|
199
|
+}
|
|
200
|
+
|
|
201
|
+/**
|
|
202
|
+ * Create queue set
|
|
203
|
+ *
|
|
204
|
+ * @v ipoib IPoIB device
|
|
205
|
+ * @v qset Queue set
|
|
206
|
+ * @ret rc Return status code
|
|
207
|
+ */
|
|
208
|
+static int ipoib_create_qset ( struct ipoib_device *ipoib,
|
|
209
|
+ struct ipoib_queue_set *qset,
|
|
210
|
+ unsigned int num_cqes,
|
|
211
|
+ unsigned int num_send_wqes,
|
|
212
|
+ unsigned int num_recv_wqes,
|
|
213
|
+ unsigned long qkey ) {
|
|
214
|
+ struct ib_device *ibdev = ipoib->ibdev;
|
|
215
|
+ int rc;
|
|
216
|
+
|
|
217
|
+ /* Store queue parameters */
|
|
218
|
+ qset->recv_max_fill = num_recv_wqes;
|
|
219
|
+
|
|
220
|
+ /* Allocate completion queue */
|
|
221
|
+ qset->cq = ib_create_cq ( ibdev, num_cqes );
|
|
222
|
+ if ( ! qset->cq ) {
|
|
223
|
+ DBGC ( ipoib, "IPoIB %p could not allocate completion queue\n",
|
|
224
|
+ ipoib );
|
|
225
|
+ rc = -ENOMEM;
|
|
226
|
+ goto err;
|
|
227
|
+ }
|
|
228
|
+
|
|
229
|
+ /* Allocate queue pair */
|
|
230
|
+ qset->qp = ib_create_qp ( ibdev, num_send_wqes, qset->cq,
|
|
231
|
+ num_recv_wqes, qset->cq, qkey );
|
|
232
|
+ if ( ! qset->qp ) {
|
|
233
|
+ DBGC ( ipoib, "IPoIB %p could not allocate queue pair\n",
|
|
234
|
+ ipoib );
|
|
235
|
+ rc = -ENOMEM;
|
|
236
|
+ goto err;
|
|
237
|
+ }
|
|
238
|
+ qset->qp->owner_priv = ipoib->netdev;
|
|
239
|
+
|
|
240
|
+ return 0;
|
|
241
|
+
|
|
242
|
+ err:
|
|
243
|
+ ipoib_destroy_qset ( ipoib, qset );
|
|
244
|
+ return rc;
|
|
245
|
+}
|
|
246
|
+
|
167
|
247
|
/**
|
168
|
248
|
* Transmit packet via IPoIB network device
|
169
|
249
|
*
|
|
@@ -183,7 +263,7 @@ static int ipoib_transmit ( struct net_device *netdev,
|
183
|
263
|
}
|
184
|
264
|
|
185
|
265
|
iob_pull ( iobuf, ( sizeof ( *ipoib_pshdr ) ) );
|
186
|
|
- return ib_post_send ( ibdev, ipoib->qp,
|
|
266
|
+ return ib_post_send ( ibdev, ipoib->data.qp,
|
187
|
267
|
&hack_ipoib_bcast_av, iobuf );
|
188
|
268
|
}
|
189
|
269
|
|
|
@@ -195,10 +275,10 @@ static int ipoib_transmit ( struct net_device *netdev,
|
195
|
275
|
* @v completion Completion
|
196
|
276
|
* @v iobuf I/O buffer
|
197
|
277
|
*/
|
198
|
|
-static void ipoib_complete_send ( struct ib_device *ibdev __unused,
|
199
|
|
- struct ib_queue_pair *qp,
|
200
|
|
- struct ib_completion *completion,
|
201
|
|
- struct io_buffer *iobuf ) {
|
|
278
|
+static void ipoib_data_complete_send ( struct ib_device *ibdev __unused,
|
|
279
|
+ struct ib_queue_pair *qp,
|
|
280
|
+ struct ib_completion *completion,
|
|
281
|
+ struct io_buffer *iobuf ) {
|
202
|
282
|
struct net_device *netdev = qp->owner_priv;
|
203
|
283
|
|
204
|
284
|
netdev_tx_complete_err ( netdev, iobuf,
|
|
@@ -213,10 +293,10 @@ static void ipoib_complete_send ( struct ib_device *ibdev __unused,
|
213
|
293
|
* @v completion Completion
|
214
|
294
|
* @v iobuf I/O buffer
|
215
|
295
|
*/
|
216
|
|
-static void ipoib_complete_recv ( struct ib_device *ibdev __unused,
|
217
|
|
- struct ib_queue_pair *qp,
|
218
|
|
- struct ib_completion *completion,
|
219
|
|
- struct io_buffer *iobuf ) {
|
|
296
|
+static void ipoib_data_complete_recv ( struct ib_device *ibdev __unused,
|
|
297
|
+ struct ib_queue_pair *qp,
|
|
298
|
+ struct ib_completion *completion,
|
|
299
|
+ struct io_buffer *iobuf ) {
|
220
|
300
|
struct net_device *netdev = qp->owner_priv;
|
221
|
301
|
struct ipoib_device *ipoib = netdev->priv;
|
222
|
302
|
struct ib_global_route_header *grh = iobuf->data;
|
|
@@ -232,7 +312,7 @@ static void ipoib_complete_recv ( struct ib_device *ibdev __unused,
|
232
|
312
|
netdev_rx ( netdev, iobuf );
|
233
|
313
|
}
|
234
|
314
|
|
235
|
|
- ipoib->rx_fill--;
|
|
315
|
+ ipoib->data.recv_fill--;
|
236
|
316
|
}
|
237
|
317
|
|
238
|
318
|
/**
|
|
@@ -240,21 +320,21 @@ static void ipoib_complete_recv ( struct ib_device *ibdev __unused,
|
240
|
320
|
*
|
241
|
321
|
* @v ipoib IPoIB device
|
242
|
322
|
*/
|
243
|
|
-static void ipoib_refill_recv ( struct ipoib_device *ipoib ) {
|
|
323
|
+static void ipoib_refill_recv ( struct ipoib_device *ipoib,
|
|
324
|
+ struct ipoib_queue_set *qset ) {
|
244
|
325
|
struct ib_device *ibdev = ipoib->ibdev;
|
245
|
326
|
struct io_buffer *iobuf;
|
246
|
327
|
int rc;
|
247
|
328
|
|
248
|
|
- while ( ipoib->rx_fill < IPOIB_NUM_RECV_WQES ) {
|
|
329
|
+ while ( qset->recv_fill < qset->recv_max_fill ) {
|
249
|
330
|
iobuf = alloc_iob ( IPOIB_MTU );
|
250
|
331
|
if ( ! iobuf )
|
251
|
332
|
break;
|
252
|
|
- if ( ( rc = ib_post_recv ( ibdev, ipoib->qp,
|
253
|
|
- iobuf ) ) != 0 ) {
|
|
333
|
+ if ( ( rc = ib_post_recv ( ibdev, qset->qp, iobuf ) ) != 0 ) {
|
254
|
334
|
free_iob ( iobuf );
|
255
|
335
|
break;
|
256
|
336
|
}
|
257
|
|
- ipoib->rx_fill++;
|
|
337
|
+ qset->recv_fill++;
|
258
|
338
|
}
|
259
|
339
|
}
|
260
|
340
|
|
|
@@ -267,9 +347,9 @@ static void ipoib_poll ( struct net_device *netdev ) {
|
267
|
347
|
struct ipoib_device *ipoib = netdev->priv;
|
268
|
348
|
struct ib_device *ibdev = ipoib->ibdev;
|
269
|
349
|
|
270
|
|
- ib_poll_cq ( ibdev, ipoib->cq, ipoib_complete_send,
|
271
|
|
- ipoib_complete_recv );
|
272
|
|
- ipoib_refill_recv ( ipoib );
|
|
350
|
+ ib_poll_cq ( ibdev, ipoib->data.cq, ipoib_data_complete_send,
|
|
351
|
+ ipoib_data_complete_recv );
|
|
352
|
+ ipoib_refill_recv ( ipoib, &ipoib->data );
|
273
|
353
|
}
|
274
|
354
|
|
275
|
355
|
/**
|
|
@@ -295,7 +375,7 @@ static int ipoib_open ( struct net_device *netdev ) {
|
295
|
375
|
int rc;
|
296
|
376
|
|
297
|
377
|
/* Attach to broadcast multicast GID */
|
298
|
|
- if ( ( rc = ib_mcast_attach ( ibdev, ipoib->qp,
|
|
378
|
+ if ( ( rc = ib_mcast_attach ( ibdev, ipoib->data.qp,
|
299
|
379
|
&ibdev->broadcast_gid ) ) != 0 ) {
|
300
|
380
|
DBG ( "Could not attach to broadcast GID: %s\n",
|
301
|
381
|
strerror ( rc ) );
|
|
@@ -303,7 +383,7 @@ static int ipoib_open ( struct net_device *netdev ) {
|
303
|
383
|
}
|
304
|
384
|
|
305
|
385
|
/* Fill receive ring */
|
306
|
|
- ipoib_refill_recv ( ipoib );
|
|
386
|
+ ipoib_refill_recv ( ipoib, &ipoib->data );
|
307
|
387
|
|
308
|
388
|
return 0;
|
309
|
389
|
}
|
|
@@ -318,7 +398,7 @@ static void ipoib_close ( struct net_device *netdev ) {
|
318
|
398
|
struct ib_device *ibdev = ipoib->ibdev;
|
319
|
399
|
|
320
|
400
|
/* Detach from broadcast multicast GID */
|
321
|
|
- ib_mcast_detach ( ibdev, ipoib->qp, &ipoib_broadcast.gid );
|
|
401
|
+ ib_mcast_detach ( ibdev, ipoib->data.qp, &ipoib_broadcast.gid );
|
322
|
402
|
|
323
|
403
|
/* FIXME: should probably flush the receive ring */
|
324
|
404
|
}
|
|
@@ -353,32 +433,23 @@ int ipoib_probe ( struct ib_device *ibdev ) {
|
353
|
433
|
ib_set_ownerdata ( ibdev, netdev );
|
354
|
434
|
netdev->dev = ibdev->dev;
|
355
|
435
|
memset ( ipoib, 0, sizeof ( *ipoib ) );
|
|
436
|
+ ipoib->netdev = netdev;
|
356
|
437
|
ipoib->ibdev = ibdev;
|
357
|
438
|
|
358
|
|
- /* Allocate completion queue */
|
359
|
|
- ipoib->cq = ib_create_cq ( ibdev, IPOIB_NUM_CQES );
|
360
|
|
- if ( ! ipoib->cq ) {
|
361
|
|
- DBGC ( ipoib, "IPoIB %p could not allocate completion queue\n",
|
362
|
|
- ipoib );
|
363
|
|
- rc = -ENOMEM;
|
364
|
|
- goto err_create_cq;
|
365
|
|
- }
|
366
|
|
-
|
367
|
|
- /* Allocate queue pair */
|
368
|
|
- ipoib->qp = ib_create_qp ( ibdev, IPOIB_NUM_SEND_WQES,
|
369
|
|
- ipoib->cq, IPOIB_NUM_RECV_WQES,
|
370
|
|
- ipoib->cq, hack_ipoib_qkey );
|
371
|
|
- if ( ! ipoib->qp ) {
|
372
|
|
- DBGC ( ipoib, "IPoIB %p could not allocate queue pair\n",
|
373
|
|
- ipoib );
|
374
|
|
- rc = -ENOMEM;
|
375
|
|
- goto err_create_qp;
|
|
439
|
+ /* Allocate data queue set */
|
|
440
|
+ if ( ( rc = ipoib_create_qset ( ipoib, &ipoib->data,
|
|
441
|
+ IPOIB_DATA_NUM_CQES,
|
|
442
|
+ IPOIB_DATA_NUM_SEND_WQES,
|
|
443
|
+ IPOIB_DATA_NUM_RECV_WQES,
|
|
444
|
+ hack_ipoib_qkey ) ) != 0 ) {
|
|
445
|
+ DBGC ( ipoib, "IPoIB %p could not allocate data QP: %s\n",
|
|
446
|
+ ipoib, strerror ( rc ) );
|
|
447
|
+ goto err_create_data_qset;
|
376
|
448
|
}
|
377
|
|
- ipoib->qp->owner_priv = netdev;
|
378
|
449
|
|
379
|
450
|
/* Construct MAC address */
|
380
|
451
|
mac = ( ( struct ipoib_mac * ) netdev->ll_addr );
|
381
|
|
- mac->qpn = htonl ( ipoib->qp->qpn );
|
|
452
|
+ mac->qpn = htonl ( ipoib->data.qp->qpn );
|
382
|
453
|
memcpy ( &mac->gid, &ibdev->port_gid, sizeof ( mac->gid ) );
|
383
|
454
|
|
384
|
455
|
/* Register network device */
|
|
@@ -388,10 +459,8 @@ int ipoib_probe ( struct ib_device *ibdev ) {
|
388
|
459
|
return 0;
|
389
|
460
|
|
390
|
461
|
err_register_netdev:
|
391
|
|
- ib_destroy_qp ( ibdev, ipoib->qp );
|
392
|
|
- err_create_qp:
|
393
|
|
- ib_destroy_cq ( ibdev, ipoib->cq );
|
394
|
|
- err_create_cq:
|
|
462
|
+ ipoib_destroy_qset ( ipoib, &ipoib->data );
|
|
463
|
+ err_create_data_qset:
|
395
|
464
|
netdev_nullify ( netdev );
|
396
|
465
|
netdev_put ( netdev );
|
397
|
466
|
return rc;
|