mirror of https://gitee.com/openkylin/linux.git
qede: qede_poll refactoring
This patch cleanups qede_poll() routine a bit and allows qede_poll() to do single iteration to handle TX completion [As under heavy TX load qede_poll() might run for indefinite time in the while(1) loop for TX completion processing and cause CPU stuck]. Signed-off-by: Manish <manish.chopra@qlogic.com> Signed-off-by: Yuval Mintz <Yuval.Mintz@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
c72a6125d0
commit
c774169d8f
|
@ -1597,56 +1597,49 @@ static int qede_rx_int(struct qede_fastpath *fp, int budget)
|
|||
|
||||
static int qede_poll(struct napi_struct *napi, int budget)
|
||||
{
|
||||
int work_done = 0;
|
||||
struct qede_fastpath *fp = container_of(napi, struct qede_fastpath,
|
||||
napi);
|
||||
napi);
|
||||
struct qede_dev *edev = fp->edev;
|
||||
int rx_work_done = 0;
|
||||
u8 tc;
|
||||
|
||||
while (1) {
|
||||
u8 tc;
|
||||
for (tc = 0; tc < edev->num_tc; tc++)
|
||||
if (qede_txq_has_work(&fp->txqs[tc]))
|
||||
qede_tx_int(edev, &fp->txqs[tc]);
|
||||
|
||||
for (tc = 0; tc < edev->num_tc; tc++)
|
||||
if (qede_txq_has_work(&fp->txqs[tc]))
|
||||
qede_tx_int(edev, &fp->txqs[tc]);
|
||||
|
||||
if (qede_has_rx_work(fp->rxq)) {
|
||||
work_done += qede_rx_int(fp, budget - work_done);
|
||||
|
||||
/* must not complete if we consumed full budget */
|
||||
if (work_done >= budget)
|
||||
break;
|
||||
}
|
||||
rx_work_done = qede_has_rx_work(fp->rxq) ?
|
||||
qede_rx_int(fp, budget) : 0;
|
||||
if (rx_work_done < budget) {
|
||||
qed_sb_update_sb_idx(fp->sb_info);
|
||||
/* *_has_*_work() reads the status block,
|
||||
* thus we need to ensure that status block indices
|
||||
* have been actually read (qed_sb_update_sb_idx)
|
||||
* prior to this check (*_has_*_work) so that
|
||||
* we won't write the "newer" value of the status block
|
||||
* to HW (if there was a DMA right after
|
||||
* qede_has_rx_work and if there is no rmb, the memory
|
||||
* reading (qed_sb_update_sb_idx) may be postponed
|
||||
* to right before *_ack_sb). In this case there
|
||||
* will never be another interrupt until there is
|
||||
* another update of the status block, while there
|
||||
* is still unhandled work.
|
||||
*/
|
||||
rmb();
|
||||
|
||||
/* Fall out from the NAPI loop if needed */
|
||||
if (!(qede_has_rx_work(fp->rxq) || qede_has_tx_work(fp))) {
|
||||
qed_sb_update_sb_idx(fp->sb_info);
|
||||
/* *_has_*_work() reads the status block,
|
||||
* thus we need to ensure that status block indices
|
||||
* have been actually read (qed_sb_update_sb_idx)
|
||||
* prior to this check (*_has_*_work) so that
|
||||
* we won't write the "newer" value of the status block
|
||||
* to HW (if there was a DMA right after
|
||||
* qede_has_rx_work and if there is no rmb, the memory
|
||||
* reading (qed_sb_update_sb_idx) may be postponed
|
||||
* to right before *_ack_sb). In this case there
|
||||
* will never be another interrupt until there is
|
||||
* another update of the status block, while there
|
||||
* is still unhandled work.
|
||||
*/
|
||||
rmb();
|
||||
if (!(qede_has_rx_work(fp->rxq) ||
|
||||
qede_has_tx_work(fp))) {
|
||||
napi_complete(napi);
|
||||
|
||||
if (!(qede_has_rx_work(fp->rxq) ||
|
||||
qede_has_tx_work(fp))) {
|
||||
napi_complete(napi);
|
||||
/* Update and reenable interrupts */
|
||||
qed_sb_ack(fp->sb_info, IGU_INT_ENABLE,
|
||||
1 /*update*/);
|
||||
break;
|
||||
}
|
||||
/* Update and reenable interrupts */
|
||||
qed_sb_ack(fp->sb_info, IGU_INT_ENABLE,
|
||||
1 /*update*/);
|
||||
} else {
|
||||
rx_work_done = budget;
|
||||
}
|
||||
}
|
||||
|
||||
return work_done;
|
||||
return rx_work_done;
|
||||
}
|
||||
|
||||
static irqreturn_t qede_msix_fp_int(int irq, void *fp_cookie)
|
||||
|
|
Loading…
Reference in New Issue