@@ -358,6 +358,28 @@ static void rds_ib_cq_comp_handler_send(struct ib_cq *cq, void *context)
358
358
tasklet_schedule (& ic -> i_send_tasklet );
359
359
}
360
360
361
+ static inline int ibdev_get_unused_vector (struct rds_ib_device * rds_ibdev )
362
+ {
363
+ int min = rds_ibdev -> vector_load [rds_ibdev -> dev -> num_comp_vectors - 1 ];
364
+ int index = rds_ibdev -> dev -> num_comp_vectors - 1 ;
365
+ int i ;
366
+
367
+ for (i = rds_ibdev -> dev -> num_comp_vectors - 1 ; i >= 0 ; i -- ) {
368
+ if (rds_ibdev -> vector_load [i ] < min ) {
369
+ index = i ;
370
+ min = rds_ibdev -> vector_load [i ];
371
+ }
372
+ }
373
+
374
+ rds_ibdev -> vector_load [index ]++ ;
375
+ return index ;
376
+ }
377
+
378
+ static inline void ibdev_put_vector (struct rds_ib_device * rds_ibdev , int index )
379
+ {
380
+ rds_ibdev -> vector_load [index ]-- ;
381
+ }
382
+
361
383
/*
362
384
* This needs to be very careful to not leave IS_ERR pointers around for
363
385
* cleanup to trip over.
@@ -399,25 +421,30 @@ static int rds_ib_setup_qp(struct rds_connection *conn)
399
421
/* Protection domain and memory range */
400
422
ic -> i_pd = rds_ibdev -> pd ;
401
423
424
+ ic -> i_scq_vector = ibdev_get_unused_vector (rds_ibdev );
402
425
cq_attr .cqe = ic -> i_send_ring .w_nr + fr_queue_space + 1 ;
403
-
426
+ cq_attr . comp_vector = ic -> i_scq_vector ;
404
427
ic -> i_send_cq = ib_create_cq (dev , rds_ib_cq_comp_handler_send ,
405
428
rds_ib_cq_event_handler , conn ,
406
429
& cq_attr );
407
430
if (IS_ERR (ic -> i_send_cq )) {
408
431
ret = PTR_ERR (ic -> i_send_cq );
409
432
ic -> i_send_cq = NULL ;
433
+ ibdev_put_vector (rds_ibdev , ic -> i_scq_vector );
410
434
rdsdebug ("ib_create_cq send failed: %d\n" , ret );
411
435
goto out ;
412
436
}
413
437
438
+ ic -> i_rcq_vector = ibdev_get_unused_vector (rds_ibdev );
414
439
cq_attr .cqe = ic -> i_recv_ring .w_nr ;
440
+ cq_attr .comp_vector = ic -> i_rcq_vector ;
415
441
ic -> i_recv_cq = ib_create_cq (dev , rds_ib_cq_comp_handler_recv ,
416
442
rds_ib_cq_event_handler , conn ,
417
443
& cq_attr );
418
444
if (IS_ERR (ic -> i_recv_cq )) {
419
445
ret = PTR_ERR (ic -> i_recv_cq );
420
446
ic -> i_recv_cq = NULL ;
447
+ ibdev_put_vector (rds_ibdev , ic -> i_rcq_vector );
421
448
rdsdebug ("ib_create_cq recv failed: %d\n" , ret );
422
449
goto out ;
423
450
}
@@ -780,10 +807,17 @@ void rds_ib_conn_path_shutdown(struct rds_conn_path *cp)
780
807
/* first destroy the ib state that generates callbacks */
781
808
if (ic -> i_cm_id -> qp )
782
809
rdma_destroy_qp (ic -> i_cm_id );
783
- if (ic -> i_send_cq )
810
+ if (ic -> i_send_cq ) {
811
+ if (ic -> rds_ibdev )
812
+ ibdev_put_vector (ic -> rds_ibdev , ic -> i_scq_vector );
784
813
ib_destroy_cq (ic -> i_send_cq );
785
- if (ic -> i_recv_cq )
814
+ }
815
+
816
+ if (ic -> i_recv_cq ) {
817
+ if (ic -> rds_ibdev )
818
+ ibdev_put_vector (ic -> rds_ibdev , ic -> i_rcq_vector );
786
819
ib_destroy_cq (ic -> i_recv_cq );
820
+ }
787
821
788
822
/* then free the resources that ib callbacks use */
789
823
if (ic -> i_send_hdrs )
0 commit comments