summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Chan <michael.chan@broadcom.com>2020-03-09 01:45:47 +0300
committerDavid S. Miller <davem@davemloft.net>2020-03-09 07:54:46 +0300
commit54a9062f6909bed8667984c1726bce8183c72118 (patch)
tree6c41dae967347159b6ed45f6633d944779c97e20
parent138470a9b2cc2e26e6018300394afc3858a54e6a (diff)
downloadlinux-54a9062f6909bed8667984c1726bce8183c72118.tar.xz
bnxt_en: Handle all NQ notifications in bnxt_poll_p5().
In bnxt_poll_p5(), the logic polls for up to 2 completion rings (RX and TX) for work. In the current code, if we reach budget polling the first completion ring, we will stop. If the other completion ring has work to do, we will handle it when NAPI calls us back. This is not optimal. We potentially leave an unproceesed entry in the NQ. When we are finally done with NAPI polling and re-enable interrupt, the remaining entry in the NQ will cause interrupt to be triggered immediately for no reason. Modify the code in bnxt_poll_p5() to keep looping until all NQ entries are handled even if the first completion ring has reached budget. Signed-off-by: Michael Chan <michael.chan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index dee13eedde8b..0b1af02ee9da 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -2438,6 +2438,9 @@ static int bnxt_poll_p5(struct napi_struct *napi, int budget)
nqcmp = &cpr->nq_desc_ring[CP_RING(cons)][CP_IDX(cons)];
if (!NQ_CMP_VALID(nqcmp, raw_cons)) {
+ if (cpr->has_more_work)
+ break;
+
__bnxt_poll_cqs_done(bp, bnapi, DBR_TYPE_CQ_ARMALL,
false);
cpr->cp_raw_cons = raw_cons;
@@ -2459,13 +2462,11 @@ static int bnxt_poll_p5(struct napi_struct *napi, int budget)
cpr2 = cpr->cp_ring_arr[idx];
work_done += __bnxt_poll_work(bp, cpr2,
budget - work_done);
- cpr->has_more_work = cpr2->has_more_work;
+ cpr->has_more_work |= cpr2->has_more_work;
} else {
bnxt_hwrm_handler(bp, (struct tx_cmp *)nqcmp);
}
raw_cons = NEXT_RAW_CMP(raw_cons);
- if (cpr->has_more_work)
- break;
}
__bnxt_poll_cqs_done(bp, bnapi, DBR_TYPE_CQ, true);
cpr->cp_raw_cons = raw_cons;