@@ -182,7 +182,7 @@ static int create_cq(struct c4iw_rdev *rdev, struct t4_cq *cq,
182
182
return ret ;
183
183
}
184
184
185
- static void insert_recv_cqe (struct t4_wq * wq , struct t4_cq * cq )
185
+ static void insert_recv_cqe (struct t4_wq * wq , struct t4_cq * cq , u32 srqidx )
186
186
{
187
187
struct t4_cqe cqe ;
188
188
@@ -195,6 +195,8 @@ static void insert_recv_cqe(struct t4_wq *wq, struct t4_cq *cq)
195
195
CQE_SWCQE_V (1 ) |
196
196
CQE_QPID_V (wq -> sq .qid ));
197
197
cqe .bits_type_ts = cpu_to_be64 (CQE_GENBIT_V ((u64 )cq -> gen ));
198
+ if (srqidx )
199
+ cqe .u .srcqe .abs_rqe_idx = cpu_to_be32 (srqidx );
198
200
cq -> sw_queue [cq -> sw_pidx ] = cqe ;
199
201
t4_swcq_produce (cq );
200
202
}
@@ -207,7 +209,7 @@ int c4iw_flush_rq(struct t4_wq *wq, struct t4_cq *cq, int count)
207
209
pr_debug ("wq %p cq %p rq.in_use %u skip count %u\n" ,
208
210
wq , cq , wq -> rq .in_use , count );
209
211
while (in_use -- ) {
210
- insert_recv_cqe (wq , cq );
212
+ insert_recv_cqe (wq , cq , 0 );
211
213
flushed ++ ;
212
214
}
213
215
return flushed ;
@@ -458,6 +460,72 @@ void c4iw_count_rcqes(struct t4_cq *cq, struct t4_wq *wq, int *count)
458
460
pr_debug ("cq %p count %d\n" , cq , * count );
459
461
}
460
462
463
+ static void post_pending_srq_wrs (struct t4_srq * srq )
464
+ {
465
+ struct t4_srq_pending_wr * pwr ;
466
+ u16 idx = 0 ;
467
+
468
+ while (srq -> pending_in_use ) {
469
+ pwr = & srq -> pending_wrs [srq -> pending_cidx ];
470
+ srq -> sw_rq [srq -> pidx ].wr_id = pwr -> wr_id ;
471
+ srq -> sw_rq [srq -> pidx ].valid = 1 ;
472
+
473
+ pr_debug ("%s posting pending cidx %u pidx %u wq_pidx %u in_use %u rq_size %u wr_id %llx\n" ,
474
+ __func__ ,
475
+ srq -> cidx , srq -> pidx , srq -> wq_pidx ,
476
+ srq -> in_use , srq -> size ,
477
+ (unsigned long long )pwr -> wr_id );
478
+
479
+ c4iw_copy_wr_to_srq (srq , & pwr -> wqe , pwr -> len16 );
480
+ t4_srq_consume_pending_wr (srq );
481
+ t4_srq_produce (srq , pwr -> len16 );
482
+ idx += DIV_ROUND_UP (pwr -> len16 * 16 , T4_EQ_ENTRY_SIZE );
483
+ }
484
+
485
+ if (idx ) {
486
+ t4_ring_srq_db (srq , idx , pwr -> len16 , & pwr -> wqe );
487
+ srq -> queue [srq -> size ].status .host_wq_pidx =
488
+ srq -> wq_pidx ;
489
+ }
490
+ }
491
+
492
+ static u64 reap_srq_cqe (struct t4_cqe * hw_cqe , struct t4_srq * srq )
493
+ {
494
+ int rel_idx = CQE_ABS_RQE_IDX (hw_cqe ) - srq -> rqt_abs_idx ;
495
+ u64 wr_id ;
496
+
497
+ srq -> sw_rq [rel_idx ].valid = 0 ;
498
+ wr_id = srq -> sw_rq [rel_idx ].wr_id ;
499
+
500
+ if (rel_idx == srq -> cidx ) {
501
+ pr_debug ("%s in order cqe rel_idx %u cidx %u pidx %u wq_pidx %u in_use %u rq_size %u wr_id %llx\n" ,
502
+ __func__ , rel_idx , srq -> cidx , srq -> pidx ,
503
+ srq -> wq_pidx , srq -> in_use , srq -> size ,
504
+ (unsigned long long )srq -> sw_rq [rel_idx ].wr_id );
505
+ t4_srq_consume (srq );
506
+ while (srq -> ooo_count && !srq -> sw_rq [srq -> cidx ].valid ) {
507
+ pr_debug ("%s eat ooo cidx %u pidx %u wq_pidx %u in_use %u rq_size %u ooo_count %u wr_id %llx\n" ,
508
+ __func__ , srq -> cidx , srq -> pidx ,
509
+ srq -> wq_pidx , srq -> in_use ,
510
+ srq -> size , srq -> ooo_count ,
511
+ (unsigned long long )
512
+ srq -> sw_rq [srq -> cidx ].wr_id );
513
+ t4_srq_consume_ooo (srq );
514
+ }
515
+ if (srq -> ooo_count == 0 && srq -> pending_in_use )
516
+ post_pending_srq_wrs (srq );
517
+ } else {
518
+ pr_debug ("%s ooo cqe rel_idx %u cidx %u pidx %u wq_pidx %u in_use %u rq_size %u ooo_count %u wr_id %llx\n" ,
519
+ __func__ , rel_idx , srq -> cidx ,
520
+ srq -> pidx , srq -> wq_pidx ,
521
+ srq -> in_use , srq -> size ,
522
+ srq -> ooo_count ,
523
+ (unsigned long long )srq -> sw_rq [rel_idx ].wr_id );
524
+ t4_srq_produce_ooo (srq );
525
+ }
526
+ return wr_id ;
527
+ }
528
+
461
529
/*
462
530
* poll_cq
463
531
*
@@ -475,7 +543,8 @@ void c4iw_count_rcqes(struct t4_cq *cq, struct t4_wq *wq, int *count)
475
543
* -EOVERFLOW CQ overflow detected.
476
544
*/
477
545
static int poll_cq (struct t4_wq * wq , struct t4_cq * cq , struct t4_cqe * cqe ,
478
- u8 * cqe_flushed , u64 * cookie , u32 * credit )
546
+ u8 * cqe_flushed , u64 * cookie , u32 * credit ,
547
+ struct t4_srq * srq )
479
548
{
480
549
int ret = 0 ;
481
550
struct t4_cqe * hw_cqe , read_cqe ;
@@ -540,7 +609,7 @@ static int poll_cq(struct t4_wq *wq, struct t4_cq *cq, struct t4_cqe *cqe,
540
609
*/
541
610
if (CQE_TYPE (hw_cqe ) == 1 ) {
542
611
if (CQE_STATUS (hw_cqe ))
543
- t4_set_wq_in_error (wq );
612
+ t4_set_wq_in_error (wq , 0 );
544
613
ret = - EAGAIN ;
545
614
goto skip_cqe ;
546
615
}
@@ -551,7 +620,7 @@ static int poll_cq(struct t4_wq *wq, struct t4_cq *cq, struct t4_cqe *cqe,
551
620
*/
552
621
if (CQE_WRID_STAG (hw_cqe ) == 1 ) {
553
622
if (CQE_STATUS (hw_cqe ))
554
- t4_set_wq_in_error (wq );
623
+ t4_set_wq_in_error (wq , 0 );
555
624
ret = - EAGAIN ;
556
625
goto skip_cqe ;
557
626
}
@@ -576,7 +645,7 @@ static int poll_cq(struct t4_wq *wq, struct t4_cq *cq, struct t4_cqe *cqe,
576
645
577
646
if (CQE_STATUS (hw_cqe ) || t4_wq_in_error (wq )) {
578
647
* cqe_flushed = (CQE_STATUS (hw_cqe ) == T4_ERR_SWFLUSH );
579
- t4_set_wq_in_error (wq );
648
+ t4_set_wq_in_error (wq , 0 );
580
649
}
581
650
582
651
/*
@@ -590,15 +659,9 @@ static int poll_cq(struct t4_wq *wq, struct t4_cq *cq, struct t4_cqe *cqe,
590
659
* then we complete this with T4_ERR_MSN and mark the wq in
591
660
* error.
592
661
*/
593
-
594
- if (t4_rq_empty (wq )) {
595
- t4_set_wq_in_error (wq );
596
- ret = - EAGAIN ;
597
- goto skip_cqe ;
598
- }
599
662
if (unlikely (!CQE_STATUS (hw_cqe ) &&
600
663
CQE_WRID_MSN (hw_cqe ) != wq -> rq .msn )) {
601
- t4_set_wq_in_error (wq );
664
+ t4_set_wq_in_error (wq , 0 );
602
665
hw_cqe -> header |= cpu_to_be32 (CQE_STATUS_V (T4_ERR_MSN ));
603
666
}
604
667
goto proc_cqe ;
@@ -657,11 +720,16 @@ static int poll_cq(struct t4_wq *wq, struct t4_cq *cq, struct t4_cqe *cqe,
657
720
c4iw_log_wr_stats (wq , hw_cqe );
658
721
t4_sq_consume (wq );
659
722
} else {
660
- pr_debug ("completing rq idx %u\n" , wq -> rq .cidx );
661
- * cookie = wq -> rq .sw_rq [wq -> rq .cidx ].wr_id ;
662
- if (c4iw_wr_log )
663
- c4iw_log_wr_stats (wq , hw_cqe );
664
- t4_rq_consume (wq );
723
+ if (!srq ) {
724
+ pr_debug ("completing rq idx %u\n" , wq -> rq .cidx );
725
+ * cookie = wq -> rq .sw_rq [wq -> rq .cidx ].wr_id ;
726
+ if (c4iw_wr_log )
727
+ c4iw_log_wr_stats (wq , hw_cqe );
728
+ t4_rq_consume (wq );
729
+ } else {
730
+ * cookie = reap_srq_cqe (hw_cqe , srq );
731
+ }
732
+ wq -> rq .msn ++ ;
665
733
goto skip_cqe ;
666
734
}
667
735
@@ -685,7 +753,7 @@ static int poll_cq(struct t4_wq *wq, struct t4_cq *cq, struct t4_cqe *cqe,
685
753
}
686
754
687
755
static int __c4iw_poll_cq_one (struct c4iw_cq * chp , struct c4iw_qp * qhp ,
688
- struct ib_wc * wc )
756
+ struct ib_wc * wc , struct c4iw_srq * srq )
689
757
{
690
758
struct t4_cqe uninitialized_var (cqe );
691
759
struct t4_wq * wq = qhp ? & qhp -> wq : NULL ;
@@ -694,7 +762,8 @@ static int __c4iw_poll_cq_one(struct c4iw_cq *chp, struct c4iw_qp *qhp,
694
762
u64 cookie = 0 ;
695
763
int ret ;
696
764
697
- ret = poll_cq (wq , & (chp -> cq ), & cqe , & cqe_flushed , & cookie , & credit );
765
+ ret = poll_cq (wq , & (chp -> cq ), & cqe , & cqe_flushed , & cookie , & credit ,
766
+ srq ? & srq -> wq : NULL );
698
767
if (ret )
699
768
goto out ;
700
769
@@ -703,6 +772,13 @@ static int __c4iw_poll_cq_one(struct c4iw_cq *chp, struct c4iw_qp *qhp,
703
772
wc -> vendor_err = CQE_STATUS (& cqe );
704
773
wc -> wc_flags = 0 ;
705
774
775
+ /*
776
+ * Simulate a SRQ_LIMIT_REACHED HW notification if required.
777
+ */
778
+ if (srq && !(srq -> flags & T4_SRQ_LIMIT_SUPPORT ) && srq -> armed &&
779
+ srq -> wq .in_use < srq -> srq_limit )
780
+ c4iw_dispatch_srq_limit_reached_event (srq );
781
+
706
782
pr_debug ("qpid 0x%x type %d opcode %d status 0x%x len %u wrid hi 0x%x lo 0x%x cookie 0x%llx\n" ,
707
783
CQE_QPID (& cqe ),
708
784
CQE_TYPE (& cqe ), CQE_OPCODE (& cqe ),
@@ -828,6 +904,7 @@ static int __c4iw_poll_cq_one(struct c4iw_cq *chp, struct c4iw_qp *qhp,
828
904
*/
829
905
static int c4iw_poll_cq_one (struct c4iw_cq * chp , struct ib_wc * wc )
830
906
{
907
+ struct c4iw_srq * srq = NULL ;
831
908
struct c4iw_qp * qhp = NULL ;
832
909
struct t4_cqe * rd_cqe ;
833
910
int ret ;
@@ -840,10 +917,15 @@ static int c4iw_poll_cq_one(struct c4iw_cq *chp, struct ib_wc *wc)
840
917
qhp = get_qhp (chp -> rhp , CQE_QPID (rd_cqe ));
841
918
if (qhp ) {
842
919
spin_lock (& qhp -> lock );
843
- ret = __c4iw_poll_cq_one (chp , qhp , wc );
920
+ srq = qhp -> srq ;
921
+ if (srq )
922
+ spin_lock (& srq -> lock );
923
+ ret = __c4iw_poll_cq_one (chp , qhp , wc , srq );
844
924
spin_unlock (& qhp -> lock );
925
+ if (srq )
926
+ spin_unlock (& srq -> lock );
845
927
} else {
846
- ret = __c4iw_poll_cq_one (chp , NULL , wc );
928
+ ret = __c4iw_poll_cq_one (chp , NULL , wc , NULL );
847
929
}
848
930
return ret ;
849
931
}
@@ -1078,3 +1160,19 @@ int c4iw_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags)
1078
1160
spin_unlock_irqrestore (& chp -> lock , flag );
1079
1161
return ret ;
1080
1162
}
1163
+
1164
+ void c4iw_flush_srqidx (struct c4iw_qp * qhp , u32 srqidx )
1165
+ {
1166
+ struct c4iw_cq * rchp = to_c4iw_cq (qhp -> ibqp .recv_cq );
1167
+ unsigned long flag ;
1168
+
1169
+ /* locking heirarchy: cq lock first, then qp lock. */
1170
+ spin_lock_irqsave (& rchp -> lock , flag );
1171
+ spin_lock (& qhp -> lock );
1172
+
1173
+ /* create a SRQ RECV CQE for srqidx */
1174
+ insert_recv_cqe (& qhp -> wq , & rchp -> cq , srqidx );
1175
+
1176
+ spin_unlock (& qhp -> lock );
1177
+ spin_unlock_irqrestore (& rchp -> lock , flag );
1178
+ }
0 commit comments