get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 41662,
    "url": "http://patchwork.dpdk.org/api/patches/41662/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20180627131527.46190-1-qi.z.zhang@intel.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20180627131527.46190-1-qi.z.zhang@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20180627131527.46190-1-qi.z.zhang@intel.com",
    "date": "2018-06-27T13:15:27",
    "name": "[v3] net/i40e: remove VF interrupt handler",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "5d8efd630bd18a3dcfff7fc70b83849d3d2b5a54",
    "submitter": {
        "id": 504,
        "url": "http://patchwork.dpdk.org/api/people/504/?format=api",
        "name": "Qi Zhang",
        "email": "qi.z.zhang@intel.com"
    },
    "delegate": {
        "id": 1540,
        "url": "http://patchwork.dpdk.org/api/users/1540/?format=api",
        "username": "qzhan15",
        "first_name": "Qi",
        "last_name": "Zhang",
        "email": "qi.z.zhang@intel.com"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/20180627131527.46190-1-qi.z.zhang@intel.com/mbox/",
    "series": [
        {
            "id": 264,
            "url": "http://patchwork.dpdk.org/api/series/264/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=264",
            "date": "2018-06-27T13:15:27",
            "name": "[v3] net/i40e: remove VF interrupt handler",
            "version": 3,
            "mbox": "http://patchwork.dpdk.org/series/264/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/41662/comments/",
    "check": "success",
    "checks": "http://patchwork.dpdk.org/api/patches/41662/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 2B5051B8BF;\n\tWed, 27 Jun 2018 15:14:59 +0200 (CEST)",
            "from mga07.intel.com (mga07.intel.com [134.134.136.100])\n\tby dpdk.org (Postfix) with ESMTP id D747F1B613\n\tfor <dev@dpdk.org>; Wed, 27 Jun 2018 15:14:56 +0200 (CEST)",
            "from orsmga002.jf.intel.com ([10.7.209.21])\n\tby orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t27 Jun 2018 06:14:54 -0700",
            "from dpdk51.sh.intel.com ([10.67.110.190])\n\tby orsmga002.jf.intel.com with ESMTP; 27 Jun 2018 06:14:53 -0700"
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.51,279,1526367600\"; d=\"scan'208\";a=\"70426769\"",
        "From": "Qi Zhang <qi.z.zhang@intel.com>",
        "To": "beilei.xing@intel.com",
        "Cc": "jingjing.wu@intel.com, de.yu@intel.com, dev@dpdk.org,\n\tQi Zhang <qi.z.zhang@intel.com>",
        "Date": "Wed, 27 Jun 2018 21:15:27 +0800",
        "Message-Id": "<20180627131527.46190-1-qi.z.zhang@intel.com>",
        "X-Mailer": "git-send-email 2.13.6",
        "Subject": "[dpdk-dev] [PATCH v3] net/i40e: remove VF interrupt handler",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "For i40evf, internal rx interrupt and adminq interrupt share the same\nsource, that cause a lot cpu cycles be wasted on interrupt handler\non rx path. This is complained by customers which require low latency\n(when set I40E_ITR_INTERVAL to small value), but have to be sufferred by\ntremendous interrupts handling that eat significant CPU resources.\n\nThe patch disable pci interrupt and remove the interrupt handler,\nreplace it with a low frequency (50ms) interrupt polling daemon\nwhich is implemented by registering a alarm callback periodly, this\nsave CPU time significently: On a typical x86 server with 2.1GHz CPU,\nwith low latency configure (32us) we saw CPU usage from top commmand\nreduced from 20% to 0% on management core in testpmd).\n\nAlso with the new method we can remove compile option: I40E_ITR_INTERVAL\nwhich is used to balance between low latency and low CPU usage previously.\nNow we don't need it since we can reach both at same time.\n\nSuggested-by: Jingjing Wu <jingjing.wu@intel.com>\nSigned-off-by: Qi Zhang <qi.z.zhang@intel.com>\n---\n\nv3:\n- update doc\n- update comment in i40evf_dev_start.\n\nv2:\n- update doc\n\n config/common_base                |  2 --\n doc/guides/nics/i40e.rst          | 15 -------------\n drivers/net/i40e/i40e_ethdev.c    |  3 +--\n drivers/net/i40e/i40e_ethdev.h    | 22 ++++++++++----------\n drivers/net/i40e/i40e_ethdev_vf.c | 44 +++++++++++++--------------------------\n 5 files changed, 27 insertions(+), 59 deletions(-)",
    "diff": "diff --git a/config/common_base b/config/common_base\nindex fcf3a1f6f..d3f91dfe0 100644\n--- a/config/common_base\n+++ b/config/common_base\n@@ -264,8 +264,6 @@ CONFIG_RTE_LIBRTE_I40E_INC_VECTOR=y\n CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC=n\n CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_PF=64\n CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VM=4\n-# interval up to 8160 us, aligned to 2 (or default value)\n-CONFIG_RTE_LIBRTE_I40E_ITR_INTERVAL=-1\n \n #\n # Compile burst-oriented FM10K PMD\ndiff --git a/doc/guides/nics/i40e.rst b/doc/guides/nics/i40e.rst\nindex 18549bf5a..d5b02c95f 100644\n--- a/doc/guides/nics/i40e.rst\n+++ b/doc/guides/nics/i40e.rst\n@@ -96,11 +96,6 @@ Please note that enabling debugging options may affect system performance.\n \n   Number of queues reserved for each VMDQ Pool.\n \n-- ``CONFIG_RTE_LIBRTE_I40E_ITR_INTERVAL`` (default ``-1``)\n-\n-  Interrupt Throttling interval.\n-\n-\n Runtime Config Options\n ~~~~~~~~~~~~~~~~~~~~~~\n \n@@ -595,16 +590,6 @@ Use 16 Bytes RX Descriptor Size\n As i40e PMD supports both 16 and 32 bytes RX descriptor sizes, and 16 bytes size can provide helps to high performance of small packets.\n Configuration of ``CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC`` in config files can be changed to use 16 bytes size RX descriptors.\n \n-High Performance and per Packet Latency Tradeoff\n-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n-\n-Due to the hardware design, the interrupt signal inside NIC is needed for per\n-packet descriptor write-back. The minimum interval of interrupts could be set\n-at compile time by ``CONFIG_RTE_LIBRTE_I40E_ITR_INTERVAL`` in configuration files.\n-Though there is a default configuration, the interval could be tuned by the\n-users with that configuration item depends on what the user cares about more,\n-performance or per packet latency.\n-\n Example of getting best performance with l3fwd example\n ------------------------------------------------------\n \ndiff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c\nindex e06e0a20b..c47b9f5f7 100644\n--- a/drivers/net/i40e/i40e_ethdev.c\n+++ b/drivers/net/i40e/i40e_ethdev.c\n@@ -1833,8 +1833,7 @@ __vsi_queues_bind_intr(struct i40e_vsi *vsi, uint16_t msix_vect,\n \t/* Write first RX queue to Link list register as the head element */\n \tif (vsi->type != I40E_VSI_SRIOV) {\n \t\tuint16_t interval =\n-\t\t\ti40e_calc_itr_interval(RTE_LIBRTE_I40E_ITR_INTERVAL, 1,\n-\t\t\t\t\t       pf->support_multi_driver);\n+\t\t\ti40e_calc_itr_interval(1, pf->support_multi_driver);\n \n \t\tif (msix_vect == I40E_MISC_VEC_ID) {\n \t\t\tI40E_WRITE_REG(hw, I40E_PFINT_LNKLST0,\ndiff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h\nindex 79bfc67fc..cb5e5b5d8 100644\n--- a/drivers/net/i40e/i40e_ethdev.h\n+++ b/drivers/net/i40e/i40e_ethdev.h\n@@ -184,7 +184,7 @@ enum i40e_flxpld_layer_idx {\n #define I40E_ITR_INDEX_NONE             3\n #define I40E_QUEUE_ITR_INTERVAL_DEFAULT 32 /* 32 us */\n #define I40E_QUEUE_ITR_INTERVAL_MAX     8160 /* 8160 us */\n-#define I40E_VF_QUEUE_ITR_INTERVAL_DEFAULT 8160 /* 8160 us */\n+#define I40E_VF_QUEUE_ITR_INTERVAL_DEFAULT 32 /* 32 us */\n /* Special FW support this floating VEB feature */\n #define FLOATING_VEB_SUPPORTED_FW_MAJ 5\n #define FLOATING_VEB_SUPPORTED_FW_MIN 0\n@@ -1318,17 +1318,17 @@ i40e_align_floor(int n)\n }\n \n static inline uint16_t\n-i40e_calc_itr_interval(int16_t interval, bool is_pf, bool is_multi_drv)\n+i40e_calc_itr_interval(bool is_pf, bool is_multi_drv)\n {\n-\tif (interval < 0 || interval > I40E_QUEUE_ITR_INTERVAL_MAX) {\n-\t\tif (is_multi_drv) {\n-\t\t\tinterval = I40E_QUEUE_ITR_INTERVAL_MAX;\n-\t\t} else {\n-\t\t\tif (is_pf)\n-\t\t\t\tinterval = I40E_QUEUE_ITR_INTERVAL_DEFAULT;\n-\t\t\telse\n-\t\t\t\tinterval = I40E_VF_QUEUE_ITR_INTERVAL_DEFAULT;\n-\t\t}\n+\tuint16_t interval = 0;\n+\n+\tif (is_multi_drv) {\n+\t\tinterval = I40E_QUEUE_ITR_INTERVAL_MAX;\n+\t} else {\n+\t\tif (is_pf)\n+\t\t\tinterval = I40E_QUEUE_ITR_INTERVAL_DEFAULT;\n+\t\telse\n+\t\t\tinterval = I40E_VF_QUEUE_ITR_INTERVAL_DEFAULT;\n \t}\n \n \t/* Convert to hardware count, as writing each 1 represents 2 us */\ndiff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c\nindex 86b38d202..7000b8aba 100644\n--- a/drivers/net/i40e/i40e_ethdev_vf.c\n+++ b/drivers/net/i40e/i40e_ethdev_vf.c\n@@ -44,6 +44,8 @@\n #define I40EVF_BUSY_WAIT_COUNT 50\n #define MAX_RESET_WAIT_CNT     20\n \n+#define I40EVF_ALARM_INTERVAL 50000 /* us */\n+\n struct i40evf_arq_msg_info {\n \tenum virtchnl_ops ops;\n \tenum i40e_status_code result;\n@@ -1133,7 +1135,7 @@ i40evf_init_vf(struct rte_eth_dev *dev)\n \tstruct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n \tstruct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);\n \tuint16_t interval =\n-\t\ti40e_calc_itr_interval(RTE_LIBRTE_I40E_ITR_INTERVAL, 0, 0);\n+\t\ti40e_calc_itr_interval(0, 0);\n \n \tvf->adapter = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);\n \tvf->dev_data = dev->data;\n@@ -1370,7 +1372,7 @@ i40evf_handle_aq_msg(struct rte_eth_dev *dev)\n  *  void\n  */\n static void\n-i40evf_dev_interrupt_handler(void *param)\n+i40evf_dev_alarm_handler(void *param)\n {\n \tstruct rte_eth_dev *dev = (struct rte_eth_dev *)param;\n \tstruct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n@@ -1399,6 +1401,8 @@ i40evf_dev_interrupt_handler(void *param)\n \n done:\n \ti40evf_enable_irq0(hw);\n+\trte_eal_alarm_set(I40EVF_ALARM_INTERVAL,\n+\t\t\t  i40evf_dev_alarm_handler, dev);\n }\n \n static int\n@@ -1442,12 +1446,8 @@ i40evf_dev_init(struct rte_eth_dev *eth_dev)\n \t\treturn -1;\n \t}\n \n-\t/* register callback func to eal lib */\n-\trte_intr_callback_register(&pci_dev->intr_handle,\n-\t\ti40evf_dev_interrupt_handler, (void *)eth_dev);\n-\n-\t/* enable uio intr after callback register */\n-\trte_intr_enable(&pci_dev->intr_handle);\n+\trte_eal_alarm_set(I40EVF_ALARM_INTERVAL,\n+\t\t\t  i40evf_dev_alarm_handler, eth_dev);\n \n \t/* configure and enable device interrupt */\n \ti40evf_enable_irq0(hw);\n@@ -1836,7 +1836,7 @@ i40evf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)\n \tstruct rte_intr_handle *intr_handle = &pci_dev->intr_handle;\n \tstruct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n \tuint16_t interval =\n-\t\ti40e_calc_itr_interval(RTE_LIBRTE_I40E_ITR_INTERVAL, 0, 0);\n+\t\ti40e_calc_itr_interval(0, 0);\n \tuint16_t msix_intr;\n \n \tmsix_intr = intr_handle->intr_vec[queue_id];\n@@ -1859,8 +1859,6 @@ i40evf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)\n \n \tI40EVF_WRITE_FLUSH(hw);\n \n-\trte_intr_enable(&pci_dev->intr_handle);\n-\n \treturn 0;\n }\n \n@@ -2016,17 +2014,9 @@ i40evf_dev_start(struct rte_eth_dev *dev)\n \t\tgoto err_mac;\n \t}\n \n-\t/* When a VF port is bound to VFIO-PCI, only miscellaneous interrupt\n-\t * is mapped to VFIO vector 0 in i40evf_dev_init( ).\n-\t * If previous VFIO interrupt mapping set in i40evf_dev_init( ) is\n-\t * not cleared, it will fail when rte_intr_enable( ) tries to map Rx\n-\t * queue interrupt to other VFIO vectors.\n-\t * So clear uio/vfio intr/evevnfd first to avoid failure.\n-\t */\n-\tif (dev->data->dev_conf.intr_conf.rxq != 0) {\n-\t\trte_intr_disable(intr_handle);\n+\t/* only enable interrupt in rx interrupt mode */\n+\tif (dev->data->dev_conf.intr_conf.rxq != 0)\n \t\trte_intr_enable(intr_handle);\n-\t}\n \n \ti40evf_enable_queues_intr(dev);\n \n@@ -2050,6 +2040,9 @@ i40evf_dev_stop(struct rte_eth_dev *dev)\n \n \tPMD_INIT_FUNC_TRACE();\n \n+\tif (dev->data->dev_conf.intr_conf.rxq != 0)\n+\t\trte_intr_disable(intr_handle);\n+\n \tif (hw->adapter_stopped == 1)\n \t\treturn;\n \ti40evf_stop_queues(dev);\n@@ -2284,9 +2277,8 @@ static void\n i40evf_dev_close(struct rte_eth_dev *dev)\n {\n \tstruct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n-\tstruct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);\n-\tstruct rte_intr_handle *intr_handle = &pci_dev->intr_handle;\n \n+\trte_eal_alarm_cancel(i40evf_dev_alarm_handler, dev);\n \ti40evf_dev_stop(dev);\n \ti40e_dev_free_queues(dev);\n \t/*\n@@ -2299,12 +2291,6 @@ i40evf_dev_close(struct rte_eth_dev *dev)\n \n \ti40evf_reset_vf(hw);\n \ti40e_shutdown_adminq(hw);\n-\t/* disable uio intr before callback unregister */\n-\trte_intr_disable(intr_handle);\n-\n-\t/* unregister callback func from eal lib */\n-\trte_intr_callback_unregister(intr_handle,\n-\t\t\t\t     i40evf_dev_interrupt_handler, dev);\n \ti40evf_disable_irq0(hw);\n }\n \n",
    "prefixes": [
        "v3"
    ]
}