提交 b647d398 编写于 作者: I Igor Russkikh 提交者: David S. Miller

net: aquantia: Add tx clean budget and valid budget handling logic

We should report to napi full budget only when we have more job to do.
Before this fix, on any tx queue cleanup we forced napi to do poll again.
Thats a waste of cpu resources and caused storming with napi polls when
there was at least one tx on each interrupt.

With this fix we report full budget only when there is more job on TX
to do. Or, as before, when rx budget was fully consumed.
Signed-off-by: NIgor Russkikh <igor.russkikh@aquantia.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 47203b34
...@@ -36,6 +36,8 @@ ...@@ -36,6 +36,8 @@
#define AQ_CFG_TX_FRAME_MAX (16U * 1024U) #define AQ_CFG_TX_FRAME_MAX (16U * 1024U)
#define AQ_CFG_RX_FRAME_MAX (4U * 1024U) #define AQ_CFG_RX_FRAME_MAX (4U * 1024U)
#define AQ_CFG_TX_CLEAN_BUDGET 256U
/* LRO */ /* LRO */
#define AQ_CFG_IS_LRO_DEF 1U #define AQ_CFG_IS_LRO_DEF 1U
......
...@@ -136,11 +136,12 @@ void aq_ring_queue_stop(struct aq_ring_s *ring) ...@@ -136,11 +136,12 @@ void aq_ring_queue_stop(struct aq_ring_s *ring)
netif_stop_subqueue(ndev, ring->idx); netif_stop_subqueue(ndev, ring->idx);
} }
void aq_ring_tx_clean(struct aq_ring_s *self) bool aq_ring_tx_clean(struct aq_ring_s *self)
{ {
struct device *dev = aq_nic_get_dev(self->aq_nic); struct device *dev = aq_nic_get_dev(self->aq_nic);
unsigned int budget = AQ_CFG_TX_CLEAN_BUDGET;
for (; self->sw_head != self->hw_head; for (; self->sw_head != self->hw_head && budget--;
self->sw_head = aq_ring_next_dx(self, self->sw_head)) { self->sw_head = aq_ring_next_dx(self, self->sw_head)) {
struct aq_ring_buff_s *buff = &self->buff_ring[self->sw_head]; struct aq_ring_buff_s *buff = &self->buff_ring[self->sw_head];
...@@ -167,6 +168,8 @@ void aq_ring_tx_clean(struct aq_ring_s *self) ...@@ -167,6 +168,8 @@ void aq_ring_tx_clean(struct aq_ring_s *self)
buff->pa = 0U; buff->pa = 0U;
buff->eop_index = 0xffffU; buff->eop_index = 0xffffU;
} }
return !!budget;
} }
#define AQ_SKB_ALIGN SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) #define AQ_SKB_ALIGN SKB_DATA_ALIGN(sizeof(struct skb_shared_info))
......
...@@ -153,7 +153,7 @@ void aq_ring_free(struct aq_ring_s *self); ...@@ -153,7 +153,7 @@ void aq_ring_free(struct aq_ring_s *self);
void aq_ring_update_queue_state(struct aq_ring_s *ring); void aq_ring_update_queue_state(struct aq_ring_s *ring);
void aq_ring_queue_wake(struct aq_ring_s *ring); void aq_ring_queue_wake(struct aq_ring_s *ring);
void aq_ring_queue_stop(struct aq_ring_s *ring); void aq_ring_queue_stop(struct aq_ring_s *ring);
void aq_ring_tx_clean(struct aq_ring_s *self); bool aq_ring_tx_clean(struct aq_ring_s *self);
int aq_ring_rx_clean(struct aq_ring_s *self, int aq_ring_rx_clean(struct aq_ring_s *self,
struct napi_struct *napi, struct napi_struct *napi,
int *work_done, int *work_done,
......
...@@ -35,12 +35,12 @@ struct aq_vec_s { ...@@ -35,12 +35,12 @@ struct aq_vec_s {
static int aq_vec_poll(struct napi_struct *napi, int budget) static int aq_vec_poll(struct napi_struct *napi, int budget)
{ {
struct aq_vec_s *self = container_of(napi, struct aq_vec_s, napi); struct aq_vec_s *self = container_of(napi, struct aq_vec_s, napi);
unsigned int sw_tail_old = 0U;
struct aq_ring_s *ring = NULL; struct aq_ring_s *ring = NULL;
bool was_tx_cleaned = true;
unsigned int i = 0U;
int work_done = 0; int work_done = 0;
int err = 0; int err = 0;
unsigned int i = 0U;
unsigned int sw_tail_old = 0U;
bool was_tx_cleaned = false;
if (!self) { if (!self) {
err = -EINVAL; err = -EINVAL;
...@@ -57,9 +57,8 @@ static int aq_vec_poll(struct napi_struct *napi, int budget) ...@@ -57,9 +57,8 @@ static int aq_vec_poll(struct napi_struct *napi, int budget)
if (ring[AQ_VEC_TX_ID].sw_head != if (ring[AQ_VEC_TX_ID].sw_head !=
ring[AQ_VEC_TX_ID].hw_head) { ring[AQ_VEC_TX_ID].hw_head) {
aq_ring_tx_clean(&ring[AQ_VEC_TX_ID]); was_tx_cleaned = aq_ring_tx_clean(&ring[AQ_VEC_TX_ID]);
aq_ring_update_queue_state(&ring[AQ_VEC_TX_ID]); aq_ring_update_queue_state(&ring[AQ_VEC_TX_ID]);
was_tx_cleaned = true;
} }
err = self->aq_hw_ops->hw_ring_rx_receive(self->aq_hw, err = self->aq_hw_ops->hw_ring_rx_receive(self->aq_hw,
...@@ -90,7 +89,7 @@ static int aq_vec_poll(struct napi_struct *napi, int budget) ...@@ -90,7 +89,7 @@ static int aq_vec_poll(struct napi_struct *napi, int budget)
} }
} }
if (was_tx_cleaned) if (!was_tx_cleaned)
work_done = budget; work_done = budget;
if (work_done < budget) { if (work_done < budget) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册