gve: Switch to use napi_complete_done
Use napi_complete_done to allow for the use of gro_flush_timeout. Fixes: f5cedc84a30d2 ("gve: Add transmit and receive support") Signed-off-by: Yangchun Fu <yangchun@google.com> Signed-off-by: Catherine Sullivan <csully@google.com> Signed-off-by: David Awogbemila <awogbemila@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
ce8bd03c47
commit
2cb67ab153
@ -825,11 +825,10 @@ __be32 gve_tx_load_event_counter(struct gve_priv *priv,
|
||||
struct gve_tx_ring *tx);
|
||||
/* rx handling */
|
||||
void gve_rx_write_doorbell(struct gve_priv *priv, struct gve_rx_ring *rx);
|
||||
bool gve_rx_poll(struct gve_notify_block *block, int budget);
|
||||
int gve_rx_poll(struct gve_notify_block *block, int budget);
|
||||
bool gve_rx_work_pending(struct gve_rx_ring *rx);
|
||||
int gve_rx_alloc_rings(struct gve_priv *priv);
|
||||
void gve_rx_free_rings_gqi(struct gve_priv *priv);
|
||||
bool gve_clean_rx_done(struct gve_rx_ring *rx, int budget,
|
||||
netdev_features_t feat);
|
||||
/* Reset */
|
||||
void gve_schedule_reset(struct gve_priv *priv);
|
||||
int gve_reset(struct gve_priv *priv, bool attempt_teardown);
|
||||
|
@ -192,34 +192,40 @@ static int gve_napi_poll(struct napi_struct *napi, int budget)
|
||||
__be32 __iomem *irq_doorbell;
|
||||
bool reschedule = false;
|
||||
struct gve_priv *priv;
|
||||
int work_done = 0;
|
||||
|
||||
block = container_of(napi, struct gve_notify_block, napi);
|
||||
priv = block->priv;
|
||||
|
||||
if (block->tx)
|
||||
reschedule |= gve_tx_poll(block, budget);
|
||||
if (block->rx)
|
||||
reschedule |= gve_rx_poll(block, budget);
|
||||
if (block->rx) {
|
||||
work_done = gve_rx_poll(block, budget);
|
||||
reschedule |= work_done == budget;
|
||||
}
|
||||
|
||||
if (reschedule)
|
||||
return budget;
|
||||
|
||||
napi_complete(napi);
|
||||
irq_doorbell = gve_irq_doorbell(priv, block);
|
||||
iowrite32be(GVE_IRQ_ACK | GVE_IRQ_EVENT, irq_doorbell);
|
||||
/* Complete processing - don't unmask irq if busy polling is enabled */
|
||||
if (likely(napi_complete_done(napi, work_done))) {
|
||||
irq_doorbell = gve_irq_doorbell(priv, block);
|
||||
iowrite32be(GVE_IRQ_ACK | GVE_IRQ_EVENT, irq_doorbell);
|
||||
|
||||
/* Double check we have no extra work.
|
||||
* Ensure unmask synchronizes with checking for work.
|
||||
*/
|
||||
mb();
|
||||
if (block->tx)
|
||||
reschedule |= gve_tx_poll(block, -1);
|
||||
if (block->rx)
|
||||
reschedule |= gve_rx_poll(block, -1);
|
||||
if (reschedule && napi_reschedule(napi))
|
||||
iowrite32be(GVE_IRQ_MASK, irq_doorbell);
|
||||
/* Double check we have no extra work.
|
||||
* Ensure unmask synchronizes with checking for work.
|
||||
*/
|
||||
mb();
|
||||
|
||||
return 0;
|
||||
if (block->tx)
|
||||
reschedule |= gve_tx_poll(block, -1);
|
||||
if (block->rx)
|
||||
reschedule |= gve_rx_work_pending(block->rx);
|
||||
|
||||
if (reschedule && napi_reschedule(napi))
|
||||
iowrite32be(GVE_IRQ_MASK, irq_doorbell);
|
||||
}
|
||||
return work_done;
|
||||
}
|
||||
|
||||
static int gve_napi_poll_dqo(struct napi_struct *napi, int budget)
|
||||
|
@ -456,7 +456,7 @@ static bool gve_rx(struct gve_rx_ring *rx, struct gve_rx_desc *rx_desc,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool gve_rx_work_pending(struct gve_rx_ring *rx)
|
||||
bool gve_rx_work_pending(struct gve_rx_ring *rx)
|
||||
{
|
||||
struct gve_rx_desc *desc;
|
||||
__be16 flags_seq;
|
||||
@ -524,8 +524,8 @@ static bool gve_rx_refill_buffers(struct gve_priv *priv, struct gve_rx_ring *rx)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool gve_clean_rx_done(struct gve_rx_ring *rx, int budget,
|
||||
netdev_features_t feat)
|
||||
static int gve_clean_rx_done(struct gve_rx_ring *rx, int budget,
|
||||
netdev_features_t feat)
|
||||
{
|
||||
struct gve_priv *priv = rx->gve;
|
||||
u32 work_done = 0, packets = 0;
|
||||
@ -559,13 +559,15 @@ bool gve_clean_rx_done(struct gve_rx_ring *rx, int budget,
|
||||
}
|
||||
|
||||
if (!work_done && rx->fill_cnt - cnt > rx->db_threshold)
|
||||
return false;
|
||||
return 0;
|
||||
|
||||
u64_stats_update_begin(&rx->statss);
|
||||
rx->rpackets += packets;
|
||||
rx->rbytes += bytes;
|
||||
u64_stats_update_end(&rx->statss);
|
||||
rx->cnt = cnt;
|
||||
if (work_done) {
|
||||
u64_stats_update_begin(&rx->statss);
|
||||
rx->rpackets += packets;
|
||||
rx->rbytes += bytes;
|
||||
u64_stats_update_end(&rx->statss);
|
||||
rx->cnt = cnt;
|
||||
}
|
||||
|
||||
/* restock ring slots */
|
||||
if (!rx->data.raw_addressing) {
|
||||
@ -576,26 +578,26 @@ bool gve_clean_rx_done(struct gve_rx_ring *rx, int budget,
|
||||
* falls below a threshold.
|
||||
*/
|
||||
if (!gve_rx_refill_buffers(priv, rx))
|
||||
return false;
|
||||
return 0;
|
||||
|
||||
/* If we were not able to completely refill buffers, we'll want
|
||||
* to schedule this queue for work again to refill buffers.
|
||||
*/
|
||||
if (rx->fill_cnt - cnt <= rx->db_threshold) {
|
||||
gve_rx_write_doorbell(priv, rx);
|
||||
return true;
|
||||
return budget;
|
||||
}
|
||||
}
|
||||
|
||||
gve_rx_write_doorbell(priv, rx);
|
||||
return gve_rx_work_pending(rx);
|
||||
return work_done;
|
||||
}
|
||||
|
||||
bool gve_rx_poll(struct gve_notify_block *block, int budget)
|
||||
int gve_rx_poll(struct gve_notify_block *block, int budget)
|
||||
{
|
||||
struct gve_rx_ring *rx = block->rx;
|
||||
netdev_features_t feat;
|
||||
bool repoll = false;
|
||||
int work_done = 0;
|
||||
|
||||
feat = block->napi.dev->features;
|
||||
|
||||
@ -604,8 +606,7 @@ bool gve_rx_poll(struct gve_notify_block *block, int budget)
|
||||
budget = INT_MAX;
|
||||
|
||||
if (budget > 0)
|
||||
repoll |= gve_clean_rx_done(rx, budget, feat);
|
||||
else
|
||||
repoll |= gve_rx_work_pending(rx);
|
||||
return repoll;
|
||||
work_done = gve_clean_rx_done(rx, budget, feat);
|
||||
|
||||
return work_done;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user