|
@@ -151,7 +151,7 @@ static void igb_setup_dca(struct igb_adapter *);
|
|
#endif /* CONFIG_IGB_DCA */
|
|
#endif /* CONFIG_IGB_DCA */
|
|
static int igb_poll(struct napi_struct *, int);
|
|
static int igb_poll(struct napi_struct *, int);
|
|
static bool igb_clean_tx_irq(struct igb_q_vector *);
|
|
static bool igb_clean_tx_irq(struct igb_q_vector *);
|
|
-static bool igb_clean_rx_irq(struct igb_q_vector *, int);
|
|
|
|
|
|
+static int igb_clean_rx_irq(struct igb_q_vector *, int);
|
|
static int igb_ioctl(struct net_device *, struct ifreq *, int cmd);
|
|
static int igb_ioctl(struct net_device *, struct ifreq *, int cmd);
|
|
static void igb_tx_timeout(struct net_device *);
|
|
static void igb_tx_timeout(struct net_device *);
|
|
static void igb_reset_task(struct work_struct *);
|
|
static void igb_reset_task(struct work_struct *);
|
|
@@ -6364,6 +6364,7 @@ static int igb_poll(struct napi_struct *napi, int budget)
|
|
struct igb_q_vector,
|
|
struct igb_q_vector,
|
|
napi);
|
|
napi);
|
|
bool clean_complete = true;
|
|
bool clean_complete = true;
|
|
|
|
+ int work_done = 0;
|
|
|
|
|
|
#ifdef CONFIG_IGB_DCA
|
|
#ifdef CONFIG_IGB_DCA
|
|
if (q_vector->adapter->flags & IGB_FLAG_DCA_ENABLED)
|
|
if (q_vector->adapter->flags & IGB_FLAG_DCA_ENABLED)
|
|
@@ -6372,15 +6373,19 @@ static int igb_poll(struct napi_struct *napi, int budget)
|
|
if (q_vector->tx.ring)
|
|
if (q_vector->tx.ring)
|
|
clean_complete = igb_clean_tx_irq(q_vector);
|
|
clean_complete = igb_clean_tx_irq(q_vector);
|
|
|
|
|
|
- if (q_vector->rx.ring)
|
|
|
|
- clean_complete &= igb_clean_rx_irq(q_vector, budget);
|
|
|
|
|
|
+ if (q_vector->rx.ring) {
|
|
|
|
+ int cleaned = igb_clean_rx_irq(q_vector, budget);
|
|
|
|
+
|
|
|
|
+ work_done += cleaned;
|
|
|
|
+ clean_complete &= (cleaned < budget);
|
|
|
|
+ }
|
|
|
|
|
|
/* If all work not completed, return budget and keep polling */
|
|
/* If all work not completed, return budget and keep polling */
|
|
if (!clean_complete)
|
|
if (!clean_complete)
|
|
return budget;
|
|
return budget;
|
|
|
|
|
|
/* If not enough Rx work done, exit the polling mode */
|
|
/* If not enough Rx work done, exit the polling mode */
|
|
- napi_complete(napi);
|
|
|
|
|
|
+ napi_complete_done(napi, work_done);
|
|
igb_ring_irq_enable(q_vector);
|
|
igb_ring_irq_enable(q_vector);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
@@ -6904,7 +6909,7 @@ static void igb_process_skb_fields(struct igb_ring *rx_ring,
|
|
skb->protocol = eth_type_trans(skb, rx_ring->netdev);
|
|
skb->protocol = eth_type_trans(skb, rx_ring->netdev);
|
|
}
|
|
}
|
|
|
|
|
|
-static bool igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget)
|
|
|
|
|
|
+static int igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget)
|
|
{
|
|
{
|
|
struct igb_ring *rx_ring = q_vector->rx.ring;
|
|
struct igb_ring *rx_ring = q_vector->rx.ring;
|
|
struct sk_buff *skb = rx_ring->skb;
|
|
struct sk_buff *skb = rx_ring->skb;
|
|
@@ -6978,7 +6983,7 @@ static bool igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget)
|
|
if (cleaned_count)
|
|
if (cleaned_count)
|
|
igb_alloc_rx_buffers(rx_ring, cleaned_count);
|
|
igb_alloc_rx_buffers(rx_ring, cleaned_count);
|
|
|
|
|
|
- return total_packets < budget;
|
|
|
|
|
|
+ return total_packets;
|
|
}
|
|
}
|
|
|
|
|
|
static bool igb_alloc_mapped_page(struct igb_ring *rx_ring,
|
|
static bool igb_alloc_mapped_page(struct igb_ring *rx_ring,
|