Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/854013/?format=api
{ "id": 854013, "url": "http://patchwork.ozlabs.org/api/patches/854013/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20171229135125.14740-1-alice.michael@intel.com/", "project": { "id": 46, "url": "http://patchwork.ozlabs.org/api/projects/46/?format=api", "name": "Intel Wired Ethernet development", "link_name": "intel-wired-lan", "list_id": "intel-wired-lan.osuosl.org", "list_email": "intel-wired-lan@osuosl.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20171229135125.14740-1-alice.michael@intel.com>", "list_archive_url": null, "date": "2017-12-29T13:51:25", "name": "[next,S85-V1,13/14] i40e/i40evf: Split container ITR into current_itr and target_itr", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": false, "hash": "702a456cca49abaafca7d06fad465db34ca8a0cd", "submitter": { "id": 71123, "url": "http://patchwork.ozlabs.org/api/people/71123/?format=api", "name": "Michael, Alice", "email": "alice.michael@intel.com" }, "delegate": { "id": 68, "url": "http://patchwork.ozlabs.org/api/users/68/?format=api", "username": "jtkirshe", "first_name": "Jeff", "last_name": "Kirsher", "email": "jeffrey.t.kirsher@intel.com" }, "mbox": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20171229135125.14740-1-alice.michael@intel.com/mbox/", "series": [ { "id": 20665, "url": "http://patchwork.ozlabs.org/api/series/20665/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/list/?series=20665", "date": "2017-12-29T13:48:33", "name": "[next,S85-V1,01/14] i40e: fix typo in function description", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/20665/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/854013/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/854013/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<intel-wired-lan-bounces@osuosl.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "intel-wired-lan@lists.osuosl.org" ], "Delivered-To": [ "patchwork-incoming@bilbo.ozlabs.org", "intel-wired-lan@lists.osuosl.org" ], "Authentication-Results": "ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=osuosl.org\n\t(client-ip=140.211.166.137; helo=fraxinus.osuosl.org;\n\tenvelope-from=intel-wired-lan-bounces@osuosl.org;\n\treceiver=<UNKNOWN>)", "Received": [ "from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137])\n\t(using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3z7gT20Mvdz9s7G\n\tfor <incoming@patchwork.ozlabs.org>;\n\tSat, 30 Dec 2017 08:58:29 +1100 (AEDT)", "from localhost (localhost [127.0.0.1])\n\tby fraxinus.osuosl.org (Postfix) with ESMTP id 99F9C86DD3;\n\tFri, 29 Dec 2017 21:58:28 +0000 (UTC)", "from fraxinus.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id kYi91CGGPKEe; Fri, 29 Dec 2017 21:58:27 +0000 (UTC)", "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby fraxinus.osuosl.org (Postfix) with ESMTP id 59A5886C82;\n\tFri, 29 Dec 2017 21:58:27 +0000 (UTC)", "from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138])\n\tby ash.osuosl.org (Postfix) with ESMTP id 44C7E1C0180\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tFri, 29 Dec 2017 21:58:26 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n\tby whitealder.osuosl.org (Postfix) with ESMTP id 3EB2987698\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tFri, 29 Dec 2017 21:58:26 +0000 (UTC)", "from whitealder.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id Jj5lySCnaObD for <intel-wired-lan@lists.osuosl.org>;\n\tFri, 29 Dec 2017 21:58:25 +0000 (UTC)", "from mga07.intel.com (mga07.intel.com [134.134.136.100])\n\tby whitealder.osuosl.org (Postfix) with ESMTPS id 0F40587214\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tFri, 29 Dec 2017 21:58:25 +0000 (UTC)", "from orsmga004.jf.intel.com ([10.7.209.38])\n\tby orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t29 Dec 2017 13:58:24 -0800", "from alicemic-2.jf.intel.com ([10.166.16.121])\n\tby orsmga004.jf.intel.com with ESMTP; 29 Dec 2017 13:58:24 -0800" ], "X-Virus-Scanned": [ "amavisd-new at osuosl.org", "amavisd-new at osuosl.org" ], "X-Greylist": "domain auto-whitelisted by SQLgrey-1.7.6", "X-Amp-Result": "SKIPPED(no attachment in message)", "X-Amp-File-Uploaded": "False", "X-ExtLoop1": "1", "X-IronPort-AV": "E=Sophos;i=\"5.45,478,1508828400\"; d=\"scan'208\";a=\"162694888\"", "From": "Alice Michael <alice.michael@intel.com>", "To": "alice.michael@intel.com,\n\tintel-wired-lan@lists.osuosl.org", "Date": "Fri, 29 Dec 2017 08:51:25 -0500", "Message-Id": "<20171229135125.14740-1-alice.michael@intel.com>", "X-Mailer": "git-send-email 2.9.5", "Subject": "[Intel-wired-lan] [next PATCH S85-V1 13/14] i40e/i40evf: Split\n\tcontainer ITR into current_itr and target_itr", "X-BeenThere": "intel-wired-lan@osuosl.org", "X-Mailman-Version": "2.1.24", "Precedence": "list", "List-Id": "Intel Wired Ethernet Linux Kernel Driver Development\n\t<intel-wired-lan.osuosl.org>", "List-Unsubscribe": "<https://lists.osuosl.org/mailman/options/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@osuosl.org?subject=unsubscribe>", "List-Archive": "<http://lists.osuosl.org/pipermail/intel-wired-lan/>", "List-Post": "<mailto:intel-wired-lan@osuosl.org>", "List-Help": "<mailto:intel-wired-lan-request@osuosl.org?subject=help>", "List-Subscribe": "<https://lists.osuosl.org/mailman/listinfo/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@osuosl.org?subject=subscribe>", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=\"us-ascii\"", "Content-Transfer-Encoding": "7bit", "Errors-To": "intel-wired-lan-bounces@osuosl.org", "Sender": "\"Intel-wired-lan\" <intel-wired-lan-bounces@osuosl.org>" }, "content": "From: Alexander Duyck <alexander.h.duyck@intel.com>\n\nThis patch is mostly prep-work for replacing the current approach to\nprogramming the dynamic aka adaptive ITR. Specifically here what we are\ndoing is splitting the Tx and Rx ITR each into two separate values.\n\nThe first value current_itr represents the current value of the register.\n\nThe second value target_itr represents the desired value of the register.\n\nThe general plan by doing this is to allow for deferring the update of the\nITR value under certain circumstances. For now we will work with what we\nhave, but in the future I hope to change the behavior so that we always\nonly update one ITR at a time using some simple logic to determine which\nITR requires an update.\n\nSigned-off-by: Alexander Duyck <alexander.h.duyck@intel.com>\n---\n drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 13 +++--\n drivers/net/ethernet/intel/i40e/i40e_main.c | 22 ++++---\n drivers/net/ethernet/intel/i40e/i40e_txrx.c | 68 +++++++++++++---------\n drivers/net/ethernet/intel/i40e/i40e_txrx.h | 5 +-\n drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 68 +++++++++++++---------\n drivers/net/ethernet/intel/i40evf/i40e_txrx.h | 5 +-\n drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c | 14 ++---\n drivers/net/ethernet/intel/i40evf/i40evf_main.c | 10 ++--\n 8 files changed, 117 insertions(+), 88 deletions(-)", "diff": "diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c\nindex 0212f6c..bfaeb77 100644\n--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c\n+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c\n@@ -2329,14 +2329,15 @@ static void i40e_set_itr_per_queue(struct i40e_vsi *vsi,\n \t\ttx_ring->itr_setting &= ~I40E_ITR_DYNAMIC;\n \n \tq_vector = rx_ring->q_vector;\n-\tq_vector->rx.itr = ITR_TO_REG(rx_ring->itr_setting);\n-\twr32(hw, I40E_PFINT_ITRN(I40E_RX_ITR, q_vector->reg_idx),\n-\t q_vector->rx.itr);\n+\tq_vector->rx.target_itr = ITR_TO_REG(rx_ring->itr_setting);\n \n \tq_vector = tx_ring->q_vector;\n-\tq_vector->tx.itr = ITR_TO_REG(tx_ring->itr_setting);\n-\twr32(hw, I40E_PFINT_ITRN(I40E_TX_ITR, q_vector->reg_idx),\n-\t q_vector->tx.itr);\n+\tq_vector->tx.target_itr = ITR_TO_REG(tx_ring->itr_setting);\n+\n+\t/* The interrupt handler itself will take care of programming\n+\t * the Tx and Rx ITR values based on the values we have entered\n+\t * into the q_vector, no need to write the values now.\n+\t */\n \n \twr32(hw, I40E_PFINT_RATEN(q_vector->reg_idx), intrl);\n \ti40e_flush(hw);\ndiff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c\nindex c810e9d..6380d03 100644\n--- a/drivers/net/ethernet/intel/i40e/i40e_main.c\n+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c\n@@ -3434,14 +3434,18 @@ static void i40e_vsi_configure_msix(struct i40e_vsi *vsi)\n \t\tstruct i40e_q_vector *q_vector = vsi->q_vectors[i];\n \n \t\tq_vector->itr_countdown = ITR_COUNTDOWN_START;\n-\t\tq_vector->rx.itr = ITR_TO_REG(vsi->rx_rings[i]->itr_setting);\n+\t\tq_vector->rx.target_itr =\n+\t\t\tITR_TO_REG(vsi->rx_rings[i]->itr_setting);\n \t\tq_vector->rx.latency_range = I40E_LOW_LATENCY;\n \t\twr32(hw, I40E_PFINT_ITRN(I40E_RX_ITR, vector - 1),\n-\t\t q_vector->rx.itr);\n-\t\tq_vector->tx.itr = ITR_TO_REG(vsi->tx_rings[i]->itr_setting);\n+\t\t q_vector->rx.target_itr);\n+\t\tq_vector->rx.current_itr = q_vector->rx.target_itr;\n+\t\tq_vector->tx.target_itr =\n+\t\t\tITR_TO_REG(vsi->tx_rings[i]->itr_setting);\n \t\tq_vector->tx.latency_range = I40E_LOW_LATENCY;\n \t\twr32(hw, I40E_PFINT_ITRN(I40E_TX_ITR, vector - 1),\n-\t\t q_vector->tx.itr);\n+\t\t q_vector->tx.target_itr);\n+\t\tq_vector->tx.current_itr = q_vector->tx.target_itr;\n \t\twr32(hw, I40E_PFINT_RATEN(vector - 1),\n \t\t i40e_intrl_usec_to_reg(vsi->int_rate_limit));\n \n@@ -3543,12 +3547,14 @@ static void i40e_configure_msi_and_legacy(struct i40e_vsi *vsi)\n \n \t/* set the ITR configuration */\n \tq_vector->itr_countdown = ITR_COUNTDOWN_START;\n-\tq_vector->rx.itr = ITR_TO_REG(vsi->rx_rings[0]->itr_setting);\n+\tq_vector->rx.target_itr = ITR_TO_REG(vsi->rx_rings[0]->itr_setting);\n \tq_vector->rx.latency_range = I40E_LOW_LATENCY;\n-\twr32(hw, I40E_PFINT_ITR0(I40E_RX_ITR), q_vector->rx.itr);\n-\tq_vector->tx.itr = ITR_TO_REG(vsi->tx_rings[0]->itr_setting);\n+\twr32(hw, I40E_PFINT_ITR0(I40E_RX_ITR), q_vector->rx.target_itr);\n+\tq_vector->rx.current_itr = q_vector->rx.target_itr;\n+\tq_vector->tx.target_itr = ITR_TO_REG(vsi->tx_rings[0]->itr_setting);\n \tq_vector->tx.latency_range = I40E_LOW_LATENCY;\n-\twr32(hw, I40E_PFINT_ITR0(I40E_TX_ITR), q_vector->tx.itr);\n+\twr32(hw, I40E_PFINT_ITR0(I40E_TX_ITR), q_vector->tx.target_itr);\n+\tq_vector->tx.current_itr = q_vector->tx.target_itr;\n \n \ti40e_enable_misc_int_causes(pf);\n \ndiff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c\nindex 170256e..d810e0e 100644\n--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c\n+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c\n@@ -1011,17 +1011,16 @@ void i40e_force_wb(struct i40e_vsi *vsi, struct i40e_q_vector *q_vector)\n static bool i40e_set_new_dynamic_itr(struct i40e_ring_container *rc)\n {\n \tenum i40e_latency_range new_latency_range = rc->latency_range;\n-\tu32 new_itr = rc->itr;\n \tint bytes_per_usec;\n \tunsigned int usecs, estimated_usecs;\n \n \tif (!rc->ring || !ITR_IS_DYNAMIC(rc->ring->itr_setting))\n \t\treturn false;\n \n-\tif (rc->total_packets == 0 || !rc->itr)\n+\tif (!rc->total_packets || !rc->current_itr)\n \t\treturn false;\n \n-\tusecs = (rc->itr << 1) * ITR_COUNTDOWN_START;\n+\tusecs = (rc->current_itr << 1) * ITR_COUNTDOWN_START;\n \tbytes_per_usec = rc->total_bytes / usecs;\n \n \t/* The calculations in this algorithm depend on interrupts actually\n@@ -1069,13 +1068,13 @@ static bool i40e_set_new_dynamic_itr(struct i40e_ring_container *rc)\n \n \tswitch (new_latency_range) {\n \tcase I40E_LOWEST_LATENCY:\n-\t\tnew_itr = I40E_ITR_50K;\n+\t\trc->target_itr = I40E_ITR_50K;\n \t\tbreak;\n \tcase I40E_LOW_LATENCY:\n-\t\tnew_itr = I40E_ITR_20K;\n+\t\trc->target_itr = I40E_ITR_20K;\n \t\tbreak;\n \tcase I40E_BULK_LATENCY:\n-\t\tnew_itr = I40E_ITR_18K;\n+\t\trc->target_itr = I40E_ITR_18K;\n \t\tbreak;\n \tdefault:\n \t\tbreak;\n@@ -1085,11 +1084,7 @@ static bool i40e_set_new_dynamic_itr(struct i40e_ring_container *rc)\n \trc->total_packets = 0;\n \trc->last_itr_update = jiffies;\n \n-\tif (new_itr != rc->itr) {\n-\t\trc->itr = new_itr;\n-\t\treturn true;\n-\t}\n-\treturn false;\n+\treturn rc->target_itr != rc->current_itr;\n }\n \n /**\n@@ -2305,7 +2300,7 @@ static inline void i40e_update_enable_itr(struct i40e_vsi *vsi,\n {\n \tstruct i40e_hw *hw = &vsi->back->hw;\n \tbool rx = false, tx = false;\n-\tu32 txval;\n+\tu32 intval;\n \n \t/* If we don't have MSIX, then we only need to re-enable icr0 */\n \tif (!(vsi->back->flags & I40E_FLAG_MSIX_ENABLED)) {\n@@ -2313,8 +2308,6 @@ static inline void i40e_update_enable_itr(struct i40e_vsi *vsi,\n \t\treturn;\n \t}\n \n-\ttxval = i40e_buildreg_itr(I40E_ITR_NONE, 0);\n-\n \t/* avoid dynamic calculation if in countdown mode */\n \tif (q_vector->itr_countdown > 0)\n \t\tgoto enable_int;\n@@ -2328,26 +2321,43 @@ static inline void i40e_update_enable_itr(struct i40e_vsi *vsi,\n \t\t * use the same value for both ITR registers\n \t\t * when in adaptive mode (Rx and/or Tx)\n \t\t */\n-\t\tu16 itr = max(q_vector->tx.itr, q_vector->rx.itr);\n-\t\tu32 rxval;\n-\n-\t\tq_vector->tx.itr = q_vector->rx.itr = itr;\n-\n-\t\t/* set the INTENA_MSK_MASK so that this first write\n-\t\t * won't actually enable the interrupt, instead just\n-\t\t * updating the ITR (it's bit 31 PF and VF)\n-\t\t */\n-\t\trxval = i40e_buildreg_itr(I40E_RX_ITR, itr) | BIT(31);\n+\t\tu16 itr = max(q_vector->tx.target_itr,\n+\t\t\t q_vector->rx.target_itr);\n \n-\t\t/* don't check _DOWN because interrupt isn't being enabled */\n-\t\twr32(hw, INTREG(q_vector->reg_idx), rxval);\n-\n-\t\ttxval = i40e_buildreg_itr(I40E_TX_ITR, itr);\n+\t\tq_vector->tx.target_itr = itr;\n+\t\tq_vector->rx.target_itr = itr;\n \t}\n \n enable_int:\n+\tif (q_vector->rx.target_itr != q_vector->rx.current_itr) {\n+\t\tintval = i40e_buildreg_itr(I40E_RX_ITR,\n+\t\t\t\t\t q_vector->rx.target_itr);\n+\t\tq_vector->rx.current_itr = q_vector->rx.target_itr;\n+\n+\t\tif (q_vector->tx.target_itr != q_vector->tx.current_itr) {\n+\t\t\t/* set the INTENA_MSK_MASK so that this first write\n+\t\t\t * won't actually enable the interrupt, instead just\n+\t\t\t * updating the ITR (it's bit 31 PF and VF)\n+\t\t\t *\n+\t\t\t * don't check _DOWN because interrupt isn't being\n+\t\t\t * enabled\n+\t\t\t */\n+\t\t\twr32(hw, INTREG(q_vector->reg_idx),\n+\t\t\t intval | BIT(31));\n+\t\t\t/* now that Rx is done process Tx update */\n+\t\t\tgoto update_tx;\n+\t\t}\n+\t} else if (q_vector->tx.target_itr != q_vector->tx.current_itr) {\n+update_tx:\n+\t\tintval = i40e_buildreg_itr(I40E_TX_ITR,\n+\t\t\t\t\t q_vector->tx.target_itr);\n+\t\tq_vector->tx.current_itr = q_vector->tx.target_itr;\n+\t} else {\n+\t\tintval = i40e_buildreg_itr(I40E_ITR_NONE, 0);\n+\t}\n+\n \tif (!test_bit(__I40E_VSI_DOWN, vsi->state))\n-\t\twr32(hw, INTREG(q_vector->reg_idx), txval);\n+\t\twr32(hw, INTREG(q_vector->reg_idx), intval);\n \n \tif (q_vector->itr_countdown)\n \t\tq_vector->itr_countdown--;\ndiff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.h b/drivers/net/ethernet/intel/i40e/i40e_txrx.h\nindex d226c7c..59acc25 100644\n--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.h\n+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.h\n@@ -32,7 +32,7 @@\n \n /* The datasheet for the X710 and XL710 indicate that the maximum value for\n * the ITR is 8160usec which is then called out as 0xFF0 with a 2usec\n- * resoltion. 8160 is 0x1FE0 when written out in hex. So instead of storing\n+ * resolution. 8160 is 0x1FE0 when written out in hex. So instead of storing\n * the register value which is divided by 2 lets use the actual values and\n * avoid an excessive amount of translation.\n */\n@@ -474,7 +474,8 @@ struct i40e_ring_container {\n \tunsigned long last_itr_update;\t/* jiffies of last ITR update */\n \tu16 count;\n \tenum i40e_latency_range latency_range;\n-\tu16 itr;\n+\tu16 target_itr;\t\t\t/* target ITR setting for ring(s) */\n+\tu16 current_itr;\t\t/* current ITR setting for ring(s) */\n };\n \n /* iterator for handling rings in ring container */\ndiff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c\nindex c5f8e94..1f130e9 100644\n--- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c\n+++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c\n@@ -409,17 +409,16 @@ void i40evf_force_wb(struct i40e_vsi *vsi, struct i40e_q_vector *q_vector)\n static bool i40e_set_new_dynamic_itr(struct i40e_ring_container *rc)\n {\n \tenum i40e_latency_range new_latency_range = rc->latency_range;\n-\tu32 new_itr = rc->itr;\n \tint bytes_per_usec;\n \tunsigned int usecs, estimated_usecs;\n \n \tif (!rc->ring || !ITR_IS_DYNAMIC(rc->ring->itr_setting))\n \t\treturn false;\n \n-\tif (rc->total_packets == 0 || !rc->itr)\n+\tif (!rc->total_packets || !rc->current_itr)\n \t\treturn false;\n \n-\tusecs = (rc->itr << 1) * ITR_COUNTDOWN_START;\n+\tusecs = (rc->current_itr << 1) * ITR_COUNTDOWN_START;\n \tbytes_per_usec = rc->total_bytes / usecs;\n \n \t/* The calculations in this algorithm depend on interrupts actually\n@@ -467,13 +466,13 @@ static bool i40e_set_new_dynamic_itr(struct i40e_ring_container *rc)\n \n \tswitch (new_latency_range) {\n \tcase I40E_LOWEST_LATENCY:\n-\t\tnew_itr = I40E_ITR_50K;\n+\t\trc->target_itr = I40E_ITR_50K;\n \t\tbreak;\n \tcase I40E_LOW_LATENCY:\n-\t\tnew_itr = I40E_ITR_20K;\n+\t\trc->target_itr = I40E_ITR_20K;\n \t\tbreak;\n \tcase I40E_BULK_LATENCY:\n-\t\tnew_itr = I40E_ITR_18K;\n+\t\trc->target_itr = I40E_ITR_18K;\n \t\tbreak;\n \tdefault:\n \t\tbreak;\n@@ -483,11 +482,7 @@ static bool i40e_set_new_dynamic_itr(struct i40e_ring_container *rc)\n \trc->total_packets = 0;\n \trc->last_itr_update = jiffies;\n \n-\tif (new_itr != rc->itr) {\n-\t\trc->itr = new_itr;\n-\t\treturn true;\n-\t}\n-\treturn false;\n+\treturn rc->target_itr != rc->current_itr;\n }\n \n /**\n@@ -1502,9 +1497,7 @@ static inline void i40e_update_enable_itr(struct i40e_vsi *vsi,\n {\n \tstruct i40e_hw *hw = &vsi->back->hw;\n \tbool rx = false, tx = false;\n-\tu32 txval;\n-\n-\ttxval = i40e_buildreg_itr(I40E_ITR_NONE, 0);\n+\tu32 intval;\n \n \t/* avoid dynamic calculation if in countdown mode */\n \tif (q_vector->itr_countdown > 0)\n@@ -1519,26 +1512,43 @@ static inline void i40e_update_enable_itr(struct i40e_vsi *vsi,\n \t\t * use the same value for both ITR registers\n \t\t * when in adaptive mode (Rx and/or Tx)\n \t\t */\n-\t\tu16 itr = max(q_vector->tx.itr, q_vector->rx.itr);\n-\t\tu32 rxval;\n-\n-\t\tq_vector->tx.itr = q_vector->rx.itr = itr;\n-\n-\t\t/* set the INTENA_MSK_MASK so that this first write\n-\t\t * won't actually enable the interrupt, instead just\n-\t\t * updating the ITR (it's bit 31 PF and VF)\n-\t\t */\n-\t\trxval = i40e_buildreg_itr(I40E_RX_ITR, itr) | BIT(31);\n+\t\tu16 itr = max(q_vector->tx.target_itr,\n+\t\t\t q_vector->rx.target_itr);\n \n-\t\t/* don't check _DOWN because interrupt isn't being enabled */\n-\t\twr32(hw, INTREG(q_vector->reg_idx), rxval);\n-\n-\t\ttxval = i40e_buildreg_itr(I40E_TX_ITR, itr);\n+\t\tq_vector->tx.target_itr = itr;\n+\t\tq_vector->rx.target_itr = itr;\n \t}\n \n enable_int:\n+\tif (q_vector->rx.target_itr != q_vector->rx.current_itr) {\n+\t\tintval = i40e_buildreg_itr(I40E_RX_ITR,\n+\t\t\t\t\t q_vector->rx.target_itr);\n+\t\tq_vector->rx.current_itr = q_vector->rx.target_itr;\n+\n+\t\tif (q_vector->tx.target_itr != q_vector->tx.current_itr) {\n+\t\t\t/* set the INTENA_MSK_MASK so that this first write\n+\t\t\t * won't actually enable the interrupt, instead just\n+\t\t\t * updating the ITR (it's bit 31 PF and VF)\n+\t\t\t *\n+\t\t\t * don't check _DOWN because interrupt isn't being\n+\t\t\t * enabled\n+\t\t\t */\n+\t\t\twr32(hw, INTREG(q_vector->reg_idx),\n+\t\t\t intval | BIT(31));\n+\t\t\t/* now that Rx is done process Tx update */\n+\t\t\tgoto update_tx;\n+\t\t}\n+\t} else if (q_vector->tx.target_itr != q_vector->tx.current_itr) {\n+update_tx:\n+\t\tintval = i40e_buildreg_itr(I40E_TX_ITR,\n+\t\t\t\t\t q_vector->tx.target_itr);\n+\t\tq_vector->tx.current_itr = q_vector->tx.target_itr;\n+\t} else {\n+\t\tintval = i40e_buildreg_itr(I40E_ITR_NONE, 0);\n+\t}\n+\n \tif (!test_bit(__I40E_VSI_DOWN, vsi->state))\n-\t\twr32(hw, INTREG(q_vector->reg_idx), txval);\n+\t\twr32(hw, INTREG(q_vector->reg_idx), intval);\n \n \tif (q_vector->itr_countdown)\n \t\tq_vector->itr_countdown--;\ndiff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.h b/drivers/net/ethernet/intel/i40evf/i40e_txrx.h\nindex f1c5ef7..5a6012b 100644\n--- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.h\n+++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.h\n@@ -32,7 +32,7 @@\n \n /* The datasheet for the X710 and XL710 indicate that the maximum value for\n * the ITR is 8160usec which is then called out as 0xFF0 with a 2usec\n- * resoltion. 8160 is 0x1FE0 when written out in hex. So instead of storing\n+ * resolution. 8160 is 0x1FE0 when written out in hex. So instead of storing\n * the register value which is divided by 2 lets use the actual values and\n * avoid an excessive amount of translation.\n */\n@@ -442,7 +442,8 @@ struct i40e_ring_container {\n \tunsigned long last_itr_update;\t/* jiffies of last ITR update */\n \tu16 count;\n \tenum i40e_latency_range latency_range;\n-\tu16 itr;\n+\tu16 target_itr;\t\t\t/* target ITR setting for ring(s) */\n+\tu16 current_itr;\t\t/* current ITR setting for ring(s) */\n };\n \n /* iterator for handling rings in ring container */\ndiff --git a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c\nindex f5d3725..aded3ad 100644\n--- a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c\n+++ b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c\n@@ -514,7 +514,6 @@ static void i40evf_set_itr_per_queue(struct i40evf_adapter *adapter,\n {\n \tstruct i40e_ring *rx_ring = &adapter->rx_rings[queue];\n \tstruct i40e_ring *tx_ring = &adapter->tx_rings[queue];\n-\tstruct i40e_hw *hw = &adapter->hw;\n \tstruct i40e_q_vector *q_vector;\n \n \trx_ring->itr_setting = ITR_REG_ALIGN(ec->rx_coalesce_usecs);\n@@ -529,16 +528,15 @@ static void i40evf_set_itr_per_queue(struct i40evf_adapter *adapter,\n \t\ttx_ring->itr_setting ^= I40E_ITR_DYNAMIC;\n \n \tq_vector = rx_ring->q_vector;\n-\tq_vector->rx.itr = ITR_TO_REG(rx_ring->itr_setting);\n-\twr32(hw, I40E_VFINT_ITRN1(I40E_RX_ITR, q_vector->reg_idx),\n-\t q_vector->rx.itr);\n+\tq_vector->rx.target_itr = ITR_TO_REG(rx_ring->itr_setting);\n \n \tq_vector = tx_ring->q_vector;\n-\tq_vector->tx.itr = ITR_TO_REG(tx_ring->itr_setting);\n-\twr32(hw, I40E_VFINT_ITRN1(I40E_TX_ITR, q_vector->reg_idx),\n-\t q_vector->tx.itr);\n+\tq_vector->tx.target_itr = ITR_TO_REG(tx_ring->itr_setting);\n \n-\ti40e_flush(hw);\n+\t/* The interrupt handler itself will take care of programming\n+\t * the Tx and Rx ITR values based on the values we have entered\n+\t * into the q_vector, no need to write the values now.\n+\t */\n }\n \n /**\ndiff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c\nindex f648e5e..3bf6a12 100644\n--- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c\n+++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c\n@@ -354,11 +354,12 @@ i40evf_map_vector_to_rxq(struct i40evf_adapter *adapter, int v_idx, int r_idx)\n \tq_vector->rx.ring = rx_ring;\n \tq_vector->rx.count++;\n \tq_vector->rx.latency_range = I40E_LOW_LATENCY;\n-\tq_vector->rx.itr = ITR_TO_REG(rx_ring->itr_setting);\n+\tq_vector->rx.target_itr = ITR_TO_REG(rx_ring->itr_setting);\n \tq_vector->ring_mask |= BIT(r_idx);\n \tq_vector->itr_countdown = ITR_COUNTDOWN_START;\n \twr32(hw, I40E_VFINT_ITRN1(I40E_RX_ITR, q_vector->reg_idx),\n-\t q_vector->rx.itr);\n+\t q_vector->rx.current_itr);\n+\tq_vector->rx.current_itr = q_vector->rx.target_itr;\n }\n \n /**\n@@ -380,11 +381,12 @@ i40evf_map_vector_to_txq(struct i40evf_adapter *adapter, int v_idx, int t_idx)\n \tq_vector->tx.ring = tx_ring;\n \tq_vector->tx.count++;\n \tq_vector->tx.latency_range = I40E_LOW_LATENCY;\n-\tq_vector->tx.itr = ITR_TO_REG(tx_ring->itr_setting);\n+\tq_vector->tx.target_itr = ITR_TO_REG(tx_ring->itr_setting);\n \tq_vector->itr_countdown = ITR_COUNTDOWN_START;\n \tq_vector->num_ringpairs++;\n \twr32(hw, I40E_VFINT_ITRN1(I40E_TX_ITR, q_vector->reg_idx),\n-\t q_vector->tx.itr);\n+\t q_vector->tx.target_itr);\n+\tq_vector->tx.current_itr = q_vector->tx.target_itr;\n }\n \n /**\n", "prefixes": [ "next", "S85-V1", "13/14" ] }