get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 31746,
    "url": "http://patches.dpdk.org/api/patches/31746/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1511947970-48290-1-git-send-email-motih@mellanox.com/",
    "project": {
        "id": 1,
        "url": "http://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": "<1511947970-48290-1-git-send-email-motih@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1511947970-48290-1-git-send-email-motih@mellanox.com",
    "date": "2017-11-29T09:32:50",
    "name": "[dpdk-dev,RFC,V2] net/failsafe: add Rx interrupts",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "c0d1de7d26a88c0b35f70b1edd075fdb23c6666d",
    "submitter": {
        "id": 748,
        "url": "http://patches.dpdk.org/api/people/748/?format=api",
        "name": "Moti Haimovsky",
        "email": "motih@mellanox.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1511947970-48290-1-git-send-email-motih@mellanox.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/31746/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/31746/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 B9F0D2B9E;\n\tWed, 29 Nov 2017 10:33:09 +0100 (CET)",
            "from EUR01-VE1-obe.outbound.protection.outlook.com\n\t(mail-ve1eur01on0055.outbound.protection.outlook.com [104.47.1.55])\n\tby dpdk.org (Postfix) with ESMTP id 1BC7128EE\n\tfor <dev@dpdk.org>; Wed, 29 Nov 2017 10:33:09 +0100 (CET)",
            "from mellanox.com (37.142.13.130) by\n\tAM4PR05MB1906.eurprd05.prod.outlook.com (2603:10a6:200:15::14) with\n\tMicrosoft SMTP Server (version=TLS1_2,\n\tcipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.260.4;\n\tWed, 29 Nov 2017 09:33:05 +0000"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com;\n\ts=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version;\n\tbh=VhttHCo5SPB2CoMCpePU0TWMuLrGnRsovpj1VRbcrXQ=;\n\tb=wIHa3mr2QJT0r4BlrXHKEVtm0fQdUcfarhgTqUyCKiNZ6tNfL5PLfKkYP72gzQ2daRSWeYUylg10bHfkHCNaFJRVN6bDjGIhi+c70LVwdWyQJR2dYtMD9k0P48wftpuCX2i+/pgFx7T28bXUydnK/QJVLPs3k51uesFQWP6/qWs=",
        "Authentication-Results": "spf=none (sender IP is )\n\tsmtp.mailfrom=motih@mellanox.com; ",
        "From": "Moti Haimovsky <motih@mellanox.com>",
        "To": "gaetan.rivet@6wind.com",
        "Cc": "dev@dpdk.org,\n\tMoti Haimovsky <motih@mellanox.com>",
        "Date": "Wed, 29 Nov 2017 11:32:50 +0200",
        "Message-Id": "<1511947970-48290-1-git-send-email-motih@mellanox.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1511946476-47368-1-git-send-email-motih@mellanox.com>",
        "References": "<1511946476-47368-1-git-send-email-motih@mellanox.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[37.142.13.130]",
        "X-ClientProxiedBy": "DB6PR1001CA0033.EURPRD10.PROD.OUTLOOK.COM\n\t(2603:10a6:4:55::19) To AM4PR05MB1906.eurprd05.prod.outlook.com\n\t(2603:10a6:200:15::14)",
        "X-MS-PublicTrafficType": "Email",
        "X-MS-Office365-Filtering-Correlation-Id": "b9e82760-facb-45bd-b593-08d5370c3246",
        "X-MS-Office365-Filtering-HT": "Tenant",
        "X-Microsoft-Antispam": "UriScan:; BCL:0; PCL:0;\n\tRULEID:(5600026)(4604075)(4534020)(4602075)(4627115)(201703031133081)(201702281549075)(48565401081)(2017052603199);\n\tSRVR:AM4PR05MB1906; ",
        "X-Microsoft-Exchange-Diagnostics": [
            "1; AM4PR05MB1906;\n\t3:AC6X+AJ7nVnrPWeGfAu/Tz4oPRFerYC7LylHUrmDIp69WSro52fmAQolV3fTWQlwgT7UhvWjtLM45uz5w1JZ7WXoWGC8XP7iVGbLLf40QwbYqH3FHoCkppWeoXbn8LIwqPjZVIuf3l4umXVs25gNDQLMJUTZb9sxda4Er8GwUwE3jWzoIh2rLK3eisWNLX5aj7WluzZXi2pqBERWejEbrfzODooE+XH8qs+cFeLrkBRZn2tXcrYEdITpumEoUOKM;\n\t25:I4LZjLzvCgetIzNl918MJeMvPIXOTWxX66VwFyis9rzKdC2sPhA0QF+seZdktDLRdSJbdcNUc7dlJd5pndiEhb19cwvS9RvemrZDUz5qLAVoDflNxarBcdVylZZN6SmRGgsImq3rGaVa5VT3nsqSmogfA9jmX9MdGL/7Md8rUJndsj7JAzl8KtCH07sb1EMktRZUUF2rZVgAm8gZhDDLcFG81HJkQt52B7l1jEzP6obF6Xen/yRfWSNJhxIO4KAl7SLivwgTXeFeDjQAElw54OndOmPGijvsHuc/XBKfyF/SrjMGFeoEwrqkw+kCh/VbHwXqWcnnUe63JeuKDpAzSg==;\n\t31:FLLOb9BNkouyOdcHiOflsPOw1lD6ZQ61L8JHR3AIzFEMLHSPQF0uHPvHviCGrGuMuuqK+SoV1oBeZl2eMAu7OfXpep4225x7IaoYA4fzi7XRXh9Fig+AY24LDUkLDAuyD2x30Zp50DTQMK2CXTlt9U0rMzY3QinDYmvfnEhCxFq7MwSMV2V+C9HI6JTiX8mBqwid2WmpHB/l7HDWA2N0NMcux1HI6Z25WpH0y7UyQpI=",
            "1; AM4PR05MB1906;\n\t20:oE8aa4fpkfGXXzhHnA58UdD1XwCkK+zwXWCZl1IE+R0lpyqnp2/FAWiqtNGMwnKmA2fpKhjTRJ1qSWINTUbjo8TjdY+1vdmdzDw+jvW1RT18bJxOQL4kxOSTtJejk4guB4iQWer9lS6SeSQ576O8LoZNszl/uDCUOA/WLMIz9qTUvfdPt/mvUSZL2yClH/hSwChyzim52pDHqrjuhTVEHkQR9HodsjzX1r+xFVDLY3kVsW1H2f6rbjjN/6Y9004zNIKlAeVaC+oPZN7hpyEDFcZvfpncjoxREwG91V0W4+Y0BsjYCyk+YP0jo1XUV7WxObv84eRHXBb2J1Q9JjUmC99yTEPiWE5UqIu4lGLcfzRYrJiFh5WOLhyHURurxY6uJrbYDvMsqM+Gf/8eOaBOxr22rnxumtORY5AXvTbskmUgCGLROkFcq9ka/KZFwRtIWSxhJqTjonN1fq2pbYZv1h+cKgCN8M+9g+HYg/RmB4cOkJmljAF2JDmOiSyKHPXY;\n\t4:a7khjmYkVnxT4yKUOwsVlap+4e96OZ4wgIrDq1iEWwGcocuKFxqqoHZ+KSYCtDIaNslXUfmaxvH6wF0Y8w0714ktE0o9f9+R/LEKtb56q3GafpS6vLtP6cvIR6LVZ3yo8uZ0eaICAKZFMnfo7KoLFi2LWMAvKpNbxXCkewxl4pB0GmeQ9Z0EdG21RK8fnE7R1sDaZzA2/mWlcWYaC8mUtE9GR2SrNvtO4n+5BU4nRDPj1nLs4Esiz0XTyqQEmuX0ETAl0hOvxZyn9p2iSBaxVwNAsKUMRXAOMxFnaVFxj8vG5a5OcjKddfxtHH63z/QV",
            "=?us-ascii?Q?1; AM4PR05MB1906;\n\t23:b29FpIznjgN0kqwlubKW+wsWwH/1qE9lS8vkI6xq5?=\n\tyZUu3tkIevatQE3j+ZDbdQRRWRFGk/EOoKHsgU5yIFMSBq/CD2nIpOf9xU4cVa8batbAWaX8JaiBkxPzDNRL1dWZOcgBxz+4Mf0Pr5SD4BB0Ut5RNdZLBqWinaD8U+Ud5JR7Un9fU2Z9GlF623cDA8flEckqv+9sOO5oO84ckTbCGdGUM+pVWxuK9eE24zhJI78vJ7n1r13F+HiKIk5WtbAunpfomiW32ND+jIYFd0ZmNhDkp2q1YawDjXD+28xC7FCHmUPfu1TSS0/6hhJ4UIfGxT7m3AfRlYEXpLtrD/kXKeXMADmxXNoTgF5x0bNM9hb80ojUpt45ZKueBmrbKbUGV8SCNrSPmVNPbFc95cWjlj89hU1aFXaMT/rkfMXLSrFMUfzd54qE7N/Am2NCCRS64UA29K8hEFRrRu/2UZ+11mAi53rKUvuokIx7kufQ0/ctg66AXee0xnetBaEAykAq4xDX2hHouH3LirJ6c0rADjFAjiklrMJW/xkIq8EL9h6b/lVe+XT5TQs6UkoQ8OTu2k7a1u/Teo7G3nbfwA7CMuKvbnmV9PgtMqoVDWXkI0G8Iwnib5MwakDy7jZjBP1HE0ncn8IZqM00WrmVTAcHrDHfmEL4tel7kFE7AbTnCnrm6CaZktn7+4SwDcyEeopftR/p/Hv+STLksw90IZg8RL9iiNs/TCpriodbwOX3HgD4O4cCIAIGGawUhTuSwoREaveY80li2zP84okdAeyRgct7ntgtlpjZp8mlsy9GNEemxhFf1q2EKS3nTd82YoW6UaVChIV0sF0SzUXMea6JOBV3wDNvUHVTwz5mrEBDBp6iX+g4XcOvmwSxN6X+adl2pUgxSoUe9cXlS/Mq+QI/JzpZuVvivYbAJhneJ+xh65wJ8Qjy7gWgRjZWXlAowbfl3HxuYoF/WfQmMyhoz3i+TrUbA5cg2ccgoxOx2RnGTdFPqleqV8CLgK8pbYVt7T8r91MlRrW/vu6UHHCENZToAMkv2hYPKfEiQO9xFaephmWsUcl/A+DbVf3vdB4kZAIek8LEfGYOAaLiGLZG8wSVimnPQlF+7FhN4IQSYgE5p94O/PniYjc5X20TcSh9KpYIOSyzsPn61LCs99PdSN/cN1czaHN6CY9WlR4iImOgVQZamai+zOjy/5xjyWtsxElapl79s7UFYV4Y+Lrh8izGwnfxTRM8B0emOqeyV7DzAw=",
            "1; AM4PR05MB1906;\n\t6:TDxCL7OayzWTIJ1iB/6VxBjaUekpBHzj3Kz0Ji6N5H0x6z6fXN/4rS/1PDYn3waClliJ+5YvF4rPkJi/zvipWV0TE/fLwqcdTop6DNzy0pifC/C/NEf09AtLl6Wfk5Enz5MT0hA2EcLdBj5vsW4QcJHZpW4JybNnR1FG71hPonDdOsbDxOzaZ8vHbYFS3rF1B+y9bnvCdfNfCVVUI3SbNNw694z1iM+8d8ZBTv9/j619FalNW+DZn4ZvNCWQzcYgnQnYLNK7wiELsyq5fVse/u94QZwWrds0Fe6ZjDEG1R2CuZZsglwVFScEc4n89K+Pz7Yj5pzVxKqCjaAO8mXEeg2/6tNATzI67JfJoLX31f0=;\n\t5:Hk7WBJcU5Ky9uABvsQnxLs+JHPqL5UNXgOThDFHBi9C8xUJJgYo955RIjix0s5Z2BKTVKJ6vZ9mB2rT61HhFH7nGajSlLfR++SIPSHVXLEWS9vJuS9b1Y/THBOMTTYQhK7dJQIt5MFEJ0DAlZd0VbgFx283K8rDGCqv6XSPD0To=;\n\t24:UnqV8t1Y5a0uv3g++xWJkljS3k/XhR2xz6Rk80dyrgv7jjnhNjM+HwqtbuigIJRHxBcDmAhUp4QEOBH/TJrJGglu0LJ9ULsW1thd0z6pJ98=;\n\t7:E2Ud1z4pbkEzwYeU3yTKHyS7ajLGJlCBWIEriR10Z+qgXHD51Lq8yQIZbN2gwyTw0801FbMl3YZ57QRLc8H2GL/WY2cJJL32T/DMKI/NXZS9dhvQ5EgMgaOndKh5igvEuq9PJVE3yJ2NJmg2+1z5ahWDHROJM85P4UYOS+DssdemD+qMGhGAbEj35EDBAqP35l46uJDHGDq0gCgj7mY5PnM8Gbp1qdbITcgOa3NeIpVYJZIjcJzx+1Yw/P5F9Ose"
        ],
        "X-MS-TrafficTypeDiagnostic": "AM4PR05MB1906:",
        "X-Microsoft-Antispam-PRVS": "<AM4PR05MB1906DC5299E65846EBAB78E5D23B0@AM4PR05MB1906.eurprd05.prod.outlook.com>",
        "X-Exchange-Antispam-Report-Test": "UriScan:(278428928389397);",
        "X-Exchange-Antispam-Report-CFA-Test": "BCL:0; PCL:0;\n\tRULEID:(6040450)(2401047)(5005006)(8121501046)(3002001)(3231022)(93006095)(93001095)(10201501046)(6055026)(6041248)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123558100)(20161123560025)(20161123555025)(20161123562025)(20161123564025)(6072148)(201708071742011);\n\tSRVR:AM4PR05MB1906; BCL:0; PCL:0; RULEID:(100000803101)(100110400095);\n\tSRVR:AM4PR05MB1906; ",
        "X-Forefront-PRVS": "05066DEDBB",
        "X-Forefront-Antispam-Report": "SFV:NSPM;\n\tSFS:(10009020)(6009001)(366004)(39860400002)(376002)(346002)(199003)(189002)(33026002)(86362001)(6916009)(2950100002)(21086003)(50226002)(68736007)(47776003)(66066001)(2906002)(316002)(51416003)(7696005)(16526018)(478600001)(16586007)(52116002)(6666003)(5660300001)(69596002)(8936002)(189998001)(7736002)(4720700003)(97736004)(25786009)(81166006)(81156014)(55016002)(8676002)(53936002)(6116002)(305945005)(2361001)(2351001)(105586002)(36756003)(3846002)(106356001)(33646002)(50986999)(48376002)(50466002)(76176999)(107886003)(4326008)(101416001);\n\tDIR:OUT; SFP:1101; SCL:1; SRVR:AM4PR05MB1906; H:mellanox.com; FPR:;\n\tSPF:None; \n\tPTR:InfoNoRecords; A:1; MX:1; LANG:en; ",
        "Received-SPF": "None (protection.outlook.com: mellanox.com does not designate\n\tpermitted sender hosts)",
        "SpamDiagnosticOutput": "1:99",
        "SpamDiagnosticMetadata": "NSPM",
        "X-OriginatorOrg": "Mellanox.com",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "29 Nov 2017 09:33:05.7297\n\t(UTC)",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "b9e82760-facb-45bd-b593-08d5370c3246",
        "X-MS-Exchange-CrossTenant-FromEntityHeader": "Hosted",
        "X-MS-Exchange-CrossTenant-Id": "a652971c-7d2e-4d9b-a6a4-d149256f461b",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "AM4PR05MB1906",
        "Subject": "[dpdk-dev] [RFC V2] net/failsafe: add Rx interrupts",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <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": "This RFC suggests support for registering and waiting for Rx\ninterrupts in failsafe PMD. This allows applications to wait\nfor Rx events from the PMD using the DPDK rte_epoll subsystem.\nThe failsafe PMD presents to the application a facade of a single\ndevice to be handled by the application while internally it manages\nseveral devices on behalf of the application including packets\ntransmission and reception.\nThe Proposed failsafe Rx interrupt scheme follows this approach.\nThe failsafe PMD will present the application with a single set of Rx\ninterrupt vectors representing the failsafe Rx queues, while internally\nit will serve as an interrupt proxy for its subdevices.\nThis will allow applications to wait for Rx traffic from the failsafe\nPMD by registering and waiting for Rx events from its Rx queues.\nIn order to support this the following is suggested:\n  * Every Rx queue in the failsafe (virtual) device will be assigned a\n  * Linux\n    event file descriptor (efd) and an enable_interrupts flag.\n  * The failsafe PMD will fill in its rte_intr_handle structure with the\n  * Rx\n    efds assigned previously and register them with the EAL.\n  * The failsafe driver will create a private epoll fd (epfd) and will\n  * allocate\n    enough space to handle all the Rx events from all its subdevices.\n  * Acting as an application,\n    for each Rx queue in each active subdevice the failsafe will:\n      o Register the Rx queue with the EAL.\n      o Pass the EAL the failsafe private epoll fd as the epfd to\nregister the\n        Rx queue event on.\n      o Pass the EAL, as a parameter, the pointer to the failsafe Rx\nqueue that\n        handles this subdevice Rx queue.\n      o Using the DPDK service callbacks, the failsafe PMD will launch\nan\n        Rx proxy service that will Wait on the epoll fd for Rx events\nfrom the\n        sub-devices.\n      o For each Rx event received the proxy service will\n         - Retrieve the pointer to failsafe Rx queue that handles this\n           subdevice Rx queue from the user info returned by the EAL.\n         - Trigger a failsafe Rx event on that queue by writing to the\n           event fd\n           unless interrupts are disabled for that queue.\n  * The failsafe pmd will also implement the rx_queue_intr_enable and\n    rx_queue_intr_disable routines that will enable and disable Rx\ninterrupts\n    respectively on both on the failsafe and its subdevices.\n\nSigned-off-by: Moti Haimovsky <motih@mellanox.com>\n---\nV2:\n* Fixed code warnings reported in\n  1511946476-47368-1-git-send-email-motih@mellanox.com\n---\n drivers/net/failsafe/Makefile           |   1 +\n drivers/net/failsafe/failsafe.c         |   4 +\n drivers/net/failsafe/failsafe_ether.c   |   1 +\n drivers/net/failsafe/failsafe_intr.c    | 523 ++++++++++++++++++++++++++++++++\n drivers/net/failsafe/failsafe_ops.c     |  15 +\n drivers/net/failsafe/failsafe_private.h |  42 +++\n 6 files changed, 586 insertions(+)\n create mode 100644 drivers/net/failsafe/failsafe_intr.c",
    "diff": "diff --git a/drivers/net/failsafe/Makefile b/drivers/net/failsafe/Makefile\nindex ea2a8fe..91a734b 100644\n--- a/drivers/net/failsafe/Makefile\n+++ b/drivers/net/failsafe/Makefile\n@@ -46,6 +46,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_ops.c\n SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_rxtx.c\n SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_ether.c\n SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_flow.c\n+SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_intr.c\n \n # No exported include files\n \ndiff --git a/drivers/net/failsafe/failsafe.c b/drivers/net/failsafe/failsafe.c\nindex 6bc5aba..3b5e059 100644\n--- a/drivers/net/failsafe/failsafe.c\n+++ b/drivers/net/failsafe/failsafe.c\n@@ -239,6 +239,10 @@\n \t\tmac->addr_bytes[2], mac->addr_bytes[3],\n \t\tmac->addr_bytes[4], mac->addr_bytes[5]);\n \tdev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;\n+\tPRIV(dev)->intr_handle = (struct rte_intr_handle){\n+\t\t.fd = -1,\n+\t\t.type = RTE_INTR_HANDLE_EXT,\n+\t};\n \treturn 0;\n free_args:\n \tfailsafe_args_free(dev);\ndiff --git a/drivers/net/failsafe/failsafe_ether.c b/drivers/net/failsafe/failsafe_ether.c\nindex 21392e5..80741ba 100644\n--- a/drivers/net/failsafe/failsafe_ether.c\n+++ b/drivers/net/failsafe/failsafe_ether.c\n@@ -283,6 +283,7 @@\n \t\treturn;\n \tswitch (sdev->state) {\n \tcase DEV_STARTED:\n+\t\tfailsafe_rx_intr_uninstall_subdevice(sdev);\n \t\trte_eth_dev_stop(PORT_ID(sdev));\n \t\tsdev->state = DEV_ACTIVE;\n \t\t/* fallthrough */\ndiff --git a/drivers/net/failsafe/failsafe_intr.c b/drivers/net/failsafe/failsafe_intr.c\nnew file mode 100644\nindex 0000000..085f4f4\n--- /dev/null\n+++ b/drivers/net/failsafe/failsafe_intr.c\n@@ -0,0 +1,523 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright 2017 Mellanox\n+ *\n+ *   Redistribution and use in source and binary forms, with or without\n+ *   modification, are permitted provided that the following conditions\n+ *   are met:\n+ *\n+ *     * Redistributions of source code must retain the above copyright\n+ *       notice, this list of conditions and the following disclaimer.\n+ *     * Redistributions in binary form must reproduce the above copyright\n+ *       notice, this list of conditions and the following disclaimer in\n+ *       the documentation and/or other materials provided with the\n+ *       distribution.\n+ *     * Neither the name of the copyright holder nor the names of its\n+ *       contributors may be used to endorse or promote products derived\n+ *       from this software without specific prior written permission.\n+ *\n+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+/**\n+ * @file\n+ * Interrupts handling for failsafe driver.\n+ */\n+\n+#include <sys/eventfd.h>\n+#include <sys/epoll.h>\n+#include <unistd.h>\n+\n+#include <rte_alarm.h>\n+#include <rte_errno.h>\n+#include <rte_ethdev.h>\n+#include <rte_interrupts.h>\n+#include <rte_io.h>\n+#include <rte_service_component.h>\n+\n+#include \"failsafe_private.h\"\n+\n+#define NUM_RX_PROXIES (FAILSAFE_MAX_ETHPORTS * RTE_MAX_RXTX_INTR_VEC_ID)\n+\n+/**\n+ * Install failsafe Rx event proxy service.\n+ * The Rx event proxy is the service that listens to Rx events from the\n+ * subdevices and triggers failsafe Rx events accordingly.\n+ *\n+ * @param priv\n+ *   Pointer to failsafe private structure.\n+ * @return\n+ *   0 on success, negative errno value otherwise.\n+ */\n+static int\n+fs_rx_event_proxy_service(void *data)\n+{\n+\tstruct fs_priv *priv = data;\n+\tstruct rxq *rxq;\n+\tstruct rte_epoll_event *events = priv->rxp.evec;\n+\tuint64_t u64 = 1;\n+\tint i, n, rc = 0;\n+\n+\tn = rte_epoll_wait(priv->rxp.efd, events, NUM_RX_PROXIES, -1);\n+\tfor (i = 0; i < n; i++) {\n+\t\trxq = (struct rxq *)events[i].epdata.data;\n+\t\tif (rxq->enable_events && rxq->event_fd != -1) {\n+\t\t\tif (write(rxq->event_fd, &u64, sizeof(u64)) !=\n+\t\t\t    sizeof(u64)) {\n+\t\t\t\tERROR(\"failed to proxy Rx event to socket %d\",\n+\t\t\t\t       rxq->event_fd);\n+\t\t\t\trc = -EIO;\n+\t\t\t} else {\n+\t\t\t\tINFO(\"Proxied Rx event to %d\", rxq->event_fd);\n+\t\t\t}\n+\t\t}\n+\t}\n+\treturn rc;\n+}\n+\n+/**\n+ * Install the failsafe Rx event proxy service.\n+ *\n+ * @param priv\n+ *   Pointer to failsafe private structure.\n+ * @return\n+ *   0 on success, negative errno value otherwise.\n+ */\n+static int\n+fs_rx_event_proxy_service_install(struct fs_priv *priv)\n+{\n+\tstruct rte_service_spec service;\n+\n+\tif (priv->rxp.sstate == SS_NO_SREVICE) {\n+\t\t/* allocate epoll array   */\n+\t\tmemset(&service, 0, sizeof(struct rte_service_spec));\n+\t\tsnprintf(service.name, sizeof(service.name), \"%s_service\",\n+\t\t\t priv->dev->device->name);\n+\t\tservice.socket_id = priv->dev->data->numa_node;\n+\t\tservice.callback = fs_rx_event_proxy_service;\n+\t\tservice.callback_userdata = (void *)priv;\n+\t\tint32_t ret = rte_service_component_register(&service,\n+\t\t\t\t\t\t\t     &priv->rxp.sid);\n+\t\tif (ret) {\n+\t\t\tERROR(\"service register() failed\");\n+\t\t\treturn -ENOEXEC;\n+\t\t}\n+\t\trte_service_component_runstate_set(priv->rxp.sid, 1);\n+\t\tpriv->rxp.sstate = SS_REGISTERED;\n+\t}\n+\treturn 0;\n+}\n+\n+/**\n+ * Uninstall failsafe Rx event proxy service.\n+ *\n+ * @param priv\n+ *   Pointer to failsafe private structure.\n+ */\n+static void\n+fs_rx_event_proxy_service_uninstall(struct fs_priv *priv)\n+{\n+\t/* Unregister the event service. */\n+\tif (priv->rxp.sid > 0) {\n+\t\trte_service_runstate_set(priv->rxp.sid, 0);\n+\t\trte_service_component_runstate_set(priv->rxp.sid, 0);\n+\t\trte_service_component_unregister(priv->rxp.sid);\n+\t\tpriv->rxp.sid = 0;\n+\t\tpriv->rxp.sstate = SS_NO_SREVICE;\n+\t}\n+}\n+\n+/**\n+ * Install failsafe Rx event proxy subsystem.\n+ * This is the way the failsafe PMD generates Rx events on behalf of its\n+ * subdevices.\n+ *\n+ * @param priv\n+ *   Pointer to failsafe private structure.\n+ * @return\n+ *   0 on success, negative errno value otherwise and rte_errno is set.\n+ */\n+static int\n+fs_rx_event_proxy_install(struct fs_priv *priv)\n+{\n+\tint rc = 0;\n+\n+\t/* create the epoll to wait on for Rx events form subdevices */\n+\tpriv->rxp.efd = epoll_create1(0);\n+\tif (priv->rxp.efd < 0) {\n+\t\trte_errno = errno;\n+\t\tERROR(\"failed to create epoll,\"\n+\t\t      \" Rx interrupts will not be supported\");\n+\t\treturn -rte_errno;\n+\t}\n+\t/* allocate memory for receiving the Rx events from the subdevices. */\n+\tpriv->rxp.evec = calloc(NUM_RX_PROXIES, sizeof(*priv->rxp.evec));\n+\tif (priv->rxp.evec == NULL) {\n+\t\tERROR(\"failed to allocate memory for event vectors,\"\n+\t\t      \" Rx interrupts will not be supported\");\n+\t\trc = -ENOMEM;\n+\t\tgoto error;\n+\t}\n+\tif (fs_rx_event_proxy_service_install(priv) < 0) {\n+\t\trc = -rte_errno;\n+\t\tgoto error;\n+\t}\n+\treturn 0;\n+error:\n+\tif (priv->rxp.efd >= 0)\n+\t\tclose(priv->rxp.efd);\n+\tif (priv->rxp.evec)\n+\t\tfree(priv->rxp.evec);\n+\trte_errno = -rc;\n+\treturn rc;\n+}\n+\n+/**\n+ * Uninstall failsafe Rx event proxy.\n+ *\n+ * @param priv\n+ *   Pointer to failsafe private structure.\n+ */\n+static void\n+fs_rx_event_proxy_uninstall(struct fs_priv *priv)\n+{\n+\tfs_rx_event_proxy_service_uninstall(priv);\n+\tif (priv->rxp.evec) {\n+\t\tfree(priv->rxp.evec);\n+\t\tpriv->rxp.evec = NULL;\n+\t}\n+\tif (priv->rxp.efd <= 0) {\n+\t\tWARN(\"epoll fd is invalid\");\n+\t} else {\n+\t\tclose(priv->rxp.efd);\n+\t\tpriv->rxp.efd = -1;\n+\t}\n+}\n+\n+/**\n+ * Uninstall failsafe interrupt vector.\n+ *\n+ * @param priv\n+ *   Pointer to failsafe private structure.\n+ */\n+static void\n+fs_rx_intr_vec_uninstall(struct fs_priv *priv)\n+{\n+\tstruct rte_intr_handle *intr_handle = &priv->intr_handle;\n+\n+\tif (intr_handle->intr_vec) {\n+\t\tfree(intr_handle->intr_vec);\n+\t\tintr_handle->intr_vec = NULL;\n+\t}\n+\tintr_handle->nb_efd = 0;\n+}\n+/**\n+ * Installs failsafe interrupt vector to be registered with EAL later on.\n+ *\n+ * @param priv\n+ *   Pointer to failsafe private structure.\n+ *\n+ * @return\n+ *   0 on success, negative errno value otherwise and rte_errno is set.\n+ */\n+static int\n+fs_rx_intr_vec_install(struct fs_priv *priv)\n+{\n+\tunsigned int i;\n+\tunsigned int rxqs_n = priv->dev->data->nb_rx_queues;\n+\tunsigned int n = RTE_MIN(rxqs_n, (uint32_t)RTE_MAX_RXTX_INTR_VEC_ID);\n+\tunsigned int count = 0;\n+\tstruct rte_intr_handle *intr_handle = &priv->intr_handle;\n+\n+\t/* Allocate the interrupt vector of the failsafe Rx proxy interrupts */\n+\tintr_handle->intr_vec = malloc(n * sizeof(intr_handle->intr_vec[0]));\n+\tif (intr_handle->intr_vec == NULL) {\n+\t\tfs_rx_intr_vec_uninstall(priv);\n+\t\trte_errno = ENOMEM;\n+\t\tERROR(\"failed to allocate memory for interrupt vector,\"\n+\t\t      \" Rx interrupts will not be supported\");\n+\t\treturn -rte_errno;\n+\t}\n+\tfor (i = 0; i < n; i++) {\n+\t\tstruct rxq *rxq = priv->dev->data->rx_queues[i];\n+\n+\t\t/* Skip queues that cannot request interrupts. */\n+\t\tif (!rxq || rxq->event_fd < 0) {\n+\t\t\t/* Use invalid intr_vec[] index to disable entry. */\n+\t\t\tintr_handle->intr_vec[i] =\n+\t\t\t\tRTE_INTR_VEC_RXTX_OFFSET +\n+\t\t\t\tRTE_MAX_RXTX_INTR_VEC_ID;\n+\t\t\tcontinue;\n+\t\t}\n+\t\tif (count >= RTE_MAX_RXTX_INTR_VEC_ID) {\n+\t\t\trte_errno = E2BIG;\n+\t\t\tERROR(\"too many Rx queues for interrupt vector size\"\n+\t\t\t      \" (%d), Rx interrupts cannot be enabled\",\n+\t\t\t      RTE_MAX_RXTX_INTR_VEC_ID);\n+\t\t\tfs_rx_intr_vec_uninstall(priv);\n+\t\t\treturn -rte_errno;\n+\t\t}\n+\t\tintr_handle->intr_vec[i] = RTE_INTR_VEC_RXTX_OFFSET + count;\n+\t\tintr_handle->efds[count] = rxq->event_fd;\n+\t\tcount++;\n+\t}\n+\tif (!count)\n+\t\tfs_rx_intr_vec_uninstall(priv);\n+\telse\n+\t\tintr_handle->nb_efd = count;\n+\treturn 0;\n+}\n+\n+/**\n+ * RX Interrupt control per port.\n+ *\n+ * @param sdev\n+ *   Pointer to sub-device structure.\n+ * @param op\n+ *   The operation be performed for the vector.\n+ *   Operation type of {RTE_INTR_EVENT_ADD, RTE_INTR_EVENT_DEL}.\n+ * @return\n+ *   - On success, zero.\n+ *   - On failure, a negative value.\n+ */\n+static int\n+fs_eth_sdev_rx_intr_ctl(struct sub_device *sdev, int op)\n+{\n+\tstruct rte_eth_dev *dev = ETH(sdev);\n+\tstruct rte_eth_dev *fsdev = sdev->fs_dev;\n+\tstruct rxq *fsrxq;\n+\tuint16_t qid;\n+\tint epfd = PRIV(sdev->fs_dev)->rxp.efd;\n+\tuint16_t pid = PORT_ID(sdev);\n+\n+\tif (epfd <= 0) {\n+\t\tERROR(\"proxy events are not initialized\");\n+\t\treturn -EBADFD;\n+\t}\n+\tif (ETH(sdev)->data->nb_rx_queues > fsdev->data->nb_rx_queues) {\n+\t\tERROR(\"Subdevice has too many queues,\"\n+\t\t\t\" Interrupts will not be enabled\");\n+\t\treturn -E2BIG;\n+\t}\n+\tfor (qid = 0; qid < dev->data->nb_rx_queues; qid++) {\n+\t\tfsrxq = fsdev->data->rx_queues[qid];\n+\t\trte_eth_dev_rx_intr_ctl_q(pid, qid, epfd, op, (void *)fsrxq);\n+\t}\n+\treturn 0;\n+}\n+\n+/**\n+ * Apply interrupt control operation on all subdevices.\n+ *\n+ * @param priv\n+ *   Pointer to failsafe provate data structure.\n+ * @param op\n+ *   The operation to perform.\n+ *   Operation type of {RTE_INTR_EVENT_ADD, RTE_INTR_EVENT_DEL}.\n+ * @return\n+ *   0 on success, negative errno value otherwise and rte_errno is set.\n+ */\n+static int\n+slaves_rx_inter_ctrl(struct fs_priv *priv, int op)\n+{\n+\tstruct sub_device *sdev;\n+\tuint8_t i;\n+\tint ret;\n+\tint rc = 0;\n+\n+\tFOREACH_SUBDEV_STATE(sdev, i, priv->dev,\n+\t\t\t     op == RTE_INTR_EVENT_DEL ?\n+\t\t\t     DEV_UNDEFINED : DEV_ACTIVE) {\n+\t\tret = fs_eth_sdev_rx_intr_ctl(sdev, op);\n+\t\tif (ret < 0)\n+\t\t\trc = ret;\n+\t}\n+\treturn rc;\n+}\n+\n+\n+/**\n+ * Install Rx interrupts subsystem for a subdevice.\n+ * This is a support for dynamically adding subdevices.\n+ *\n+ * @param sdev\n+ *   Pointer to subdevice structure.\n+ *\n+ * @return\n+ *   0 on success, negative errno value otherwise and rte_errno is set.\n+ */\n+int failsafe_rx_intr_install_subdevice(struct sub_device *sdev)\n+{\n+\treturn fs_eth_sdev_rx_intr_ctl(sdev, RTE_INTR_EVENT_ADD);\n+}\n+\n+/**\n+ * Uninstall Rx interrupts subsystem for a subdevice.\n+ * This is a support for dynamically removing subdevices.\n+ *\n+ * @param sdev\n+ *   Pointer to subdevice structure.\n+ *\n+ * @return\n+ *   0 on success, negative errno value otherwise and rte_errno is set.\n+ */\n+void failsafe_rx_intr_uninstall_subdevice(struct sub_device *sdev)\n+{\n+\tfs_eth_sdev_rx_intr_ctl(sdev, RTE_INTR_EVENT_DEL);\n+}\n+\n+/**\n+ * Uninstall failsafe Rx interrupts subsystem.\n+ *\n+ * @param priv\n+ *   Pointer to private structure.\n+ *\n+ * @return\n+ *   0 on success, negative errno value otherwise and rte_errno is set.\n+ */\n+void\n+failsafe_rx_intr_uninstall(struct rte_eth_dev *dev)\n+{\n+\tstruct fs_priv *priv = PRIV(dev);\n+\tstruct rte_intr_handle *intr_handle = &priv->intr_handle;\n+\n+\tslaves_rx_inter_ctrl(priv, RTE_INTR_EVENT_DEL);\n+\tfs_rx_event_proxy_uninstall(priv);\n+\trte_intr_free_epoll_fd(intr_handle);\n+\tif (intr_handle->intr_vec) {\n+\t\tfree(intr_handle->intr_vec);\n+\t\tintr_handle->intr_vec = NULL;\n+\t}\n+\tintr_handle->nb_efd = 0;\n+}\n+\n+/**\n+ * Install failsafe Rx interrupts subsystem.\n+ *\n+ * @param priv\n+ *   Pointer to private structure.\n+ *\n+ * @return\n+ *   0 on success, negative errno value otherwise and rte_errno is set.\n+ */\n+int\n+failsafe_rx_intr_install(struct rte_eth_dev *dev)\n+{\n+\tstruct fs_priv *priv = PRIV(dev);\n+\tconst struct rte_intr_conf *const intr_conf =\n+\t\t\t&priv->dev->data->dev_conf.intr_conf;\n+\tint rc = 0;\n+\n+\tfailsafe_rx_intr_uninstall(dev);\n+\tif (!intr_conf->rxq)\n+\t\treturn 0;\n+\tif (fs_rx_intr_vec_install(priv) < 0)\n+\t\treturn -rte_errno;\n+\tif (fs_rx_event_proxy_install(priv) < 0) {\n+\t\tfs_rx_intr_vec_uninstall(priv);\n+\t\treturn -rte_errno;\n+\t}\n+\trc = slaves_rx_inter_ctrl(priv, RTE_INTR_EVENT_ADD);\n+\tif (rc) {\n+\t\tfs_rx_intr_vec_uninstall(priv);\n+\t\tfs_rx_intr_vec_uninstall(priv);\n+\t\treturn rc;\n+\t}\n+\treturn 0;\n+}\n+\n+\n+/**\n+ * DPDK callback for Rx queue interrupt disable.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device structure.\n+ * @param idx\n+ *   Rx queue index.\n+ *\n+ * @return\n+ *   0 on success, negative errno value otherwise and rte_errno is set.\n+ */\n+int\n+failsafe_rx_intr_disable(struct rte_eth_dev *dev, uint16_t idx)\n+{\n+\tstruct rxq *rxq = dev->data->rx_queues[idx];\n+\tstruct sub_device *sdev;\n+\tuint64_t u64;\n+\tuint8_t i;\n+\tint rc = 0;\n+\tint ret;\n+\n+\tif (!rxq || rxq->event_fd <= 0) {\n+\t\trte_errno = EINVAL;\n+\t\treturn -rte_errno;\n+\t}\n+\trxq->enable_events = 0;\n+\tFOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {\n+\t\tret = rte_eth_dev_rx_intr_disable(PORT_ID(sdev), idx);\n+\t\tif ((ret != -ENOTSUP) && (ret != -ENODEV))\n+\t\t\trc = rc;\n+\t}\n+\t/* Clear pending events */\n+\twhile (read(rxq->event_fd, &u64, sizeof(uint64_t)) >  0)\n+\t\t;\n+\tif (rc)\n+\t\trte_errno = -rc;\n+\treturn rc;\n+}\n+\n+/**\n+ * DPDK callback for Rx queue interrupt enable.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device structure.\n+ * @param idx\n+ *   Rx queue index.\n+ *\n+ * @return\n+ *   0 on success, negative errno value otherwise and rte_errno is set.\n+ */\n+int\n+failsafe_rx_intr_enable(struct rte_eth_dev *dev, uint16_t idx)\n+{\n+\tstruct rxq *rxq = dev->data->rx_queues[idx];\n+\tstruct sub_device *sdev;\n+\tuint8_t i;\n+\tint rc = 0;\n+\tint ret;\n+\n+\tif (!rxq || rxq->event_fd <= 0) {\n+\t\trte_errno = EINVAL;\n+\t\treturn -rte_errno;\n+\t}\n+\t/* Let the proxy service run. */\n+\tif (PRIV(dev)->rxp.sstate != SS_RUNNING) {\n+\t\trc = rte_service_runstate_set(PRIV(dev)->rxp.sid, 1);\n+\t\tif (rc) {\n+\t\t\tERROR(\"Failed to run failsafe interrupt services.\");\n+\t\t\tgoto exit;\n+\t\t}\n+\t\tPRIV(dev)->rxp.sstate = SS_RUNNING;\n+\t}\n+\trxq->enable_events = 1;\n+\tFOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {\n+\t\tret = rte_eth_dev_rx_intr_enable(PORT_ID(sdev), idx);\n+\t\tif ((ret != -ENOTSUP) && (ret != -ENODEV))\n+\t\t\trc = ret;\n+\t}\n+exit:\n+\tif (rc)\n+\t\trte_errno = -rc;\n+\treturn rc;\n+}\ndiff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c\nindex e16a590..6626d93 100644\n--- a/drivers/net/failsafe/failsafe_ops.c\n+++ b/drivers/net/failsafe/failsafe_ops.c\n@@ -32,6 +32,7 @@\n  */\n \n #include <stdint.h>\n+#include <unistd.h>\n \n #include <rte_debug.h>\n #include <rte_atomic.h>\n@@ -167,6 +168,9 @@\n \t\t\treturn ret;\n \t\tsdev->state = DEV_STARTED;\n \t}\n+\tret = failsafe_rx_intr_install(dev);\n+\tif (ret)\n+\t\tWARN(\"Rx interrupts are not supported\");\n \tif (PRIV(dev)->state < DEV_STARTED)\n \t\tPRIV(dev)->state = DEV_STARTED;\n \tfs_switch_dev(dev, NULL);\n@@ -179,8 +183,10 @@\n \tstruct sub_device *sdev;\n \tuint8_t i;\n \n+\tfailsafe_rx_intr_uninstall(dev);\n \tPRIV(dev)->state = DEV_STARTED - 1;\n \tFOREACH_SUBDEV_STATE(sdev, i, dev, DEV_STARTED) {\n+\t\tfailsafe_rx_intr_uninstall_subdevice(sdev);\n \t\trte_eth_dev_stop(PORT_ID(sdev));\n \t\tsdev->state = DEV_STARTED - 1;\n \t}\n@@ -254,6 +260,8 @@\n \tif (queue == NULL)\n \t\treturn;\n \trxq = queue;\n+\tif (rxq->event_fd > 0)\n+\t\tclose(rxq->event_fd);\n \tdev = rxq->priv->dev;\n \tFOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE)\n \t\tSUBOPS(sdev, rx_queue_release)\n@@ -294,6 +302,11 @@\n \trxq->info.conf = *rx_conf;\n \trxq->info.nb_desc = nb_rx_desc;\n \trxq->priv = PRIV(dev);\n+\trxq->event_fd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);\n+\tif (rxq->event_fd < 0) {\n+\t\tERROR(\"Rx event_fd error, %s\", strerror(errno));\n+\t\treturn -errno;\n+\t}\n \tdev->data->rx_queues[rx_queue_id] = rxq;\n \tFOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {\n \t\tret = rte_eth_rx_queue_setup(PORT_ID(sdev),\n@@ -767,4 +780,6 @@\n \t.mac_addr_add = fs_mac_addr_add,\n \t.mac_addr_set = fs_mac_addr_set,\n \t.filter_ctrl = fs_filter_ctrl,\n+\t.rx_queue_intr_enable = failsafe_rx_intr_enable,\n+\t.rx_queue_intr_disable = failsafe_rx_intr_disable,\n };\ndiff --git a/drivers/net/failsafe/failsafe_private.h b/drivers/net/failsafe/failsafe_private.h\nindex d81cc3c..538fdc0 100644\n--- a/drivers/net/failsafe/failsafe_private.h\n+++ b/drivers/net/failsafe/failsafe_private.h\n@@ -34,6 +34,7 @@\n #ifndef _RTE_ETH_FAILSAFE_PRIVATE_H_\n #define _RTE_ETH_FAILSAFE_PRIVATE_H_\n \n+#include <sys/eventfd.h>\n #include <sys/queue.h>\n \n #include <rte_atomic.h>\n@@ -57,6 +58,13 @@\n #define FAILSAFE_MAX_ETHPORTS 2\n #define FAILSAFE_MAX_ETHADDR 128\n \n+enum rxp_service_state {\n+\tSS_NO_SREVICE = 0,\n+\tSS_REGISTERED,\n+\tSS_READY,\n+\tSS_RUNNING,\n+};\n+\n /* TYPES */\n \n struct rxq {\n@@ -65,10 +73,23 @@ struct rxq {\n \t/* id of last sub_device polled */\n \tuint8_t last_polled;\n \tunsigned int socket_id;\n+\tint event_fd;\n+\tunsigned int enable_events:1;\n \tstruct rte_eth_rxq_info info;\n \trte_atomic64_t refcnt[];\n };\n \n+struct rx_proxy {\n+\t/* epoll file descriptor */\n+\tint efd;\n+\t/* event vector to be used by epoll */\n+\tstruct rte_epoll_event *evec;\n+\t/* rte service id */\n+\tuint32_t sid;\n+\tenum rxp_service_state sstate;\n+\n+};\n+\n struct txq {\n \tstruct fs_priv *priv;\n \tuint16_t qid;\n@@ -139,6 +160,7 @@ struct fs_priv {\n \tuint32_t mac_addr_pool[FAILSAFE_MAX_ETHADDR];\n \t/* current capabilities */\n \tstruct rte_eth_dev_info infos;\n+\tstruct rte_intr_handle intr_handle; /* Port interrupt handle. */\n \t/*\n \t * Fail-safe state machine.\n \t * This level will be tracking state of the EAL and eth\n@@ -151,8 +173,28 @@ struct fs_priv {\n \tunsigned int pending_alarm:1; /* An alarm is pending */\n \t/* flow isolation state */\n \tint flow_isolated:1;\n+\t/*\n+\t * Rx interrupts/events proxy.\n+\t * The PMD issues Rx events to the EAL on behalf of its subdevices,\n+\t *  it does that by registering event queues to the EAL. Each such\n+\t *  queue represents a failsafe Rx queue. A PMD service thread listens\n+\t *  to all the Rx events of of all the failsafe subdevices.\n+\t *  When an Rx event is issued by a subdevice Rx queue it will be\n+\t *  caught by the service and delivered by it to the appropriate\n+\t *  failsafe event queue.\n+\t */\n+\tstruct rx_proxy rxp;\n };\n \n+/* FAILSAFE_INTR */\n+\n+int failsafe_rx_intr_install(struct rte_eth_dev *dev);\n+void failsafe_rx_intr_uninstall(struct rte_eth_dev *dev);\n+int failsafe_rx_intr_enable(struct rte_eth_dev *dev, uint16_t idx);\n+int failsafe_rx_intr_disable(struct rte_eth_dev *dev, uint16_t idx);\n+int failsafe_rx_intr_install_subdevice(struct sub_device *sdev);\n+void failsafe_rx_intr_uninstall_subdevice(struct sub_device *sdev);\n+\n /* MISC */\n \n int failsafe_hotplug_alarm_install(struct rte_eth_dev *dev);\n",
    "prefixes": [
        "dpdk-dev",
        "RFC",
        "V2"
    ]
}