From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-iy0-f171.google.com (mail-iy0-f171.google.com [209.85.210.171]) (using TLSv1 with cipher RC4-SHA (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority" (verified OK)) by huchra.bufferbloat.net (Postfix) with ESMTPS id 7AD6D2003E0 for ; Sat, 17 Sep 2011 10:10:45 -0700 (PDT) Received: by iagv1 with SMTP id v1so6270338iag.16 for ; Sat, 17 Sep 2011 10:10:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; bh=JvKaF7zk+xXLV8qXfba0zbcMNWm5CQo2d9PQPjLVgZA=; b=tMfXLdJdSQdJmC8F7CgNfKQBgN5gtyNrIPOG7xDLMeypDnDMH5pn9beZw4ICeWhmCr PUooVUaRbLT1/+ivQN9JOEfX1ISXUJJ1sOB9xKyi0qEIv1HJsI1ggwmnjRpbK1EsmOYP WqywjL+NNhXEtK40m8Y/BTWoxj/4GFg2vutmk= MIME-Version: 1.0 Received: by 10.42.19.72 with SMTP id a8mr1171472icb.41.1316279444512; Sat, 17 Sep 2011 10:10:44 -0700 (PDT) Received: by 10.43.133.129 with HTTP; Sat, 17 Sep 2011 10:10:44 -0700 (PDT) In-Reply-To: <1316246677-8830-12-git-send-email-jeffrey.t.kirsher@intel.com> References: <1316246677-8830-1-git-send-email-jeffrey.t.kirsher@intel.com> <1316246677-8830-12-git-send-email-jeffrey.t.kirsher@intel.com> Date: Sat, 17 Sep 2011 10:10:44 -0700 Message-ID: Subject: Fwd: [net-next 11/13] igb: Make Tx budget for NAPI user adjustable From: Dave Taht To: bloat-devel Content-Type: multipart/alternative; boundary=20cf3040ee52b71fc004ad263007 X-BeenThere: bloat-devel@lists.bufferbloat.net X-Mailman-Version: 2.1.13 Precedence: list List-Id: "Developers working on AQM, device drivers, and networking stacks" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 17 Sep 2011 17:10:45 -0000 --20cf3040ee52b71fc004ad263007 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable I am encouraged... more discussion on the netdev list... ---------- Forwarded message ---------- From: Jeff Kirsher Date: Sat, Sep 17, 2011 at 1:04 AM Subject: [net-next 11/13] igb: Make Tx budget for NAPI user adjustable To: davem@davemloft.net Cc: Alexander Duyck , netdev@vger.kernel.org, gospo@redhat.com, Jeff Kirsher From: Alexander Duyck This change is meant to make the NAPI budget limits for transmit adjustable. By doing this it is possible to tune the value for optimal performance with applications such as routing. Signed-off-by: Alexander Duyck Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/igb/igb.h | 3 + drivers/net/ethernet/intel/igb/igb_ethtool.c | 6 + drivers/net/ethernet/intel/igb/igb_main.c | 136 ++++++++++++++++---------- 3 files changed, 92 insertions(+), 53 deletions(-) diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h index b725937..cfa590c8 100644 --- a/drivers/net/ethernet/intel/igb/igb.h +++ b/drivers/net/ethernet/intel/igb/igb.h @@ -47,6 +47,7 @@ struct igb_adapter; /* TX/RX descriptor defines */ #define IGB_DEFAULT_TXD 256 +#define IXGBE_DEFAULT_TX_WORK 128 #define IGB_MIN_TXD 80 #define IGB_MAX_TXD 4096 @@ -177,6 +178,7 @@ struct igb_q_vector { u32 eims_value; u16 cpu; + u16 tx_work_limit; u16 itr_val; u8 set_itr; @@ -266,6 +268,7 @@ struct igb_adapter { u16 rx_itr; /* TX */ + u16 tx_work_limit; u32 tx_timeout_count; int num_tx_queues; struct igb_ring *tx_ring[16]; diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c index f231d82..f6da820 100644 --- a/drivers/net/ethernet/intel/igb/igb_ethtool.c +++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c @@ -1989,6 +1989,9 @@ static int igb_set_coalesce(struct net_device *netdev= , if ((adapter->flags & IGB_FLAG_QUEUE_PAIRS) && ec->tx_coalesce_usecs= ) return -EINVAL; + if (ec->tx_max_coalesced_frames_irq) + adapter->tx_work_limit =3D ec->tx_max_coalesced_frames_irq; + /* If ITR is disabled, disable DMAC */ if (ec->rx_coalesce_usecs =3D=3D 0) { if (adapter->flags & IGB_FLAG_DMAC) @@ -2011,6 +2014,7 @@ static int igb_set_coalesce(struct net_device *netdev= , for (i =3D 0; i < adapter->num_q_vectors; i++) { struct igb_q_vector *q_vector =3D adapter->q_vector[i]; + q_vector->tx_work_limit =3D adapter->tx_work_limit; if (q_vector->rx_ring) q_vector->itr_val =3D adapter->rx_itr_setting; else @@ -2033,6 +2037,8 @@ static int igb_get_coalesce(struct net_device *netdev= , else ec->rx_coalesce_usecs =3D adapter->rx_itr_setting >> 2; + ec->tx_max_coalesced_frames_irq =3D adapter->tx_work_limit; + if (!(adapter->flags & IGB_FLAG_QUEUE_PAIRS)) { if (adapter->tx_itr_setting <=3D 3) ec->tx_coalesce_usecs =3D adapter->tx_itr_setting; diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 7ad25e8..989e774 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -136,8 +136,8 @@ static irqreturn_t igb_msix_ring(int irq, void *); static void igb_update_dca(struct igb_q_vector *); static void igb_setup_dca(struct igb_adapter *); #endif /* CONFIG_IGB_DCA */ -static bool igb_clean_tx_irq(struct igb_q_vector *); static int igb_poll(struct napi_struct *, int); +static bool igb_clean_tx_irq(struct igb_q_vector *); static bool igb_clean_rx_irq(struct igb_q_vector *, int); static int igb_ioctl(struct net_device *, struct ifreq *, int cmd); static void igb_tx_timeout(struct net_device *); @@ -1120,6 +1120,7 @@ static void igb_map_tx_ring_to_vector(struct igb_adapter *adapter, q_vector->tx_ring =3D adapter->tx_ring[ring_idx]; q_vector->tx_ring->q_vector =3D q_vector; q_vector->itr_val =3D adapter->tx_itr_setting; + q_vector->tx_work_limit =3D adapter->tx_work_limit; if (q_vector->itr_val && q_vector->itr_val <=3D 3) q_vector->itr_val =3D IGB_START_ITR; } @@ -2388,11 +2389,17 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter) pci_read_config_word(pdev, PCI_COMMAND, &hw->bus.pci_cmd_word); + /* set default ring sizes */ adapter->tx_ring_count =3D IGB_DEFAULT_TXD; adapter->rx_ring_count =3D IGB_DEFAULT_RXD; + + /* set default ITR values */ adapter->rx_itr_setting =3D IGB_DEFAULT_ITR; adapter->tx_itr_setting =3D IGB_DEFAULT_ITR; + /* set default work limits */ + adapter->tx_work_limit =3D IXGBE_DEFAULT_TX_WORK; + adapter->max_frame_size =3D netdev->mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN; adapter->min_frame_size =3D ETH_ZLEN + ETH_FCS_LEN; @@ -5496,7 +5503,7 @@ static int igb_poll(struct napi_struct *napi, int budget) igb_update_dca(q_vector); #endif if (q_vector->tx_ring) - clean_complete =3D !!igb_clean_tx_irq(q_vector); + clean_complete =3D igb_clean_tx_irq(q_vector); if (q_vector->rx_ring) clean_complete &=3D igb_clean_rx_irq(q_vector, budget); @@ -5578,64 +5585,69 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector) { struct igb_adapter *adapter =3D q_vector->adapter; struct igb_ring *tx_ring =3D q_vector->tx_ring; - struct net_device *netdev =3D tx_ring->netdev; - struct e1000_hw *hw =3D &adapter->hw; - struct igb_buffer *buffer_info; - union e1000_adv_tx_desc *tx_desc, *eop_desc; + struct igb_buffer *tx_buffer; + union e1000_adv_tx_desc *tx_desc; unsigned int total_bytes =3D 0, total_packets =3D 0; - unsigned int i, eop, count =3D 0; - bool cleaned =3D false; + unsigned int budget =3D q_vector->tx_work_limit; + u16 i =3D tx_ring->next_to_clean; - i =3D tx_ring->next_to_clean; - eop =3D tx_ring->buffer_info[i].next_to_watch; - eop_desc =3D IGB_TX_DESC(tx_ring, eop); + if (test_bit(__IGB_DOWN, &adapter->state)) + return true; - while ((eop_desc->wb.status & cpu_to_le32(E1000_TXD_STAT_DD)) && - (count < tx_ring->count)) { - rmb(); /* read buffer_info after eop_desc status */ - for (cleaned =3D false; !cleaned; count++) { - tx_desc =3D IGB_TX_DESC(tx_ring, i); - buffer_info =3D &tx_ring->buffer_info[i]; - cleaned =3D (i =3D=3D eop); + tx_buffer =3D &tx_ring->buffer_info[i]; + tx_desc =3D IGB_TX_DESC(tx_ring, i); - if (buffer_info->skb) { - total_bytes +=3D buffer_info->bytecount; - /* gso_segs is currently only valid for tcp */ - total_packets +=3D buffer_info->gso_segs; - igb_tx_hwtstamp(q_vector, buffer_info); - } + for (; budget; budget--) { + u16 eop =3D tx_buffer->next_to_watch; + union e1000_adv_tx_desc *eop_desc; + + eop_desc =3D IGB_TX_DESC(tx_ring, eop); + + /* if DD is not set pending work has not been completed */ + if (!(eop_desc->wb.status & cpu_to_le32(E1000_TXD_STAT_DD))= ) + break; + + /* prevent any other reads prior to eop_desc being verified */ + rmb(); - igb_unmap_and_free_tx_resource(tx_ring, buffer_info); + do { tx_desc->wb.status =3D 0; + if (likely(tx_desc =3D=3D eop_desc)) { + eop_desc =3D NULL; + + total_bytes +=3D tx_buffer->bytecount; + total_packets +=3D tx_buffer->gso_segs; + igb_tx_hwtstamp(q_vector, tx_buffer); + } + + igb_unmap_and_free_tx_resource(tx_ring, tx_buffer); + tx_buffer++; + tx_desc++; i++; - if (i =3D=3D tx_ring->count) + if (unlikely(i =3D=3D tx_ring->count)) { i =3D 0; - } - eop =3D tx_ring->buffer_info[i].next_to_watch; - eop_desc =3D IGB_TX_DESC(tx_ring, eop); + tx_buffer =3D tx_ring->buffer_info; + tx_desc =3D IGB_TX_DESC(tx_ring, 0); + } + } while (eop_desc); } tx_ring->next_to_clean =3D i; + u64_stats_update_begin(&tx_ring->tx_syncp); + tx_ring->tx_stats.bytes +=3D total_bytes; + tx_ring->tx_stats.packets +=3D total_packets; + u64_stats_update_end(&tx_ring->tx_syncp); + tx_ring->total_bytes +=3D total_bytes; + tx_ring->total_packets +=3D total_packets; - if (unlikely(count && - netif_carrier_ok(netdev) && - igb_desc_unused(tx_ring) >=3D IGB_TX_QUEUE_WAKE)) { - /* Make sure that anybody stopping the queue after this - * sees the new next_to_clean. - */ - smp_mb(); - if (__netif_subqueue_stopped(netdev, tx_ring->queue_index) && - !(test_bit(__IGB_DOWN, &adapter->state))) { - netif_wake_subqueue(netdev, tx_ring->queue_index); + if (tx_ring->detect_tx_hung) { + struct e1000_hw *hw =3D &adapter->hw; + u16 eop =3D tx_ring->buffer_info[i].next_to_watch; + union e1000_adv_tx_desc *eop_desc; - u64_stats_update_begin(&tx_ring->tx_syncp); - tx_ring->tx_stats.restart_queue++; - u64_stats_update_end(&tx_ring->tx_syncp); - } - } + eop_desc =3D IGB_TX_DESC(tx_ring, eop); - if (tx_ring->detect_tx_hung) { /* Detect a transmit hang in hardware, this serializes the * check with the clearing of time_stamp and movement of i *= / tx_ring->detect_tx_hung =3D false; @@ -5666,16 +5678,34 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector) eop, jiffies, eop_desc->wb.status); - netif_stop_subqueue(netdev, tx_ring->queue_index); + netif_stop_subqueue(tx_ring->netdev, + tx_ring->queue_index); + + /* we are about to reset, no point in enabling stuf= f */ + return true; } } - tx_ring->total_bytes +=3D total_bytes; - tx_ring->total_packets +=3D total_packets; - u64_stats_update_begin(&tx_ring->tx_syncp); - tx_ring->tx_stats.bytes +=3D total_bytes; - tx_ring->tx_stats.packets +=3D total_packets; - u64_stats_update_end(&tx_ring->tx_syncp); - return count < tx_ring->count; + + if (unlikely(total_packets && + netif_carrier_ok(tx_ring->netdev) && + igb_desc_unused(tx_ring) >=3D IGB_TX_QUEUE_WAKE)) { + /* Make sure that anybody stopping the queue after this + * sees the new next_to_clean. + */ + smp_mb(); + if (__netif_subqueue_stopped(tx_ring->netdev, + tx_ring->queue_index) && + !(test_bit(__IGB_DOWN, &adapter->state))) { + netif_wake_subqueue(tx_ring->netdev, + tx_ring->queue_index); + + u64_stats_update_begin(&tx_ring->tx_syncp); + tx_ring->tx_stats.restart_queue++; + u64_stats_update_end(&tx_ring->tx_syncp); + } + } + + return !!budget; } static inline void igb_rx_checksum(struct igb_ring *ring, -- 1.7.6 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html --=20 Dave T=E4ht SKYPE: davetaht US Tel: 1-239-829-5608 http://the-edge.blogspot.com --20cf3040ee52b71fc004ad263007 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable I am encouraged... more discussion on the netdev list...

---------- Forwarded message ----------
From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>=
Date: Sat, Sep 17, 2011 at 1:04 AM
Subject: [net-next 11/13] igb: Make T= x budget for NAPI user adjustable
To: davem@davemloft.net
Cc: Alexander Duyck <alexander.h.duyck@intel.com>, netdev@vger.kernel.org, gospo@redhat.com, Jeff Kirsher <jeffrey.t.kirsher@intel.com>


From: Alexander Duyck <alexander.h.duyck@intel.com>

This change is meant to make the NAPI budget limits for transmit
adjustable. =A0By doing this it is possible to tune the value for optimal performance with applications such as routing.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Tested-by: =A0Aaron Brown =A0<aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
=A0drivers/net/ethernet/intel/igb/igb.h =A0 =A0 =A0 =A0 | =A0 =A03 +
=A0drivers/net/ethernet/intel/igb/igb_ethtool.c | =A0 =A06 +
=A0drivers/net/ethernet/intel/igb/igb_main.c =A0 =A0| =A0136 ++++++++++++++= ++----------
=A03 files changed, 92 insertions(+), 53 deletions(-)

diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/in= tel/igb/igb.h
index b725937..cfa590c8 100644
--- a/drivers/net/ethernet/intel/igb/igb.h
+++ b/drivers/net/ethernet/intel/igb/igb.h
@@ -47,6 +47,7 @@ struct igb_adapter;

=A0/* TX/RX descriptor defines */
=A0#define IGB_DEFAULT_TXD =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0256
+#define IXGBE_DEFAULT_TX_WORK =A0 =A0 =A0 =A0 =A0 128
=A0#define IGB_MIN_TXD =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 80
=A0#define IGB_MAX_TXD =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 4096

@@ -177,6 +178,7 @@ struct igb_q_vector {

=A0 =A0 =A0 =A0u32 eims_value;
=A0 =A0 =A0 =A0u16 cpu;
+ =A0 =A0 =A0 u16 tx_work_limit;

=A0 =A0 =A0 =A0u16 itr_val;
=A0 =A0 =A0 =A0u8 set_itr;
@@ -266,6 +268,7 @@ struct igb_adapter {
=A0 =A0 =A0 =A0u16 rx_itr;

=A0 =A0 =A0 =A0/* TX */
+ =A0 =A0 =A0 u16 tx_work_limit;
=A0 =A0 =A0 =A0u32 tx_timeout_count;
=A0 =A0 =A0 =A0int num_tx_queues;
=A0 =A0 =A0 =A0struct igb_ring *tx_ring[16];
diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/eth= ernet/intel/igb/igb_ethtool.c
index f231d82..f6da820 100644
--- a/drivers/net/ethernet/intel/igb/igb_ethtool.c
+++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c
@@ -1989,6 +1989,9 @@ static int igb_set_coalesce(struct net_device *netdev= ,
=A0 =A0 =A0 =A0if ((adapter->flags & IGB_FLAG_QUEUE_PAIRS) &&am= p; ec->tx_coalesce_usecs)
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return -EINVAL;

+ =A0 =A0 =A0 if (ec->tx_max_coalesced_frames_irq)
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 adapter->tx_work_limit =3D ec->tx_max_c= oalesced_frames_irq;
+
=A0 =A0 =A0 =A0/* If ITR is disabled, disable DMAC */
=A0 =A0 =A0 =A0if (ec->rx_coalesce_usecs =3D=3D 0) {
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (adapter->flags & IGB_FLAG_DMAC)<= br> @@ -2011,6 +2014,7 @@ static int igb_set_coalesce(struct net_device *netdev= ,

=A0 =A0 =A0 =A0for (i =3D 0; i < adapter->num_q_vectors; i++) {
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0struct igb_q_vector *q_vector =3D adapter-&= gt;q_vector[i];
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 q_vector->tx_work_limit =3D adapter->tx= _work_limit;
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (q_vector->rx_ring)
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0q_vector->itr_val =3D ad= apter->rx_itr_setting;
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0else
@@ -2033,6 +2037,8 @@ static int igb_get_coalesce(struct net_device *netdev= ,
=A0 =A0 =A0 =A0else
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0ec->rx_coalesce_usecs =3D adapter->rx= _itr_setting >> 2;

+ =A0 =A0 =A0 ec->tx_max_coalesced_frames_irq =3D adapter->tx_work_li= mit;
+
=A0 =A0 =A0 =A0if (!(adapter->flags & IGB_FLAG_QUEUE_PAIRS)) {
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (adapter->tx_itr_setting <=3D 3) =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0ec->tx_coalesce_usecs = =3D adapter->tx_itr_setting;
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethern= et/intel/igb/igb_main.c
index 7ad25e8..989e774 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -136,8 +136,8 @@ static irqreturn_t igb_msix_ring(int irq, void *);
=A0static void igb_update_dca(struct igb_q_vector *);
=A0static void igb_setup_dca(struct igb_adapter *);
=A0#endif /* CONFIG_IGB_DCA */
-static bool igb_clean_tx_irq(struct igb_q_vector *);
=A0static int igb_poll(struct napi_struct *, int);
+static bool igb_clean_tx_irq(struct igb_q_vector *);
=A0static bool igb_clean_rx_irq(struct igb_q_vector *, int);
=A0static int igb_ioctl(struct net_device *, struct ifreq *, int cmd);
=A0static void igb_tx_timeout(struct net_device *);
@@ -1120,6 +1120,7 @@ static void igb_map_tx_ring_to_vector(struct igb_adap= ter *adapter,
=A0 =A0 =A0 =A0q_vector->tx_ring =3D adapter->tx_ring[ring_idx];
=A0 =A0 =A0 =A0q_vector->tx_ring->q_vector =3D q_vector;
=A0 =A0 =A0 =A0q_vector->itr_val =3D adapter->tx_itr_setting;
+ =A0 =A0 =A0 q_vector->tx_work_limit =3D adapter->tx_work_limit;
=A0 =A0 =A0 =A0if (q_vector->itr_val && q_vector->itr_val &l= t;=3D 3)
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0q_vector->itr_val =3D IGB_START_ITR;
=A0}
@@ -2388,11 +2389,17 @@ static int __devinit igb_sw_init(struct igb_adapter= *adapter)

=A0 =A0 =A0 =A0pci_read_config_word(pdev, PCI_COMMAND, &hw->bus.pci= _cmd_word);

+ =A0 =A0 =A0 /* set default ring sizes */
=A0 =A0 =A0 =A0adapter->tx_ring_count =3D IGB_DEFAULT_TXD;
=A0 =A0 =A0 =A0adapter->rx_ring_count =3D IGB_DEFAULT_RXD;
+
+ =A0 =A0 =A0 /* set default ITR values */
=A0 =A0 =A0 =A0adapter->rx_itr_setting =3D IGB_DEFAULT_ITR;
=A0 =A0 =A0 =A0adapter->tx_itr_setting =3D IGB_DEFAULT_ITR;

+ =A0 =A0 =A0 /* set default work limits */
+ =A0 =A0 =A0 adapter->tx_work_limit =3D IXGBE_DEFAULT_TX_WORK;
+
=A0 =A0 =A0 =A0adapter->max_frame_size =3D netdev->mtu + ETH_HLEN + = ETH_FCS_LEN +
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0VLAN_HL= EN;
=A0 =A0 =A0 =A0adapter->min_frame_size =3D ETH_ZLEN + ETH_FCS_LEN;
@@ -5496,7 +5503,7 @@ static int igb_poll(struct napi_struct *napi, int bud= get)
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0igb_update_dca(q_vector);
=A0#endif
=A0 =A0 =A0 =A0if (q_vector->tx_ring)
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 clean_complete =3D !!igb_clean_tx_irq(q_vecto= r);
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 clean_complete =3D igb_clean_tx_irq(q_vector)= ;

=A0 =A0 =A0 =A0if (q_vector->rx_ring)
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0clean_complete &=3D igb_clean_rx_irq(q_= vector, budget);
@@ -5578,64 +5585,69 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q= _vector)
=A0{
=A0 =A0 =A0 =A0struct igb_adapter *adapter =3D q_vector->adapter;
=A0 =A0 =A0 =A0struct igb_ring *tx_ring =3D q_vector->tx_ring;
- =A0 =A0 =A0 struct net_device *netdev =3D tx_ring->netdev;
- =A0 =A0 =A0 struct e1000_hw *hw =3D &adapter->hw;
- =A0 =A0 =A0 struct igb_buffer *buffer_info;
- =A0 =A0 =A0 union e1000_adv_tx_desc *tx_desc, *eop_desc;
+ =A0 =A0 =A0 struct igb_buffer *tx_buffer;
+ =A0 =A0 =A0 union e1000_adv_tx_desc *tx_desc;
=A0 =A0 =A0 =A0unsigned int total_bytes =3D 0, total_packets =3D 0;
- =A0 =A0 =A0 unsigned int i, eop, count =3D 0;
- =A0 =A0 =A0 bool cleaned =3D false;
+ =A0 =A0 =A0 unsigned int budget =3D q_vector->tx_work_limit;
+ =A0 =A0 =A0 u16 i =3D tx_ring->next_to_clean;

- =A0 =A0 =A0 i =3D tx_ring->next_to_clean;
- =A0 =A0 =A0 eop =3D tx_ring->buffer_info[i].next_to_watch;
- =A0 =A0 =A0 eop_desc =3D IGB_TX_DESC(tx_ring, eop);
+ =A0 =A0 =A0 if (test_bit(__IGB_DOWN, &adapter->state))
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 return true;

- =A0 =A0 =A0 while ((eop_desc->wb.status & cpu_to_le32(E1000_TXD_ST= AT_DD)) &&
- =A0 =A0 =A0 =A0 =A0 =A0 =A0(count < tx_ring->count)) {
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 rmb(); =A0/* read buffer_info after eop_desc = status */
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 for (cleaned =3D false; !cleaned; count++) {<= br> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 tx_desc =3D IGB_TX_DESC(tx_ri= ng, i);
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 buffer_info =3D &tx_ring-= >buffer_info[i];
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 cleaned =3D (i =3D=3D eop); + =A0 =A0 =A0 tx_buffer =3D &tx_ring->buffer_info[i];
+ =A0 =A0 =A0 tx_desc =3D IGB_TX_DESC(tx_ring, i);

- =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (buffer_info->skb) { - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 total_bytes += =3D buffer_info->bytecount;
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* gso_segs i= s currently only valid for tcp */
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 total_packets= +=3D buffer_info->gso_segs;
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 igb_tx_hwtsta= mp(q_vector, buffer_info);
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
+ =A0 =A0 =A0 for (; budget; budget--) {
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 u16 eop =3D tx_buffer->next_to_watch;
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 union e1000_adv_tx_desc *eop_desc;
+
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 eop_desc =3D IGB_TX_DESC(tx_ring, eop);
+
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* if DD is not set pending work has not been= completed */
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!(eop_desc->wb.status & cpu_to_le3= 2(E1000_TXD_STAT_DD)))
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 break;
+
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* prevent any other reads prior to eop_desc = being verified */
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 rmb();

- =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 igb_unmap_and_free_tx_resourc= e(tx_ring, buffer_info);
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 do {
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0tx_desc->wb.status =3D 0= ;
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (likely(tx_desc =3D=3D eop= _desc)) {
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 eop_desc =3D = NULL;
+
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 total_bytes += =3D tx_buffer->bytecount;
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 total_packets= +=3D tx_buffer->gso_segs;
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 igb_tx_hwtsta= mp(q_vector, tx_buffer);
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
+
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 igb_unmap_and_free_tx_resourc= e(tx_ring, tx_buffer);

+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 tx_buffer++;
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 tx_desc++;
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0i++;
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (i =3D=3D tx_ring->coun= t)
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (unlikely(i =3D=3D tx_ring= ->count)) {
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0i =3D 0; - =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 eop =3D tx_ring->buffer_info[i].next_to_wa= tch;
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 eop_desc =3D IGB_TX_DESC(tx_ring, eop);
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 tx_buffer =3D= tx_ring->buffer_info;
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 tx_desc =3D I= GB_TX_DESC(tx_ring, 0);
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 } while (eop_desc);
=A0 =A0 =A0 =A0}

=A0 =A0 =A0 =A0tx_ring->next_to_clean =3D i;
+ =A0 =A0 =A0 u64_stats_update_begin(&tx_ring->tx_syncp);
+ =A0 =A0 =A0 tx_ring->tx_stats.bytes +=3D total_bytes;
+ =A0 =A0 =A0 tx_ring->tx_stats.packets +=3D total_packets;
+ =A0 =A0 =A0 u64_stats_update_end(&tx_ring->tx_syncp);
+ =A0 =A0 =A0 tx_ring->total_bytes +=3D total_bytes;
+ =A0 =A0 =A0 tx_ring->total_packets +=3D total_packets;

- =A0 =A0 =A0 if (unlikely(count &&
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0netif_carrier_ok(netdev) &&= ;
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0igb_desc_unused(tx_ring) >=3D I= GB_TX_QUEUE_WAKE)) {
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* Make sure that anybody stopping the queue = after this
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* sees the new next_to_clean.
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*/
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 smp_mb();
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (__netif_subqueue_stopped(netdev, tx_ring-= >queue_index) &&
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 !(test_bit(__IGB_DOWN, &adapter-&= gt;state))) {
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 netif_wake_subqueue(netdev, t= x_ring->queue_index);
+ =A0 =A0 =A0 if (tx_ring->detect_tx_hung) {
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 struct e1000_hw *hw =3D &adapter->hw;<= br> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 u16 eop =3D tx_ring->buffer_info[i].next_t= o_watch;
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 union e1000_adv_tx_desc *eop_desc;

- =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 u64_stats_update_begin(&t= x_ring->tx_syncp);
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 tx_ring->tx_stats.restart_= queue++;
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 u64_stats_update_end(&tx_= ring->tx_syncp);
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
- =A0 =A0 =A0 }
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 eop_desc =3D IGB_TX_DESC(tx_ring, eop);

- =A0 =A0 =A0 if (tx_ring->detect_tx_hung) {
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* Detect a transmit hang in hardware, this= serializes the
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 * check with the clearing of time_stamp an= d movement of i */
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0tx_ring->detect_tx_hung =3D false;
@@ -5666,16 +5678,34 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q= _vector)
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0eop,
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0jiffies, =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0eop_desc-&g= t;wb.status);
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 netif_stop_subqueue(netdev, t= x_ring->queue_index);
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 netif_stop_subqueue(tx_ring-&= gt;netdev,
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 tx_ring->queue_index);
+
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* we are about to reset, no = point in enabling stuff */
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return true;
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0}
=A0 =A0 =A0 =A0}
- =A0 =A0 =A0 tx_ring->total_bytes +=3D total_bytes;
- =A0 =A0 =A0 tx_ring->total_packets +=3D total_packets;
- =A0 =A0 =A0 u64_stats_update_begin(&tx_ring->tx_syncp);
- =A0 =A0 =A0 tx_ring->tx_stats.bytes +=3D total_bytes;
- =A0 =A0 =A0 tx_ring->tx_stats.packets +=3D total_packets;
- =A0 =A0 =A0 u64_stats_update_end(&tx_ring->tx_syncp);
- =A0 =A0 =A0 return count < tx_ring->count;
+
+ =A0 =A0 =A0 if (unlikely(total_packets &&
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0netif_carrier_ok(tx_ring->netde= v) &&
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0igb_desc_unused(tx_ring) >=3D I= GB_TX_QUEUE_WAKE)) {
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* Make sure that anybody stopping the queue = after this
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* sees the new next_to_clean.
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*/
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 smp_mb();
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (__netif_subqueue_stopped(tx_ring->netd= ev,
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0tx_ring->queue_index) &&
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 !(test_bit(__IGB_DOWN, &adapter-&= gt;state))) {
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 netif_wake_subqueue(tx_ring-&= gt;netdev,
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 tx_ring->queue_index);
+
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 u64_stats_update_begin(&t= x_ring->tx_syncp);
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 tx_ring->tx_stats.restart_= queue++;
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 u64_stats_update_end(&tx_= ring->tx_syncp);
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
+ =A0 =A0 =A0 }
+
+ =A0 =A0 =A0 return !!budget;
=A0}

=A0static inline void igb_rx_checksum(struct igb_ring *ring,
--
1.7.6

--
To unsubscribe from this list: send the line "unsubscribe netdev"= in
the body of a message to major= domo@vger.kernel.org
More majordomo info at =A0http://vger.kernel.org/majordomo-info.html



--
Dave T=E4ht
SKYPE: davetah= t
US Tel: 1-239-829-5608
http://the-edge.blogspot.com
--20cf3040ee52b71fc004ad263007--