get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 2392,
    "url": "https://patches.dpdk.org/api/patches/2392/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1421747640-20978-4-git-send-email-danny.zhou@intel.com/",
    "project": {
        "id": 1,
        "url": "https://patches.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": "<1421747640-20978-4-git-send-email-danny.zhou@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1421747640-20978-4-git-send-email-danny.zhou@intel.com",
    "date": "2015-01-20T09:53:58",
    "name": "[dpdk-dev,RFC,3/5] eal: add per rx queue interrupt handling based on VFIO",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "e6863974803a695094fa2720b04a0149245d8a09",
    "submitter": {
        "id": 29,
        "url": "https://patches.dpdk.org/api/people/29/?format=api",
        "name": "Zhou, Danny",
        "email": "danny.zhou@intel.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1421747640-20978-4-git-send-email-danny.zhou@intel.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/2392/comments/",
    "check": "pending",
    "checks": "https://patches.dpdk.org/api/patches/2392/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 [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id 211895A99;\n\tTue, 20 Jan 2015 10:54:21 +0100 (CET)",
            "from mga02.intel.com (mga02.intel.com [134.134.136.20])\n\tby dpdk.org (Postfix) with ESMTP id DE8EC5A70\n\tfor <dev@dpdk.org>; Tue, 20 Jan 2015 10:54:18 +0100 (CET)",
            "from fmsmga001.fm.intel.com ([10.253.24.23])\n\tby orsmga101.jf.intel.com with ESMTP; 20 Jan 2015 01:54:17 -0800",
            "from shvmail01.sh.intel.com ([10.239.29.42])\n\tby fmsmga001.fm.intel.com with ESMTP; 20 Jan 2015 01:54:17 -0800",
            "from shecgisg004.sh.intel.com (shecgisg004.sh.intel.com\n\t[10.239.29.89])\n\tby shvmail01.sh.intel.com with ESMTP id t0K9sF4d000486;\n\tTue, 20 Jan 2015 17:54:15 +0800",
            "from shecgisg004.sh.intel.com (localhost [127.0.0.1])\n\tby shecgisg004.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP\n\tid t0K9sCP4021035; Tue, 20 Jan 2015 17:54:14 +0800",
            "(from dyzhou@localhost)\n\tby shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id t0K9sBcG021031; \n\tTue, 20 Jan 2015 17:54:11 +0800"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.09,433,1418112000\"; d=\"scan'208\";a=\"653618708\"",
        "From": "Danny Zhou <danny.zhou@intel.com>",
        "To": "dev@dpdk.org",
        "Date": "Tue, 20 Jan 2015 17:53:58 +0800",
        "Message-Id": "<1421747640-20978-4-git-send-email-danny.zhou@intel.com>",
        "X-Mailer": "git-send-email 1.7.4.1",
        "In-Reply-To": "<1421747640-20978-1-git-send-email-danny.zhou@intel.com>",
        "References": "<1421747640-20978-1-git-send-email-danny.zhou@intel.com>",
        "Subject": "[dpdk-dev] [RFC PATCH 3/5] eal: add per rx queue interrupt handling\n\tbased on VFIO",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "patches and discussions about DPDK <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Signed-off-by: Danny Zhou <danny.zhou@intel.com>\n---\n lib/librte_eal/common/include/rte_eal.h            |   9 ++\n lib/librte_eal/linuxapp/eal/eal_interrupts.c       | 120 ++++++++++++++++++++-\n lib/librte_eal/linuxapp/eal/eal_pci_vfio.c         |  11 +-\n .../linuxapp/eal/include/exec-env/rte_interrupts.h |   3 +\n 4 files changed, 137 insertions(+), 6 deletions(-)",
    "diff": "diff --git a/lib/librte_eal/common/include/rte_eal.h b/lib/librte_eal/common/include/rte_eal.h\nindex f4ecd2e..5f31aa5 100644\n--- a/lib/librte_eal/common/include/rte_eal.h\n+++ b/lib/librte_eal/common/include/rte_eal.h\n@@ -150,6 +150,15 @@ int rte_eal_iopl_init(void);\n  *   - On failure, a negative error value.\n  */\n int rte_eal_init(int argc, char **argv);\n+\n+/**\n+ * @param port_id\n+ *   the port id\n+ * @return\n+ *   - On success, return 0\n+ */\n+int rte_eal_wait_rx_intr(uint8_t port_id, uint8_t queue_id);\n+\n /**\n  * Usage function typedef used by the application usage function.\n  *\ndiff --git a/lib/librte_eal/linuxapp/eal/eal_interrupts.c b/lib/librte_eal/linuxapp/eal/eal_interrupts.c\nindex dc2668a..1be4ba7 100644\n--- a/lib/librte_eal/linuxapp/eal/eal_interrupts.c\n+++ b/lib/librte_eal/linuxapp/eal/eal_interrupts.c\n@@ -64,6 +64,7 @@\n #include <rte_malloc.h>\n #include <rte_errno.h>\n #include <rte_spinlock.h>\n+#include <rte_ethdev.h>\n \n #include \"eal_private.h\"\n #include \"eal_vfio.h\"\n@@ -127,6 +128,7 @@ static pthread_t intr_thread;\n #ifdef VFIO_PRESENT\n \n #define IRQ_SET_BUF_LEN  (sizeof(struct vfio_irq_set) + sizeof(int))\n+#define MSIX_IRQ_SET_BUF_LEN (sizeof(struct vfio_irq_set) + sizeof(int) * (VFIO_MAX_QUEUE_ID + 1))\n \n /* enable legacy (INTx) interrupts */\n static int\n@@ -293,7 +295,7 @@ vfio_disable_msi(struct rte_intr_handle *intr_handle) {\n static int\n vfio_enable_msix(struct rte_intr_handle *intr_handle) {\n \tint len, ret;\n-\tchar irq_set_buf[IRQ_SET_BUF_LEN];\n+\tchar irq_set_buf[MSIX_IRQ_SET_BUF_LEN];\n \tstruct vfio_irq_set *irq_set;\n \tint *fd_ptr;\n \n@@ -301,12 +303,13 @@ vfio_enable_msix(struct rte_intr_handle *intr_handle) {\n \n \tirq_set = (struct vfio_irq_set *) irq_set_buf;\n \tirq_set->argsz = len;\n-\tirq_set->count = 1;\n+\tirq_set->count = VFIO_MAX_QUEUE_ID + 1;\n \tirq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER;\n \tirq_set->index = VFIO_PCI_MSIX_IRQ_INDEX;\n \tirq_set->start = 0;\n \tfd_ptr = (int *) &irq_set->data;\n-\t*fd_ptr = intr_handle->fd;\n+\tmemcpy(fd_ptr, intr_handle->queue_fd, sizeof(intr_handle->queue_fd));\n+\tfd_ptr[VFIO_MAX_QUEUE_ID] = intr_handle->fd;\n \n \tret = ioctl(intr_handle->vfio_dev_fd, VFIO_DEVICE_SET_IRQS, irq_set);\n \n@@ -323,7 +326,7 @@ vfio_enable_msix(struct rte_intr_handle *intr_handle) {\n \tirq_set->count = 1;\n \tirq_set->flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_TRIGGER;\n \tirq_set->index = VFIO_PCI_MSIX_IRQ_INDEX;\n-\tirq_set->start = 0;\n+\tirq_set->start = VFIO_MAX_QUEUE_ID;\n \n \tret = ioctl(intr_handle->vfio_dev_fd, VFIO_DEVICE_SET_IRQS, irq_set);\n \n@@ -332,6 +335,7 @@ vfio_enable_msix(struct rte_intr_handle *intr_handle) {\n \t\t\t\t\t\tintr_handle->fd);\n \t\treturn -1;\n \t}\n+\n \treturn 0;\n }\n \n@@ -339,7 +343,7 @@ vfio_enable_msix(struct rte_intr_handle *intr_handle) {\n static int\n vfio_disable_msix(struct rte_intr_handle *intr_handle) {\n \tstruct vfio_irq_set *irq_set;\n-\tchar irq_set_buf[IRQ_SET_BUF_LEN];\n+\tchar irq_set_buf[MSIX_IRQ_SET_BUF_LEN];\n \tint len, ret;\n \n \tlen = sizeof(struct vfio_irq_set);\n@@ -824,3 +828,109 @@ rte_eal_intr_init(void)\n \treturn -ret;\n }\n \n+static int\n+eal_intr_process_rx_interrupts(uint8_t port_id, struct epoll_event *events, int nfds)\n+{\n+\tint n, bytes_read;\n+\tunion rte_intr_read_buffer buf;\n+\tstruct rte_intr_handle intr_handle = rte_eth_devices[port_id].pci_dev->intr_handle;\n+\n+\tfor (n = 0; n < nfds; n++) {\n+\t\t/* set the length to be read dor different handle type */\n+\t\tswitch (intr_handle.type) {\n+\t\tcase RTE_INTR_HANDLE_UIO:\n+\t\t\tbytes_read = sizeof(buf.uio_intr_count);\n+\t\t\tbreak;\n+\t\tcase RTE_INTR_HANDLE_ALARM:\n+\t\t\tbytes_read = sizeof(buf.timerfd_num);\n+\t\t\tbreak;\n+#ifdef VFIO_PRESENT\n+\t\tcase RTE_INTR_HANDLE_VFIO_MSIX:\n+\t\tcase RTE_INTR_HANDLE_VFIO_MSI:\n+\t\tcase RTE_INTR_HANDLE_VFIO_LEGACY:\n+\t\t\tbytes_read = sizeof(buf.vfio_intr_count);\n+\t\t\tbreak;\n+#endif\n+\t\tdefault:\n+\t\t\tbytes_read = 1;\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\t/**\n+\t\t* read out to clear the ready-to-be-read flag\n+\t\t* for epoll_wait.\n+\t\t*/\n+\t\tbytes_read = read(events[n].data.fd, &buf, bytes_read);\n+\t\tif (bytes_read < 0)\n+\t\t\tRTE_LOG(ERR, EAL, \"Error reading from file \"\n+\t\t\t\t\"descriptor %d: %s\\n\", events[n].data.fd,\n+\t\t\t\t\t\t\tstrerror(errno));\n+\t\telse if (bytes_read == 0)\n+\t\t\tRTE_LOG(ERR, EAL, \"Read nothing from file \"\n+\t\t\t\t\"descriptor %d\\n\", events[n].data.fd);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static void\n+eal_intr_handle_rx_interrupts(uint8_t port_id, int pfd, unsigned totalfds)\n+{\n+\tstruct epoll_event events[totalfds];\n+\tint nfds = 0;\n+\n+m_wait:\n+\tnfds = epoll_wait(pfd, events, totalfds,\n+\t\t\tEAL_INTR_EPOLL_WAIT_FOREVER);\n+\t/* epoll_wait fail */\n+\tif (nfds < 0) {\n+\t\tif (errno == EINTR)\n+\t\t\tgoto m_wait;/*continue;*/\n+\t\tRTE_LOG(ERR, EAL,\n+\t\t\t\"epoll_wait returns with fail\\n\");\n+\t\treturn;\n+\t}\n+\t/* epoll_wait timeout, will never happens here */\n+\telse if (nfds == 0)\n+\t\tgoto m_wait;/*continue;*/\n+\t/* epoll_wait has at least one fd ready to read */\n+\tif (eal_intr_process_rx_interrupts(port_id, events, nfds) < 0)\n+\t\treturn;\n+}\n+\n+int\n+rte_eal_wait_rx_intr(uint8_t port_id, uint8_t queue_id)\n+{\n+\tstruct rte_intr_handle intr_handle = rte_eth_devices[port_id].pci_dev->intr_handle;\n+\tstruct epoll_event ev;\n+\tunsigned numfds = 0;\n+\n+\t/* create epoll fd */\n+\tint pfd = epoll_create(1);\n+\tif (pfd < 0)\n+\t\trte_panic(\"Cannot create epoll instance\\n\");\n+\n+\trte_spinlock_lock(&intr_lock);\n+\n+\tev.events = EPOLLIN | EPOLLPRI;\n+\tev.data.fd = intr_handle.queue_fd[queue_id];\n+\n+\tif (epoll_ctl(pfd, EPOLL_CTL_ADD,\n+\t\t\t\tintr_handle.queue_fd[queue_id], &ev) < 0){\n+\t\trte_panic(\"Error adding fd %d epoll_ctl, %s\\n\",\n+\t\t\t\tintr_handle.queue_fd[queue_id], strerror(errno));\n+\t} else\n+\t\tnumfds++;\n+\n+\trte_spinlock_unlock(&intr_lock);\n+\t/* serve the interrupt */\n+\teal_intr_handle_rx_interrupts(port_id, pfd, numfds);\n+\n+\t/**\n+\t* when we return, we need to rebuild the\n+\t* list of fds to monitor.\n+\t*/\n+\tclose(pfd);\n+\n+\treturn 0;\n+}\ndiff --git a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c\nindex 20e0977..63d0ae8 100644\n--- a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c\n+++ b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c\n@@ -283,7 +283,6 @@ pci_vfio_setup_interrupts(struct rte_pci_device *dev, int vfio_dev_fd)\n \n \t\tdev->intr_handle.fd = fd;\n \t\tdev->intr_handle.vfio_dev_fd = vfio_dev_fd;\n-\n \t\tswitch (i) {\n \t\tcase VFIO_PCI_MSIX_IRQ_INDEX:\n \t\t\tinternal_config.vfio_intr_mode = RTE_INTR_MODE_MSIX;\n@@ -302,6 +301,16 @@ pci_vfio_setup_interrupts(struct rte_pci_device *dev, int vfio_dev_fd)\n \t\t\treturn -1;\n \t\t}\n \n+\t\tfor (i = 0; i < VFIO_MAX_QUEUE_ID; i++) {\n+\t\t\tfd = eventfd(0, 0);\n+\t\t\tif (fd < 0) {\n+\t\t\t\tRTE_LOG(ERR, EAL, \"  cannot set up eventfd, \"\n+\t\t\t\t\t\t\"error %i (%s)\\n\", errno, strerror(errno));\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\tdev->intr_handle.queue_fd[i] = fd;\n+\t\t}\n+\n \t\treturn 0;\n \t}\n \ndiff --git a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_interrupts.h b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_interrupts.h\nindex 23eafd9..83b717c 100644\n--- a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_interrupts.h\n+++ b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_interrupts.h\n@@ -38,6 +38,8 @@\n #ifndef _RTE_LINUXAPP_INTERRUPTS_H_\n #define _RTE_LINUXAPP_INTERRUPTS_H_\n \n+#define VFIO_MAX_QUEUE_ID 32\n+\n enum rte_intr_handle_type {\n \tRTE_INTR_HANDLE_UNKNOWN = 0,\n \tRTE_INTR_HANDLE_UIO,      /**< uio device handle */\n@@ -52,6 +54,7 @@ enum rte_intr_handle_type {\n struct rte_intr_handle {\n \tint vfio_dev_fd;                 /**< VFIO device file descriptor */\n \tint fd;                          /**< file descriptor */\n+\tint queue_fd[VFIO_MAX_QUEUE_ID]; /**< rx and tx queue interrupt file descriptor */\n \tenum rte_intr_handle_type type;  /**< handle type */\n };\n \n",
    "prefixes": [
        "dpdk-dev",
        "RFC",
        "3/5"
    ]
}