get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/670160/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 670160,
    "url": "http://patchwork.ozlabs.org/api/patches/670160/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/1473895479-23035-9-git-send-email-bimmy.pujari@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": "<1473895479-23035-9-git-send-email-bimmy.pujari@intel.com>",
    "list_archive_url": null,
    "date": "2016-09-14T23:24:38",
    "name": "[next,S47,8/9] i40e/i40evf: fix interrupt affinity bug",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "3d19200f59e48d508b93b82e78383dfa0789feaa",
    "submitter": {
        "id": 68919,
        "url": "http://patchwork.ozlabs.org/api/people/68919/?format=api",
        "name": "Pujari, Bimmy",
        "email": "bimmy.pujari@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/1473895479-23035-9-git-send-email-bimmy.pujari@intel.com/mbox/",
    "series": [],
    "comments": "http://patchwork.ozlabs.org/api/patches/670160/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/670160/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<intel-wired-lan-bounces@lists.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"
        ],
        "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 3sZHhh6G8kz9s8x\n\tfor <incoming@patchwork.ozlabs.org>;\n\tThu, 15 Sep 2016 09:25:24 +1000 (AEST)",
            "from localhost (localhost [127.0.0.1])\n\tby fraxinus.osuosl.org (Postfix) with ESMTP id 7225186732;\n\tWed, 14 Sep 2016 23:25:23 +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 F-AWj4xjGbla; Wed, 14 Sep 2016 23:25:20 +0000 (UTC)",
            "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby fraxinus.osuosl.org (Postfix) with ESMTP id BED2786FE6;\n\tWed, 14 Sep 2016 23:25:19 +0000 (UTC)",
            "from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138])\n\tby ash.osuosl.org (Postfix) with ESMTP id C15621C1F19\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tWed, 14 Sep 2016 23:25:14 +0000 (UTC)",
            "from localhost (localhost [127.0.0.1])\n\tby whitealder.osuosl.org (Postfix) with ESMTP id C053C8BD8E\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tWed, 14 Sep 2016 23:25:14 +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 tcfYPvNLWEnh for <intel-wired-lan@lists.osuosl.org>;\n\tWed, 14 Sep 2016 23:25:13 +0000 (UTC)",
            "from mga09.intel.com (mga09.intel.com [134.134.136.24])\n\tby whitealder.osuosl.org (Postfix) with ESMTPS id 7CA3D8BE1E\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tWed, 14 Sep 2016 23:25:13 +0000 (UTC)",
            "from fmsmga006.fm.intel.com ([10.253.24.20])\n\tby orsmga102.jf.intel.com with ESMTP; 14 Sep 2016 16:25:13 -0700",
            "from bimmy.jf.intel.com (HELO bimmy.linux1.jf.intel.com)\n\t([134.134.2.177])\n\tby fmsmga006.fm.intel.com with ESMTP; 14 Sep 2016 16:25:12 -0700"
        ],
        "X-Virus-Scanned": [
            "amavisd-new at osuosl.org",
            "amavisd-new at osuosl.org"
        ],
        "X-Greylist": "domain auto-whitelisted by SQLgrey-1.7.6",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.30,336,1470726000\"; d=\"scan'208\";a=\"8507724\"",
        "From": "Bimmy Pujari <bimmy.pujari@intel.com>",
        "To": "intel-wired-lan@lists.osuosl.org",
        "Date": "Wed, 14 Sep 2016 16:24:38 -0700",
        "Message-Id": "<1473895479-23035-9-git-send-email-bimmy.pujari@intel.com>",
        "X-Mailer": "git-send-email 2.4.11",
        "In-Reply-To": "<1473895479-23035-1-git-send-email-bimmy.pujari@intel.com>",
        "References": "<1473895479-23035-1-git-send-email-bimmy.pujari@intel.com>",
        "Cc": "Alan Brady <alan.brady@intel.com>",
        "Subject": "[Intel-wired-lan] [next PATCH S47 8/9] i40e/i40evf: fix interrupt\n\taffinity bug",
        "X-BeenThere": "intel-wired-lan@lists.osuosl.org",
        "X-Mailman-Version": "2.1.18-1",
        "Precedence": "list",
        "List-Id": "Intel Wired Ethernet Linux Kernel Driver Development\n\t<intel-wired-lan.lists.osuosl.org>",
        "List-Unsubscribe": "<http://lists.osuosl.org/mailman/options/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@lists.osuosl.org?subject=unsubscribe>",
        "List-Archive": "<http://lists.osuosl.org/pipermail/intel-wired-lan/>",
        "List-Post": "<mailto:intel-wired-lan@lists.osuosl.org>",
        "List-Help": "<mailto:intel-wired-lan-request@lists.osuosl.org?subject=help>",
        "List-Subscribe": "<http://lists.osuosl.org/mailman/listinfo/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@lists.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@lists.osuosl.org",
        "Sender": "\"Intel-wired-lan\" <intel-wired-lan-bounces@lists.osuosl.org>"
    },
    "content": "From: Alan Brady <alan.brady@intel.com>\n\nThere exists a bug in which a 'perfect storm' can occur and cause\ninterrupts to fail to be correctly affinitized. This causes unexpected\nbehavior and has a substantial impact on performance when it happens.\n\nThe bug occurs if there is heavy traffic, any number of CPUs that have\nan i40e interrupt are pegged at 100%, and the interrupt afffinity for\nthose CPUs is changed.  Instead of moving to the new CPU, the interrupt\ncontinues to be polled while there is heavy traffic.\n\nThe bug is most readily realized as the driver is first brought up and\nall interrupts start on CPU0. If there is heavy traffic and the\ninterrupt starts polling before the interrupt is affinitized, the\ninterrupt will be stuck on CPU0 until traffic stops. The bug, however,\ncan also be wrought out more simply by affinitizing all the interrupts\nto a single CPU and then attempting to move any of those interrupts off\nwhile there is heavy traffic.\n\nThis patch fixes the bug by registering for update notifications from\nthe kernel when the interrupt affinity changes. When that fires, we\ncache the intended affinity mask. Then, while polling, if the cpu is\npegged at 100% and we failed to clean the rings, we check to make sure\nwe have the correct affinity and stop polling if we're firing on the\nwrong CPU.  When the kernel successfully moves the interrupt, it will\nstart polling on the correct CPU. The performance impact is minimal\nsince the only time this section gets executed is when performance is\nalready compromised by the CPU.\n\nSigned-off-by: Alan Brady <alan.brady@intel.com>\nChange-ID: I4410a880159b9dba1f8297aa72bef36dca34e830\n---\nTesting-hints:\n    1.  Bring up ethx.\n    2.  Set affinity for all traffic interrupts to CPU0\n    3.  Start heavy traffic.\n    4.  Attempt to change affinity for any/all interrupts.\n        Expected:  IRQ correctly moves to the new cpu\n        Actual:  IRQ continues to poll on CPU0 and performance is\n                 severely impacted.\n\n drivers/net/ethernet/intel/i40e/i40e.h          |  2 +\n drivers/net/ethernet/intel/i40e/i40e_main.c     | 64 +++++++++++++++++-----\n drivers/net/ethernet/intel/i40e/i40e_txrx.c     | 36 ++++++++++---\n drivers/net/ethernet/intel/i40evf/i40e_txrx.c   | 31 +++++++++--\n drivers/net/ethernet/intel/i40evf/i40evf.h      |  3 +-\n drivers/net/ethernet/intel/i40evf/i40evf_main.c | 71 +++++++++++++++++--------\n 6 files changed, 159 insertions(+), 48 deletions(-)",
    "diff": "diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h\nindex 29bc649..69c0466 100644\n--- a/drivers/net/ethernet/intel/i40e/i40e.h\n+++ b/drivers/net/ethernet/intel/i40e/i40e.h\n@@ -611,6 +611,8 @@ struct i40e_q_vector {\n \tunsigned long hung_detected; /* Set/Reset for hung_detection logic */\n \n \tcpumask_t affinity_mask;\n+\tstruct irq_affinity_notify affinity_notify;\n+\n \tstruct rcu_head rcu;\t/* to avoid race with update stats on free */\n \tchar name[I40E_INT_NAME_STR_LEN];\n \tbool arm_wb_state;\ndiff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c\nindex e18fc4a..d7169d0 100644\n--- a/drivers/net/ethernet/intel/i40e/i40e_main.c\n+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c\n@@ -3310,6 +3310,33 @@ static irqreturn_t i40e_msix_clean_rings(int irq, void *data)\n }\n \n /**\n+ * i40e_irq_affinity_notify - Callback for affinity changes\n+ * @notify: context as to what irq was changed\n+ * @mask: the new affinity mask\n+ *\n+ * This is a callback function used by the irq_set_affinity_notifier function\n+ * so that we may register to receive changes to the irq affinity masks.\n+ **/\n+static void i40e_irq_affinity_notify(struct irq_affinity_notify *notify,\n+\t\t\t\t     const cpumask_t *mask)\n+{\n+\tstruct i40e_q_vector *q_vector =\n+\t\tcontainer_of(notify, struct i40e_q_vector, affinity_notify);\n+\n+\tq_vector->affinity_mask = *mask;\n+}\n+\n+/**\n+ * i40e_irq_affinity_release - Callback for affinity notifier release\n+ * @ref: internal core kernel usage\n+ *\n+ * This is a callback function used by the irq_set_affinity_notifier function\n+ * to inform the current notification subscriber that they will no longer\n+ * receive notifications.\n+ **/\n+static void i40e_irq_affinity_release(struct kref *ref) {}\n+\n+/**\n  * i40e_vsi_request_irq_msix - Initialize MSI-X interrupts\n  * @vsi: the VSI being configured\n  * @basename: name for the vector\n@@ -3324,10 +3351,13 @@ static int i40e_vsi_request_irq_msix(struct i40e_vsi *vsi, char *basename)\n \tint rx_int_idx = 0;\n \tint tx_int_idx = 0;\n \tint vector, err;\n+\tint irq_num;\n \n \tfor (vector = 0; vector < q_vectors; vector++) {\n \t\tstruct i40e_q_vector *q_vector = vsi->q_vectors[vector];\n \n+\t\tirq_num = pf->msix_entries[base + vector].vector;\n+\n \t\tif (q_vector->tx.ring && q_vector->rx.ring) {\n \t\t\tsnprintf(q_vector->name, sizeof(q_vector->name) - 1,\n \t\t\t\t \"%s-%s-%d\", basename, \"TxRx\", rx_int_idx++);\n@@ -3342,7 +3372,7 @@ static int i40e_vsi_request_irq_msix(struct i40e_vsi *vsi, char *basename)\n \t\t\t/* skip this unused q_vector */\n \t\t\tcontinue;\n \t\t}\n-\t\terr = request_irq(pf->msix_entries[base + vector].vector,\n+\t\terr = request_irq(irq_num,\n \t\t\t\t  vsi->irq_handler,\n \t\t\t\t  0,\n \t\t\t\t  q_vector->name,\n@@ -3352,9 +3382,13 @@ static int i40e_vsi_request_irq_msix(struct i40e_vsi *vsi, char *basename)\n \t\t\t\t \"MSIX request_irq failed, error: %d\\n\", err);\n \t\t\tgoto free_queue_irqs;\n \t\t}\n+\n+\t\t/* register for affinity change notifications */\n+\t\tq_vector->affinity_notify.notify = i40e_irq_affinity_notify;\n+\t\tq_vector->affinity_notify.release = i40e_irq_affinity_release;\n+\t\tirq_set_affinity_notifier(irq_num, &q_vector->affinity_notify);\n \t\t/* assign the mask for this irq */\n-\t\tirq_set_affinity_hint(pf->msix_entries[base + vector].vector,\n-\t\t\t\t      &q_vector->affinity_mask);\n+\t\tirq_set_affinity_hint(irq_num, &q_vector->affinity_mask);\n \t}\n \n \tvsi->irqs_ready = true;\n@@ -3363,10 +3397,10 @@ static int i40e_vsi_request_irq_msix(struct i40e_vsi *vsi, char *basename)\n free_queue_irqs:\n \twhile (vector) {\n \t\tvector--;\n-\t\tirq_set_affinity_hint(pf->msix_entries[base + vector].vector,\n-\t\t\t\t      NULL);\n-\t\tfree_irq(pf->msix_entries[base + vector].vector,\n-\t\t\t &(vsi->q_vectors[vector]));\n+\t\tirq_num = pf->msix_entries[base + vector].vector;\n+\t\tirq_set_affinity_notifier(irq_num, NULL);\n+\t\tirq_set_affinity_hint(irq_num, NULL);\n+\t\tfree_irq(irq_num, &vsi->q_vectors[vector]);\n \t}\n \treturn err;\n }\n@@ -4005,19 +4039,23 @@ static void i40e_vsi_free_irq(struct i40e_vsi *vsi)\n \n \t\tvsi->irqs_ready = false;\n \t\tfor (i = 0; i < vsi->num_q_vectors; i++) {\n-\t\t\tu16 vector = i + base;\n+\t\t\tint irq_num;\n+\t\t\tu16 vector;\n+\n+\t\t\tvector = i + base;\n+\t\t\tirq_num = pf->msix_entries[vector].vector;\n \n \t\t\t/* free only the irqs that were actually requested */\n \t\t\tif (!vsi->q_vectors[i] ||\n \t\t\t    !vsi->q_vectors[i]->num_ringpairs)\n \t\t\t\tcontinue;\n \n+\t\t\t/* clear the affinity notifier in the IRQ descriptor */\n+\t\t\tirq_set_affinity_notifier(irq_num, NULL);\n \t\t\t/* clear the affinity_mask in the IRQ descriptor */\n-\t\t\tirq_set_affinity_hint(pf->msix_entries[vector].vector,\n-\t\t\t\t\t      NULL);\n-\t\t\tsynchronize_irq(pf->msix_entries[vector].vector);\n-\t\t\tfree_irq(pf->msix_entries[vector].vector,\n-\t\t\t\t vsi->q_vectors[i]);\n+\t\t\tirq_set_affinity_hint(irq_num, NULL);\n+\t\t\tsynchronize_irq(irq_num);\n+\t\t\tfree_irq(irq_num, vsi->q_vectors[i]);\n \n \t\t\t/* Tear down the interrupt queue link list\n \t\t\t *\ndiff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c\nindex eba16a1..587f596 100644\n--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c\n+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c\n@@ -1999,12 +1999,25 @@ int i40e_napi_poll(struct napi_struct *napi, int budget)\n \n \t/* If work not completed, return budget and polling will return */\n \tif (!clean_complete) {\n+\t\tconst cpumask_t *aff_mask = &q_vector->affinity_mask;\n+\t\tint cpu_id = smp_processor_id();\n+\n+\t\t/* It is possible that the interrupt affinity has changed but,\n+\t\t * if the cpu is pegged at 100%, polling will never exit while\n+\t\t * traffic continues and the interrupt will be stuck on this\n+\t\t * cpu.  We check to make sure affinity is correct before we\n+\t\t * continue to poll, otherwise we must stop polling so the\n+\t\t * interrupt can move to the correct cpu.\n+\t\t */\n+\t\tif (likely(cpumask_test_cpu(cpu_id, aff_mask) ||\n+\t\t\t   !(vsi->back->flags & I40E_FLAG_MSIX_ENABLED))) {\n tx_only:\n-\t\tif (arm_wb) {\n-\t\t\tq_vector->tx.ring[0].tx_stats.tx_force_wb++;\n-\t\t\ti40e_enable_wb_on_itr(vsi, q_vector);\n+\t\t\tif (arm_wb) {\n+\t\t\t\tq_vector->tx.ring[0].tx_stats.tx_force_wb++;\n+\t\t\t\ti40e_enable_wb_on_itr(vsi, q_vector);\n+\t\t\t}\n+\t\t\treturn budget;\n \t\t}\n-\t\treturn budget;\n \t}\n \n \tif (vsi->back->flags & I40E_TXR_FLAGS_WB_ON_ITR)\n@@ -2012,11 +2025,18 @@ tx_only:\n \n \t/* Work is done so exit the polling mode and re-enable the interrupt */\n \tnapi_complete_done(napi, work_done);\n-\tif (vsi->back->flags & I40E_FLAG_MSIX_ENABLED) {\n-\t\ti40e_update_enable_itr(vsi, q_vector);\n-\t} else { /* Legacy mode */\n+\n+\t/* If we're prematurely stopping polling to fix the interrupt\n+\t * affinity we want to make sure polling starts back up so we\n+\t * issue a call to i40e_force_wb which triggers a SW interrupt.\n+\t */\n+\tif (!clean_complete)\n+\t\ti40e_force_wb(vsi, q_vector);\n+\telse if (!(vsi->back->flags & I40E_FLAG_MSIX_ENABLED))\n \t\ti40e_irq_dynamic_enable_icr0(vsi->back, false);\n-\t}\n+\telse\n+\t\ti40e_update_enable_itr(vsi, q_vector);\n+\n \treturn 0;\n }\n \ndiff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c\nindex 75f2a2c..dd8ad6b 100644\n--- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c\n+++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c\n@@ -1461,12 +1461,24 @@ int i40evf_napi_poll(struct napi_struct *napi, int budget)\n \n \t/* If work not completed, return budget and polling will return */\n \tif (!clean_complete) {\n+\t\tconst cpumask_t *aff_mask = &q_vector->affinity_mask;\n+\t\tint cpu_id = smp_processor_id();\n+\n+\t\t/* It is possible that the interrupt affinity has changed but,\n+\t\t * if the cpu is pegged at 100%, polling will never exit while\n+\t\t * traffic continues and the interrupt will be stuck on this\n+\t\t * cpu.  We check to make sure affinity is correct before we\n+\t\t * continue to poll, otherwise we must stop polling so the\n+\t\t * interrupt can move to the correct cpu.\n+\t\t */\n+\t\tif (likely(cpumask_test_cpu(cpu_id, aff_mask))) {\n tx_only:\n-\t\tif (arm_wb) {\n-\t\t\tq_vector->tx.ring[0].tx_stats.tx_force_wb++;\n-\t\t\ti40e_enable_wb_on_itr(vsi, q_vector);\n+\t\t\tif (arm_wb) {\n+\t\t\t\tq_vector->tx.ring[0].tx_stats.tx_force_wb++;\n+\t\t\t\ti40e_enable_wb_on_itr(vsi, q_vector);\n+\t\t\t}\n+\t\t\treturn budget;\n \t\t}\n-\t\treturn budget;\n \t}\n \n \tif (vsi->back->flags & I40E_TXR_FLAGS_WB_ON_ITR)\n@@ -1474,7 +1486,16 @@ tx_only:\n \n \t/* Work is done so exit the polling mode and re-enable the interrupt */\n \tnapi_complete_done(napi, work_done);\n-\ti40e_update_enable_itr(vsi, q_vector);\n+\n+\t/* If we're prematurely stopping polling to fix the interrupt\n+\t * affinity we want to make sure polling starts back up so we\n+\t * issue a call to i40evf_force_wb which triggers a SW interrupt.\n+\t */\n+\tif (!clean_complete)\n+\t\ti40evf_force_wb(vsi, q_vector);\n+\telse\n+\t\ti40e_update_enable_itr(vsi, q_vector);\n+\n \treturn 0;\n }\n \ndiff --git a/drivers/net/ethernet/intel/i40evf/i40evf.h b/drivers/net/ethernet/intel/i40evf/i40evf.h\nindex c5fd724..fffe4cf 100644\n--- a/drivers/net/ethernet/intel/i40evf/i40evf.h\n+++ b/drivers/net/ethernet/intel/i40evf/i40evf.h\n@@ -107,7 +107,8 @@ struct i40e_q_vector {\n \tint v_idx;\t/* vector index in list */\n \tchar name[IFNAMSIZ + 9];\n \tbool arm_wb_state;\n-\tcpumask_var_t affinity_mask;\n+\tcpumask_t affinity_mask;\n+\tstruct irq_affinity_notify affinity_notify;\n };\n \n /* Helper macros to switch between ints/sec and what the register uses.\ndiff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c\nindex 1437281..0881b4e 100644\n--- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c\n+++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c\n@@ -496,6 +496,33 @@ static void i40evf_netpoll(struct net_device *netdev)\n \n #endif\n /**\n+ * i40evf_irq_affinity_notify - Callback for affinity changes\n+ * @notify: context as to what irq was changed\n+ * @mask: the new affinity mask\n+ *\n+ * This is a callback function used by the irq_set_affinity_notifier function\n+ * so that we may register to receive changes to the irq affinity masks.\n+ **/\n+static void i40evf_irq_affinity_notify(struct irq_affinity_notify *notify,\n+\t\t\t\t       const cpumask_t *mask)\n+{\n+\tstruct i40e_q_vector *q_vector =\n+\t\tcontainer_of(notify, struct i40e_q_vector, affinity_notify);\n+\n+\tq_vector->affinity_mask = *mask;\n+}\n+\n+/**\n+ * i40evf_irq_affinity_release - Callback for affinity notifier release\n+ * @ref: internal core kernel usage\n+ *\n+ * This is a callback function used by the irq_set_affinity_notifier function\n+ * to inform the current notification subscriber that they will no longer\n+ * receive notifications.\n+ **/\n+static void i40evf_irq_affinity_release(struct kref *ref) {}\n+\n+/**\n  * i40evf_request_traffic_irqs - Initialize MSI-X interrupts\n  * @adapter: board private structure\n  *\n@@ -507,6 +534,7 @@ i40evf_request_traffic_irqs(struct i40evf_adapter *adapter, char *basename)\n {\n \tint vector, err, q_vectors;\n \tint rx_int_idx = 0, tx_int_idx = 0;\n+\tint irq_num;\n \n \ti40evf_irq_disable(adapter);\n \t/* Decrement for Other and TCP Timer vectors */\n@@ -514,6 +542,7 @@ i40evf_request_traffic_irqs(struct i40evf_adapter *adapter, char *basename)\n \n \tfor (vector = 0; vector < q_vectors; vector++) {\n \t\tstruct i40e_q_vector *q_vector = &adapter->q_vectors[vector];\n+\t\tirq_num = adapter->msix_entries[vector + NONQ_VECS].vector;\n \n \t\tif (q_vector->tx.ring && q_vector->rx.ring) {\n \t\t\tsnprintf(q_vector->name, sizeof(q_vector->name) - 1,\n@@ -532,21 +561,23 @@ i40evf_request_traffic_irqs(struct i40evf_adapter *adapter, char *basename)\n \t\t\t/* skip this unused q_vector */\n \t\t\tcontinue;\n \t\t}\n-\t\terr = request_irq(\n-\t\t\tadapter->msix_entries[vector + NONQ_VECS].vector,\n-\t\t\ti40evf_msix_clean_rings,\n-\t\t\t0,\n-\t\t\tq_vector->name,\n-\t\t\tq_vector);\n+\t\terr = request_irq(irq_num,\n+\t\t\t\t  i40evf_msix_clean_rings,\n+\t\t\t\t  0,\n+\t\t\t\t  q_vector->name,\n+\t\t\t\t  q_vector);\n \t\tif (err) {\n \t\t\tdev_info(&adapter->pdev->dev,\n \t\t\t\t \"Request_irq failed, error: %d\\n\", err);\n \t\t\tgoto free_queue_irqs;\n \t\t}\n+\t\t/* register for affinity change notifications */\n+\t\tq_vector->affinity_notify.notify = i40evf_irq_affinity_notify;\n+\t\tq_vector->affinity_notify.release =\n+\t\t\t\t\t\t   i40evf_irq_affinity_release;\n+\t\tirq_set_affinity_notifier(irq_num, &q_vector->affinity_notify);\n \t\t/* assign the mask for this irq */\n-\t\tirq_set_affinity_hint(\n-\t\t\tadapter->msix_entries[vector + NONQ_VECS].vector,\n-\t\t\tq_vector->affinity_mask);\n+\t\tirq_set_affinity_hint(irq_num, &q_vector->affinity_mask);\n \t}\n \n \treturn 0;\n@@ -554,11 +585,10 @@ i40evf_request_traffic_irqs(struct i40evf_adapter *adapter, char *basename)\n free_queue_irqs:\n \twhile (vector) {\n \t\tvector--;\n-\t\tirq_set_affinity_hint(\n-\t\t\tadapter->msix_entries[vector + NONQ_VECS].vector,\n-\t\t\tNULL);\n-\t\tfree_irq(adapter->msix_entries[vector + NONQ_VECS].vector,\n-\t\t\t &adapter->q_vectors[vector]);\n+\t\tirq_num = adapter->msix_entries[vector + NONQ_VECS].vector;\n+\t\tirq_set_affinity_notifier(irq_num, NULL);\n+\t\tirq_set_affinity_hint(irq_num, NULL);\n+\t\tfree_irq(irq_num, &adapter->q_vectors[vector]);\n \t}\n \treturn err;\n }\n@@ -599,16 +629,15 @@ static int i40evf_request_misc_irq(struct i40evf_adapter *adapter)\n  **/\n static void i40evf_free_traffic_irqs(struct i40evf_adapter *adapter)\n {\n-\tint i;\n-\tint q_vectors;\n+\tint vector, irq_num, q_vectors;\n \n \tq_vectors = adapter->num_msix_vectors - NONQ_VECS;\n \n-\tfor (i = 0; i < q_vectors; i++) {\n-\t\tirq_set_affinity_hint(adapter->msix_entries[i+1].vector,\n-\t\t\t\t      NULL);\n-\t\tfree_irq(adapter->msix_entries[i+1].vector,\n-\t\t\t &adapter->q_vectors[i]);\n+\tfor (vector = 0; vector < q_vectors; vector++) {\n+\t\tirq_num = adapter->msix_entries[vector + NONQ_VECS].vector;\n+\t\tirq_set_affinity_notifier(irq_num, NULL);\n+\t\tirq_set_affinity_hint(irq_num, NULL);\n+\t\tfree_irq(irq_num, &adapter->q_vectors[vector]);\n \t}\n }\n \n",
    "prefixes": [
        "next",
        "S47",
        "8/9"
    ]
}