@@ -15,6 +15,10 @@ static void ionic_rx_clean(struct ionic_queue *q,
15
15
struct ionic_cq_info * cq_info ,
16
16
void * cb_arg );
17
17
18
+ static bool ionic_rx_service (struct ionic_cq * cq , struct ionic_cq_info * cq_info );
19
+
20
+ static bool ionic_tx_service (struct ionic_cq * cq , struct ionic_cq_info * cq_info );
21
+
18
22
static inline void ionic_txq_post (struct ionic_queue * q , bool ring_dbell ,
19
23
ionic_desc_cb cb_func , void * cb_arg )
20
24
{
@@ -249,29 +253,13 @@ static bool ionic_rx_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info)
249
253
return true;
250
254
}
251
255
252
- static u32 ionic_rx_walk_cq (struct ionic_cq * rxcq , u32 limit )
253
- {
254
- u32 work_done = 0 ;
255
-
256
- while (ionic_rx_service (rxcq , rxcq -> tail )) {
257
- if (rxcq -> tail -> last )
258
- rxcq -> done_color = !rxcq -> done_color ;
259
- rxcq -> tail = rxcq -> tail -> next ;
260
- DEBUG_STATS_CQE_CNT (rxcq );
261
-
262
- if (++ work_done >= limit )
263
- break ;
264
- }
265
-
266
- return work_done ;
267
- }
268
-
269
256
void ionic_rx_flush (struct ionic_cq * cq )
270
257
{
271
258
struct ionic_dev * idev = & cq -> lif -> ionic -> idev ;
272
259
u32 work_done ;
273
260
274
- work_done = ionic_rx_walk_cq (cq , cq -> num_descs );
261
+ work_done = ionic_cq_service (cq , cq -> num_descs ,
262
+ ionic_rx_service , NULL , NULL );
275
263
276
264
if (work_done )
277
265
ionic_intr_credits (idev -> intr_ctrl , cq -> bound_intr -> index ,
@@ -439,32 +427,42 @@ int ionic_rx_napi(struct napi_struct *napi, int budget)
439
427
struct ionic_dev * idev ;
440
428
struct ionic_lif * lif ;
441
429
struct ionic_cq * txcq ;
430
+ u32 rx_work_done = 0 ;
431
+ u32 tx_work_done = 0 ;
442
432
u32 work_done = 0 ;
443
433
u32 flags = 0 ;
434
+ bool unmask ;
444
435
445
436
lif = rxcq -> bound_q -> lif ;
446
437
idev = & lif -> ionic -> idev ;
447
438
txcq = & lif -> txqcqs [qi ].qcq -> cq ;
448
439
449
- ionic_tx_flush (txcq );
450
-
451
- work_done = ionic_rx_walk_cq (rxcq , budget );
440
+ tx_work_done = ionic_cq_service (txcq , lif -> tx_budget ,
441
+ ionic_tx_service , NULL , NULL );
452
442
453
- if (work_done )
443
+ rx_work_done = ionic_cq_service (rxcq , budget ,
444
+ ionic_rx_service , NULL , NULL );
445
+ if (rx_work_done )
454
446
ionic_rx_fill_cb (rxcq -> bound_q );
455
447
456
- if (work_done < budget && napi_complete_done (napi , work_done )) {
448
+ unmask = (rx_work_done < budget ) && (tx_work_done < lif -> tx_budget );
449
+
450
+ if (unmask && napi_complete_done (napi , rx_work_done )) {
457
451
flags |= IONIC_INTR_CRED_UNMASK ;
458
452
DEBUG_STATS_INTR_REARM (rxcq -> bound_intr );
453
+ work_done = rx_work_done ;
454
+ } else {
455
+ work_done = budget ;
459
456
}
460
457
461
458
if (work_done || flags ) {
462
459
flags |= IONIC_INTR_CRED_RESET_COALESCE ;
463
460
ionic_intr_credits (idev -> intr_ctrl , rxcq -> bound_intr -> index ,
464
- work_done , flags );
461
+ tx_work_done + rx_work_done , flags );
465
462
}
466
463
467
- DEBUG_STATS_NAPI_POLL (qcq , work_done );
464
+ DEBUG_STATS_NAPI_POLL (qcq , rx_work_done );
465
+ DEBUG_STATS_NAPI_POLL (qcq , tx_work_done );
468
466
469
467
return work_done ;
470
468
}
@@ -552,43 +550,39 @@ static void ionic_tx_clean(struct ionic_queue *q,
552
550
}
553
551
}
554
552
555
- void ionic_tx_flush (struct ionic_cq * cq )
553
+ static bool ionic_tx_service (struct ionic_cq * cq , struct ionic_cq_info * cq_info )
556
554
{
557
- struct ionic_txq_comp * comp = cq -> tail -> cq_desc ;
558
- struct ionic_dev * idev = & cq -> lif -> ionic -> idev ;
555
+ struct ionic_txq_comp * comp = cq_info -> cq_desc ;
559
556
struct ionic_queue * q = cq -> bound_q ;
560
557
struct ionic_desc_info * desc_info ;
561
- unsigned int work_done = 0 ;
562
-
563
- /* walk the completed cq entries */
564
- while (work_done < cq -> num_descs &&
565
- color_match (comp -> color , cq -> done_color )) {
566
-
567
- /* clean the related q entries, there could be
568
- * several q entries completed for each cq completion
569
- */
570
- do {
571
- desc_info = q -> tail ;
572
- q -> tail = desc_info -> next ;
573
- ionic_tx_clean (q , desc_info , cq -> tail ,
574
- desc_info -> cb_arg );
575
- desc_info -> cb = NULL ;
576
- desc_info -> cb_arg = NULL ;
577
- } while (desc_info -> index != le16_to_cpu (comp -> comp_index ));
578
-
579
- if (cq -> tail -> last )
580
- cq -> done_color = !cq -> done_color ;
581
-
582
- cq -> tail = cq -> tail -> next ;
583
- comp = cq -> tail -> cq_desc ;
584
- DEBUG_STATS_CQE_CNT (cq );
585
-
586
- work_done ++ ;
587
- }
588
558
559
+ if (!color_match (comp -> color , cq -> done_color ))
560
+ return false;
561
+
562
+ /* clean the related q entries, there could be
563
+ * several q entries completed for each cq completion
564
+ */
565
+ do {
566
+ desc_info = q -> tail ;
567
+ q -> tail = desc_info -> next ;
568
+ ionic_tx_clean (q , desc_info , cq -> tail , desc_info -> cb_arg );
569
+ desc_info -> cb = NULL ;
570
+ desc_info -> cb_arg = NULL ;
571
+ } while (desc_info -> index != le16_to_cpu (comp -> comp_index ));
572
+
573
+ return true;
574
+ }
575
+
576
+ void ionic_tx_flush (struct ionic_cq * cq )
577
+ {
578
+ struct ionic_dev * idev = & cq -> lif -> ionic -> idev ;
579
+ u32 work_done ;
580
+
581
+ work_done = ionic_cq_service (cq , cq -> num_descs ,
582
+ ionic_tx_service , NULL , NULL );
589
583
if (work_done )
590
584
ionic_intr_credits (idev -> intr_ctrl , cq -> bound_intr -> index ,
591
- work_done , 0 );
585
+ work_done , IONIC_INTR_CRED_RESET_COALESCE );
592
586
}
593
587
594
588
void ionic_tx_empty (struct ionic_queue * q )
0 commit comments