get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 139695,
    "url": "https://patches.dpdk.org/api/patches/139695/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20240426074831.1729792-8-chaoyong.he@corigine.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": "<20240426074831.1729792-8-chaoyong.he@corigine.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20240426074831.1729792-8-chaoyong.he@corigine.com",
    "date": "2024-04-26T07:48:28",
    "name": "[07/10] vdpa/nfp: setup the VF configure",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "9c1b19ec72f01741a4ddfc5cfd345384c8d888a7",
    "submitter": {
        "id": 2554,
        "url": "https://patches.dpdk.org/api/people/2554/?format=api",
        "name": "Chaoyong He",
        "email": "chaoyong.he@corigine.com"
    },
    "delegate": {
        "id": 2642,
        "url": "https://patches.dpdk.org/api/users/2642/?format=api",
        "username": "mcoquelin",
        "first_name": "Maxime",
        "last_name": "Coquelin",
        "email": "maxime.coquelin@redhat.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20240426074831.1729792-8-chaoyong.he@corigine.com/mbox/",
    "series": [
        {
            "id": 31827,
            "url": "https://patches.dpdk.org/api/series/31827/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=31827",
            "date": "2024-04-26T07:48:21",
            "name": "support software live migration",
            "version": 1,
            "mbox": "https://patches.dpdk.org/series/31827/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/139695/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/139695/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id A8AA643F12;\n\tFri, 26 Apr 2024 09:49:51 +0200 (CEST)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 47D5243C9E;\n\tFri, 26 Apr 2024 09:49:09 +0200 (CEST)",
            "from NAM10-MW2-obe.outbound.protection.outlook.com\n (mail-mw2nam10on2091.outbound.protection.outlook.com [40.107.94.91])\n by mails.dpdk.org (Postfix) with ESMTP id E3E1C43C9D\n for <dev@dpdk.org>; Fri, 26 Apr 2024 09:49:07 +0200 (CEST)",
            "from SJ0PR13MB5545.namprd13.prod.outlook.com (2603:10b6:a03:424::5)\n by SN4PR13MB5279.namprd13.prod.outlook.com (2603:10b6:806:206::7)\n with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7519.22; Fri, 26 Apr\n 2024 07:49:06 +0000",
            "from SJ0PR13MB5545.namprd13.prod.outlook.com\n ([fe80::ec12:7411:559a:850e]) by SJ0PR13MB5545.namprd13.prod.outlook.com\n ([fe80::ec12:7411:559a:850e%5]) with mapi id 15.20.7544.010; Fri, 26 Apr 2024\n 07:49:06 +0000"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;\n b=e8NyHoI9XjvHmVsZrtUlILtLK9FSHmuq7og89v53rzCUgI/+JusVsfAExC8ltc9CCxVbZWpup+6LaXH3f1P3ckNDFoGithe/T/ar2OqZ4wzmvdZqeunIwI3rn0hpN6tSDRrkItlptSX6bLaJKlFL6oAX4ifX+G/Qelu9i9jfuhg3hKgf9R0upQJK36rCri3pBfZY+nikzuRQznlV+W0yVDCG4eQl8YvVLijKSjQEbKz5SxwHjFmadz8skMvgWAAFA+LnTRRf6pKiRn/8c5gsKeyDbys9qqSltjpSd6YPsLDt+ka3ISBNCfKWpO3I9v0MDedx+/NLy7sB2HKxtgQ3sw==",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;\n s=arcselector9901;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1;\n bh=YfoPGgvNQGkQ63WfkFMmAojr2+sCV6u2NiQm6D2oauU=;\n b=B+fSg6bPKmV21X/4ZeTDqzBdiOkzDgypqD79SQeeut2zNngCIBrxo2/H3zthlZUUWq1iSerJFfrWvTSh+ERXJE1AyJa+sRLGSEiiyckQzG9gIbzQE27nkjCN6CsOErG6ahPVYdvEZPXf6KDCN0977fDezjRo4CuS8m5WfjwS5BRi9I5Df60cDIkD5h3+9/o1tYOXpjanGD82hEISqQUU0t2wE1hf4XrcHnf0r8nEBDlwadZw/58pon/nOmNp6LK/I6yUz+hRRqXVkje96SYT2uMWp2aSwO+FWmDCfoeX6Wb1CC6uX8yLKuo8D95/PGex/WJvCUx4DlfFf7zR5k59Xw==",
        "ARC-Authentication-Results": "i=1; mx.microsoft.com 1; spf=pass\n smtp.mailfrom=corigine.com; dmarc=pass action=none header.from=corigine.com;\n dkim=pass header.d=corigine.com; arc=none",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=corigine.onmicrosoft.com; s=selector2-corigine-onmicrosoft-com;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n bh=YfoPGgvNQGkQ63WfkFMmAojr2+sCV6u2NiQm6D2oauU=;\n b=cuhec73U5FRZQ98bsQlBdHDYIfSTZzrvBWweAKVxUWHIfcZgsnyIsveG3xWNlDh/ksHLGAcuvSKK9Vcz+zbmhM0KJmc4zC+89V5+/boSdlWPJ2hBzv6kTINyJqH2ZIumzeX28ElCAtusib0fQGfH0YPfRIs82aNUNe96zh02quw=",
        "Authentication-Results": "dkim=none (message not signed)\n header.d=none;dmarc=none action=none header.from=corigine.com;",
        "From": "Chaoyong He <chaoyong.he@corigine.com>",
        "To": "dev@dpdk.org",
        "Cc": "oss-drivers@corigine.com, Xinying Yu <xinying.yu@corigine.com>,\n Chaoyong He <chaoyong.he@corigine.com>, Long Wu <long.wu@corigine.com>,\n Peng Zhang <peng.zhang@corigine.com>",
        "Subject": "[PATCH 07/10] vdpa/nfp: setup the VF configure",
        "Date": "Fri, 26 Apr 2024 15:48:28 +0800",
        "Message-Id": "<20240426074831.1729792-8-chaoyong.he@corigine.com>",
        "X-Mailer": "git-send-email 2.39.1",
        "In-Reply-To": "<20240426074831.1729792-1-chaoyong.he@corigine.com>",
        "References": "<20240426074831.1729792-1-chaoyong.he@corigine.com>",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-ClientProxiedBy": "BYAPR02CA0007.namprd02.prod.outlook.com\n (2603:10b6:a02:ee::20) To SJ0PR13MB5545.namprd13.prod.outlook.com\n (2603:10b6:a03:424::5)",
        "MIME-Version": "1.0",
        "X-MS-PublicTrafficType": "Email",
        "X-MS-TrafficTypeDiagnostic": "SJ0PR13MB5545:EE_|SN4PR13MB5279:EE_",
        "X-MS-Office365-Filtering-Correlation-Id": "f14a88ef-9f8d-465f-f972-08dc65c55950",
        "X-MS-Exchange-SenderADCheck": "1",
        "X-MS-Exchange-AntiSpam-Relay": "0",
        "X-Microsoft-Antispam": "BCL:0;\n ARA:13230031|52116005|1800799015|366007|376005|38350700005;",
        "X-Microsoft-Antispam-Message-Info": "\n 7Qb/5vwsdr5Arx3i+YxsaaMYSkUSxCgDOUlr/3Zd5pedyRvz1rvNgN4N8W295swXb6PbAmLKYry6HSrNuuEFeK6298TSnAe6BLuZ42ti3jkpt7HZ4Spiet0kXcU7BQLW9wjBMXaVvmM+nQK6aWmKBNfvn4hAfVsdO7boTVlhd00VMPiD7W1KsrC2Xvj+ZBCVHsaWKOb9XYbdKefl8c1P+JJL/b4YmAVwEi1XVm9HcYjXizb3DMSn3V/YTe4mQpgn5XVqYXxRrwVDAAIeLkFaHZqSN/Kzcwn0qhtK3VvbgkH0/05SURe45jJLOaVJauDI6KHAGYpc1i2my44cC+UnaL7Co2fuB3SaVhgI8t0qafCOJU3Ext1EwknUF6CTRSaCFRQb38lfaMdk/l5LwHq9+WEKpDHiIzHSxuI56Eia/7njMHVbFjGF7wui9rDZ+bXv8aAoti34tK1+CjBcKRtWi7UB3vYdCDAj1iVmrwoXtLT/fymJ3kDPNnVTYwXJyspNW6olP0dZ48kKW4SYiOErfIOP2PPwJJXFfxlAvfR7sKiDEJ8wlov/eQl76Ul6Kl8W8BjrxxPRn4+B77yiiH5XqTt7DST6q0OXowGuA+3jeKuAyIHiLd4pLwLngj+UJYIGeU608OhJlWOr3BGGaUrqilc/pwy+6A4IZsBcTgVTOr3blbsSc2/lPnzG++P7Fr58AGp5F27QD3pI8JewiUxzQxjzGCjf440jnMa3wBkxYerrxREXdic0de2E3lkteQaDhrx93Def6E1uUEewPoGTUTYTFXqVlNwLmQTSWnFl9NOYaLQQ6MbQoZj/gRPBpwg4bP1NJt79c8h5CaWQ6CBtutxS86o+AcngZUtPJTJ5+kq75BRF0KuIRxsIT/ZTn2q4SwbNeU4RdfIqrMg2X7mLdT/PMDT/RJqewwdUN3WGFnKJUJGMg3Nn0ugVuUHmR9SkRpseCbTHZpHelgEI6Z3lhpMr7vhbvdJL6kcqYtbLbQovz7+ecvM0MQxJGXtxMiHcZNa2vhP0+dQSZf+55aVB/ZcO5kbsQ1RyA/xg442Erh4MM+bMIaxrmV6muAskaeq9nW+TRSDjDjrGdQssdOYFaHK6YMotw5+CD9EDD1NS5vgOsveejbfC4mN1QfCHxWwsMu28IvRV+wJ/XgkTYr0nPI+OVicn3JnAJ7u0Fks5/4qZ3ZVs0I5V7tA+YqUU0QQM6Ve5G795MiV2mJAivWi6eDvqEKDTuT6+7CAOdRqmBfXZcxsoNYXG1TFA1irjnjgCU0VmrBSI0CB/jjdBKg/gWglfC5ZcuyawDMEI6RvLnkFySWHeGlsHnbYKVQaZdYGWjEf28AL+aoTGYZSKyOz61g==",
        "X-Forefront-Antispam-Report": "CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:;\n IPV:NLI; SFV:NSPM; H:SJ0PR13MB5545.namprd13.prod.outlook.com; PTR:; CAT:NONE;\n SFS:(13230031)(52116005)(1800799015)(366007)(376005)(38350700005); DIR:OUT;\n SFP:1102;",
        "X-MS-Exchange-AntiSpam-MessageData-ChunkCount": "1",
        "X-MS-Exchange-AntiSpam-MessageData-0": "\n 6DApxdFkEpvzUbS6QM0tDLNT99FNiHboAjdGK6uil/gIhWWLxWCrZggV9rOJAM4+t8Q/rOiUejcLSrhoXDX1oq6E4GXy8P2Baj7on56LxGBMws1LS09KZwjA/7F0vEcQFtFwjBiaSw3n8QCaZI6mtFJgU4dAiUZhK3yQlkuk90d/f2Bxf2ghBqoVL747xZYEGnzRZUofxBqsx1SQxGuE2rIODwmJmx2bMJN6V9YCKBgc6JNoxly4G4In/astfstHHo4B3Gz/9nrz+eJGpbEvfncAc9aBpl4YEXuBcpitEkk0nMy4eM9F2UOkADPF5rJw/MFEZyFTzEJrugjhkrfK3UQTeur/vhb0QUMvBFE0lnVlhEtLzUA4sLxy7QVjiP8kz/nju3k7DzSNvTwNOrl3O4SVjc78KdmhohfdWhn2jSMUWZSQrg1jTyDR8LknK0Xh/Rtuy61+iWCIs5fvy91/w//JMAFhevr2lBfE068jjlrBDm73gpXbtK4wwWLWy8aJn3pYTebH3UaRDm4dUse3I0wzbmq+Vb3MvFwr2lIR0tMqYkeq207rXYsg3knC0iD9zxfhdHkJS872gDAdFga98Eg3RYecRPkuqnXw068elPan0a1JoC5rPlRD/eUz01hYTqyNnF6u6OuhzwwYMSwSp2jqQ1Mw6BJcwbjKaR03YFtL8qzqU7onpF1fdC4VJj1KuomcxSJyDh02aSDICVBWDwEU9V3ianW663+HeAs6YCYWyG+7w+as/gsKCj7OxBNovoQa0H9aUWeT6PnrqzPdvG5teXYNgGPNnyP1f/6Yizf9eq5ip4AseK37L4Rh8BMWarjDLlYQ6xbETzoWdYvF9Pq/DuaslP8Vn4NU5hWWB0oavBn0lpKUnH1vS21t/NL4ued4K7uzm+1SZW/QSN30BSyXJrWemJBPx14TfMwqMMPatGhur48xV+mbKfzXAr+2f1zNmmY4XrQ9uY+IN71pWcp27HhtosR4U9vLUNn1qNjHPPrpF7WBAaY1F7ojtPrvm9ctfBvgZVF4JT2R74pmeJXqRkHKUceHKzlHQMHmnFhFbt9HQia1YI5cU8jQWE9Me4ewnTW3ybmDovjnsoURfMirBkl9Ngu9sBSmDgazagn/kx1OiloPdQv1c1nqqiu7GLYmv6c59iAvjh3XePyj3fp0qsz0Jx171YRtrg6V1pQ1uwhaxo4xQEZ8KRdv7QbHXWvP5IARh4aiWA6jDaRNzIq6XTTTQoDa6AB5liGlJqQHOBqr81rZEpyCe66+8e1/ZMkxdGA4xbqitNBQOX4pwjZi6EgINnC8d+k8p9eBAlpO/qXt2RAlDrjy17r2aGRCAOOqrGik+yGVhQNMNkBAPAzd8eT5Hm0vT/uhrExua22l+ppGTfOElCWvZMcreiDUZ4P7+zoZU2pJVzqGglraUy3TDpjQv7bSvBJx/vrfIz09HzHO56MG6Vijjh1pG6H2EtAkBGCY7QpMJm0ZctZeLrgl7oY6+1Rl/MMHYjMpPggXZnV8Cdrh++bLh9e3lMg7rxXn2G0uyenoz5Q1s2ibRSFOUNTwLo2UH+i5/vpojOEK5v4JGq9QdhveT3gMYv9G24BSntd6Xo6Ec1b5G+adQw==",
        "X-OriginatorOrg": "corigine.com",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n f14a88ef-9f8d-465f-f972-08dc65c55950",
        "X-MS-Exchange-CrossTenant-AuthSource": "SJ0PR13MB5545.namprd13.prod.outlook.com",
        "X-MS-Exchange-CrossTenant-AuthAs": "Internal",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "26 Apr 2024 07:49:06.4029 (UTC)",
        "X-MS-Exchange-CrossTenant-FromEntityHeader": "Hosted",
        "X-MS-Exchange-CrossTenant-Id": "fe128f2c-073b-4c20-818e-7246a585940c",
        "X-MS-Exchange-CrossTenant-MailboxType": "HOSTED",
        "X-MS-Exchange-CrossTenant-UserPrincipalName": "\n W5wM9fhf202hdvty5Gv+G8QAWed89v2DCJgz+013DObI6N9cHuP/BpvPMdxj+5QfwOdrrVkLCv2+MOL0W54H686FWXBLRoLm1El8yqqx/So=",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "SN4PR13MB5279",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <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 <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org"
    },
    "content": "From: Xinying Yu <xinying.yu@corigine.com>\n\nCreate the relay vring on host and then set the address of Rx\nused ring to the VF config bar. So the device can DMA the\nused ring information to host rather than directly to VM.\n\nUse 'NFP_NET_CFG_CTRL_LM_RELAY' notify the device side. And\nenable the MSIX interrupt on device.\n\nTx ring address is no need to change since the relay vring only\nassistant Rx ring to do the dirty page logging.\n\nSigned-off-by: Xinying Yu <xinying.yu@corigine.com>\nReviewed-by: Chaoyong He <chaoyong.he@corigine.com>\nReviewed-by: Long Wu <long.wu@corigine.com>\nReviewed-by: Peng Zhang <peng.zhang@corigine.com>\n---\n drivers/common/nfp/nfp_common_ctrl.h |   3 +\n drivers/vdpa/nfp/nfp_vdpa.c          | 202 ++++++++++++++++++++++++---\n drivers/vdpa/nfp/nfp_vdpa_core.c     |  55 ++++++--\n drivers/vdpa/nfp/nfp_vdpa_core.h     |   8 ++\n 4 files changed, 238 insertions(+), 30 deletions(-)",
    "diff": "diff --git a/drivers/common/nfp/nfp_common_ctrl.h b/drivers/common/nfp/nfp_common_ctrl.h\nindex a0e62b063d..9311d01590 100644\n--- a/drivers/common/nfp/nfp_common_ctrl.h\n+++ b/drivers/common/nfp/nfp_common_ctrl.h\n@@ -186,6 +186,9 @@ struct nfp_net_fw_ver {\n #define NFP_NET_CFG_CTRL_FLOW_STEER       (0x1 << 8) /**< Flow Steering */\n #define NFP_NET_CFG_CTRL_VIRTIO           (0x1 << 10) /**< Virtio offload */\n #define NFP_NET_CFG_CTRL_IN_ORDER         (0x1 << 11) /**< Virtio in-order flag */\n+#define NFP_NET_CFG_CTRL_LM_RELAY         (0x1 << 12) /**< Virtio live migration relay start */\n+#define NFP_NET_CFG_CTRL_NOTIFY_DATA      (0x1 << 13) /**< Virtio notification data flag */\n+#define NFP_NET_CFG_CTRL_SWLM             (0x1 << 14) /**< Virtio SW live migration enable */\n #define NFP_NET_CFG_CTRL_USO              (0x1 << 16) /**< UDP segmentation offload */\n \n #define NFP_NET_CFG_CAP_WORD1           0x00a4\ndiff --git a/drivers/vdpa/nfp/nfp_vdpa.c b/drivers/vdpa/nfp/nfp_vdpa.c\nindex 1643ebbb8c..65f7144671 100644\n--- a/drivers/vdpa/nfp/nfp_vdpa.c\n+++ b/drivers/vdpa/nfp/nfp_vdpa.c\n@@ -11,6 +11,8 @@\n #include <nfp_common_pci.h>\n #include <nfp_dev.h>\n #include <rte_vfio.h>\n+#include <rte_eal_paging.h>\n+#include <rte_malloc.h>\n #include <vdpa_driver.h>\n \n #include \"nfp_vdpa_core.h\"\n@@ -21,6 +23,9 @@\n #define MSIX_IRQ_SET_BUF_LEN (sizeof(struct vfio_irq_set) + \\\n \t\tsizeof(int) * (NFP_VDPA_MAX_QUEUES * 2 + 1))\n \n+#define NFP_VDPA_USED_RING_LEN(size) \\\n+\t\t((size) * sizeof(struct vring_used_elem) + sizeof(struct vring_used))\n+\n struct nfp_vdpa_dev {\n \tstruct rte_pci_device *pci_dev;\n \tstruct rte_vdpa_device *vdev;\n@@ -261,15 +266,85 @@ nfp_vdpa_qva_to_gpa(int vid,\n \treturn gpa;\n }\n \n+static void\n+nfp_vdpa_relay_vring_free(struct nfp_vdpa_dev *device,\n+\t\tuint16_t vring_index)\n+{\n+\tuint16_t i;\n+\tuint64_t size;\n+\tstruct rte_vhost_vring vring;\n+\tuint64_t m_vring_iova = NFP_VDPA_RELAY_VRING;\n+\n+\tfor (i = 0; i < vring_index; i++) {\n+\t\trte_vhost_get_vhost_vring(device->vid, i, &vring);\n+\n+\t\tsize = RTE_ALIGN_CEIL(vring_size(vring.size, rte_mem_page_size()),\n+\t\t\t\trte_mem_page_size());\n+\t\trte_vfio_container_dma_unmap(device->vfio_container_fd,\n+\t\t\t\t(uint64_t)(uintptr_t)device->hw.m_vring[i].desc,\n+\t\t\t\tm_vring_iova, size);\n+\n+\t\trte_free(device->hw.m_vring[i].desc);\n+\t\tm_vring_iova += size;\n+\t}\n+}\n+\n static int\n-nfp_vdpa_start(struct nfp_vdpa_dev *device)\n+nfp_vdpa_relay_vring_alloc(struct nfp_vdpa_dev *device)\n+{\n+\tint ret;\n+\tuint16_t i;\n+\tuint64_t size;\n+\tvoid *vring_buf;\n+\tuint64_t page_size;\n+\tstruct rte_vhost_vring vring;\n+\tstruct nfp_vdpa_hw *vdpa_hw = &device->hw;\n+\tuint64_t m_vring_iova = NFP_VDPA_RELAY_VRING;\n+\n+\tpage_size = rte_mem_page_size();\n+\n+\tfor (i = 0; i < vdpa_hw->nr_vring; i++) {\n+\t\trte_vhost_get_vhost_vring(device->vid, i, &vring);\n+\n+\t\tsize = RTE_ALIGN_CEIL(vring_size(vring.size, page_size), page_size);\n+\t\tvring_buf = rte_zmalloc(\"nfp_vdpa_relay\", size, page_size);\n+\t\tif (vring_buf == NULL)\n+\t\t\tgoto vring_free_all;\n+\n+\t\tvring_init(&vdpa_hw->m_vring[i], vring.size, vring_buf, page_size);\n+\n+\t\tret = rte_vfio_container_dma_map(device->vfio_container_fd,\n+\t\t\t\t(uint64_t)(uintptr_t)vring_buf, m_vring_iova, size);\n+\t\tif (ret != 0) {\n+\t\t\tDRV_VDPA_LOG(ERR, \"vDPA vring relay dma map failed.\");\n+\t\t\tgoto vring_free_one;\n+\t\t}\n+\n+\t\tm_vring_iova += size;\n+\t}\n+\n+\treturn 0;\n+\n+vring_free_one:\n+\trte_free(device->hw.m_vring[i].desc);\n+vring_free_all:\n+\tnfp_vdpa_relay_vring_free(device, i);\n+\n+\treturn -ENOSPC;\n+}\n+\n+static int\n+nfp_vdpa_start(struct nfp_vdpa_dev *device,\n+\t\tbool relay)\n {\n \tint ret;\n \tint vid;\n \tuint16_t i;\n \tuint64_t gpa;\n+\tuint16_t size;\n \tstruct rte_vhost_vring vring;\n \tstruct nfp_vdpa_hw *vdpa_hw = &device->hw;\n+\tuint64_t m_vring_iova = NFP_VDPA_RELAY_VRING;\n \n \tvid = device->vid;\n \tvdpa_hw->nr_vring = rte_vhost_get_vring_num(vid);\n@@ -278,15 +353,21 @@ nfp_vdpa_start(struct nfp_vdpa_dev *device)\n \tif (ret != 0)\n \t\treturn ret;\n \n+\tif (relay) {\n+\t\tret = nfp_vdpa_relay_vring_alloc(device);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t}\n+\n \tfor (i = 0; i < vdpa_hw->nr_vring; i++) {\n \t\tret = rte_vhost_get_vhost_vring(vid, i, &vring);\n \t\tif (ret != 0)\n-\t\t\treturn ret;\n+\t\t\tgoto relay_vring_free;\n \n \t\tgpa = nfp_vdpa_qva_to_gpa(vid, (uint64_t)(uintptr_t)vring.desc);\n \t\tif (gpa == 0) {\n \t\t\tDRV_VDPA_LOG(ERR, \"Fail to get GPA for descriptor ring.\");\n-\t\t\treturn -1;\n+\t\t\tgoto relay_vring_free;\n \t\t}\n \n \t\tvdpa_hw->vring[i].desc = gpa;\n@@ -294,45 +375,122 @@ nfp_vdpa_start(struct nfp_vdpa_dev *device)\n \t\tgpa = nfp_vdpa_qva_to_gpa(vid, (uint64_t)(uintptr_t)vring.avail);\n \t\tif (gpa == 0) {\n \t\t\tDRV_VDPA_LOG(ERR, \"Fail to get GPA for available ring.\");\n-\t\t\treturn -1;\n+\t\t\tgoto relay_vring_free;\n \t\t}\n \n \t\tvdpa_hw->vring[i].avail = gpa;\n \n-\t\tgpa = nfp_vdpa_qva_to_gpa(vid, (uint64_t)(uintptr_t)vring.used);\n-\t\tif (gpa == 0) {\n-\t\t\tDRV_VDPA_LOG(ERR, \"Fail to get GPA for used ring.\");\n-\t\t\treturn -1;\n-\t\t}\n+\t\t/* Direct I/O for Tx queue, relay for Rx queue */\n+\t\tif (relay && ((i & 1) == 0)) {\n+\t\t\tvdpa_hw->vring[i].used = m_vring_iova +\n+\t\t\t\t\t(char *)vdpa_hw->m_vring[i].used -\n+\t\t\t\t\t(char *)vdpa_hw->m_vring[i].desc;\n+\n+\t\t\tret = rte_vhost_get_vring_base(vid, i,\n+\t\t\t\t\t&vdpa_hw->m_vring[i].avail->idx,\n+\t\t\t\t\t&vdpa_hw->m_vring[i].used->idx);\n+\t\t\tif (ret != 0)\n+\t\t\t\tgoto relay_vring_free;\n+\t\t} else {\n+\t\t\tgpa = nfp_vdpa_qva_to_gpa(vid, (uint64_t)(uintptr_t)vring.used);\n+\t\t\tif (gpa == 0) {\n+\t\t\t\tDRV_VDPA_LOG(ERR, \"Fail to get GPA for used ring.\");\n+\t\t\t\tgoto relay_vring_free;\n+\t\t\t}\n \n-\t\tvdpa_hw->vring[i].used = gpa;\n+\t\t\tvdpa_hw->vring[i].used = gpa;\n+\t\t}\n \n \t\tvdpa_hw->vring[i].size = vring.size;\n \n+\t\tif (relay) {\n+\t\t\tsize = RTE_ALIGN_CEIL(vring_size(vring.size,\n+\t\t\t\t\trte_mem_page_size()), rte_mem_page_size());\n+\t\t\tm_vring_iova += size;\n+\t\t}\n+\n \t\tret = rte_vhost_get_vring_base(vid, i,\n \t\t\t\t&vdpa_hw->vring[i].last_avail_idx,\n \t\t\t\t&vdpa_hw->vring[i].last_used_idx);\n \t\tif (ret != 0)\n-\t\t\treturn ret;\n+\t\t\tgoto relay_vring_free;\n \t}\n \n-\treturn nfp_vdpa_hw_start(&device->hw, vid);\n+\tif (relay)\n+\t\treturn nfp_vdpa_relay_hw_start(&device->hw, vid);\n+\telse\n+\t\treturn nfp_vdpa_hw_start(&device->hw, vid);\n+\n+relay_vring_free:\n+\tif (relay)\n+\t\tnfp_vdpa_relay_vring_free(device, vdpa_hw->nr_vring);\n+\n+\treturn -EFAULT;\n+}\n+\n+static void\n+nfp_vdpa_update_used_ring(struct nfp_vdpa_dev *dev,\n+\t\tuint16_t qid)\n+{\n+\trte_vdpa_relay_vring_used(dev->vid, qid, &dev->hw.m_vring[qid]);\n+\trte_vhost_vring_call(dev->vid, qid);\n }\n \n static void\n-nfp_vdpa_stop(struct nfp_vdpa_dev *device)\n+nfp_vdpa_relay_stop(struct nfp_vdpa_dev *device)\n {\n \tint vid;\n \tuint32_t i;\n+\tuint64_t len;\n+\tstruct rte_vhost_vring vring;\n \tstruct nfp_vdpa_hw *vdpa_hw = &device->hw;\n \n \tnfp_vdpa_hw_stop(vdpa_hw);\n \n \tvid = device->vid;\n-\tfor (i = 0; i < vdpa_hw->nr_vring; i++)\n+\tfor (i = 0; i < vdpa_hw->nr_vring; i++) {\n+\t\t/* Synchronize remaining new used entries if any */\n+\t\tif ((i & 1) == 0)\n+\t\t\tnfp_vdpa_update_used_ring(device, i);\n+\n+\t\trte_vhost_get_vhost_vring(vid, i, &vring);\n+\t\tlen = NFP_VDPA_USED_RING_LEN(vring.size);\n+\t\tvdpa_hw->vring[i].last_avail_idx = vring.avail->idx;\n+\t\tvdpa_hw->vring[i].last_used_idx = vring.used->idx;\n+\n \t\trte_vhost_set_vring_base(vid, i,\n \t\t\t\tvdpa_hw->vring[i].last_avail_idx,\n \t\t\t\tvdpa_hw->vring[i].last_used_idx);\n+\n+\t\trte_vhost_log_used_vring(vid, i, 0, len);\n+\n+\t\tif (vring.used->idx != vring.avail->idx)\n+\t\t\trte_atomic_store_explicit(&vring.used->idx, vring.avail->idx,\n+\t\t\t\t\trte_memory_order_relaxed);\n+\t}\n+\n+\tnfp_vdpa_relay_vring_free(device, vdpa_hw->nr_vring);\n+}\n+\n+static void\n+nfp_vdpa_stop(struct nfp_vdpa_dev *device,\n+\t\tbool relay)\n+{\n+\tint vid;\n+\tuint32_t i;\n+\tstruct nfp_vdpa_hw *vdpa_hw = &device->hw;\n+\n+\tnfp_vdpa_hw_stop(vdpa_hw);\n+\n+\tvid = device->vid;\n+\tif (relay)\n+\t\tnfp_vdpa_relay_stop(device);\n+\telse\n+\t\tfor (i = 0; i < vdpa_hw->nr_vring; i++)\n+\t\t\trte_vhost_set_vring_base(vid, i,\n+\t\t\t\t\tvdpa_hw->vring[i].last_avail_idx,\n+\t\t\t\t\tvdpa_hw->vring[i].last_used_idx);\n+\n }\n \n static int\n@@ -575,7 +733,7 @@ update_datapath(struct nfp_vdpa_dev *device)\n \t\tif (ret != 0)\n \t\t\tgoto dma_map_rollback;\n \n-\t\tret = nfp_vdpa_start(device);\n+\t\tret = nfp_vdpa_start(device, false);\n \t\tif (ret != 0)\n \t\t\tgoto disable_vfio_intr;\n \n@@ -591,7 +749,7 @@ update_datapath(struct nfp_vdpa_dev *device)\n \t\t\t\t\trte_memory_order_relaxed) != 0))) {\n \t\tnfp_vdpa_unset_notify_relay(device);\n \n-\t\tnfp_vdpa_stop(device);\n+\t\tnfp_vdpa_stop(device, false);\n \n \t\tret = nfp_vdpa_disable_vfio_intr(device);\n \t\tif (ret != 0)\n@@ -608,7 +766,7 @@ update_datapath(struct nfp_vdpa_dev *device)\n \treturn 0;\n \n vdpa_stop:\n-\tnfp_vdpa_stop(device);\n+\tnfp_vdpa_stop(device, false);\n disable_vfio_intr:\n \tnfp_vdpa_disable_vfio_intr(device);\n dma_map_rollback:\n@@ -639,10 +797,17 @@ nfp_vdpa_sw_fallback(struct nfp_vdpa_dev *device)\n \tif (ret != 0)\n \t\tgoto error;\n \n+\t/* Config the VF */\n+\tret = nfp_vdpa_start(device, true);\n+\tif (ret != 0)\n+\t\tgoto unset_intr;\n+\n \tdevice->hw.sw_fallback_running = true;\n \n \treturn 0;\n \n+unset_intr:\n+\tnfp_vdpa_disable_vfio_intr(device);\n error:\n \treturn ret;\n }\n@@ -691,6 +856,9 @@ nfp_vdpa_dev_close(int vid)\n \n \tdevice = node->device;\n \tif (device->hw.sw_fallback_running) {\n+\t\t/* Reset VF */\n+\t\tnfp_vdpa_stop(device, true);\n+\n \t\tdevice->hw.sw_fallback_running = false;\n \n \t\trte_atomic_store_explicit(&device->dev_attached, 0,\ndiff --git a/drivers/vdpa/nfp/nfp_vdpa_core.c b/drivers/vdpa/nfp/nfp_vdpa_core.c\nindex 82a323a6d0..63a69aaf36 100644\n--- a/drivers/vdpa/nfp/nfp_vdpa_core.c\n+++ b/drivers/vdpa/nfp/nfp_vdpa_core.c\n@@ -110,7 +110,8 @@ nfp_vdpa_check_offloads(void)\n \n static int\n nfp_vdpa_vf_config(struct nfp_hw *hw,\n-\t\tint vid)\n+\t\tint vid,\n+\t\tbool relay)\n {\n \tint ret;\n \tuint32_t update;\n@@ -134,6 +135,10 @@ nfp_vdpa_vf_config(struct nfp_hw *hw,\n \tnfp_write_mac(hw, (uint8_t *)mac_addr);\n \n \tnew_ext_ctrl = nfp_vdpa_check_offloads();\n+\tif (relay)\n+\t\tnew_ext_ctrl |= NFP_NET_CFG_CTRL_LM_RELAY;\n+\telse\n+\t\tnew_ext_ctrl |= NFP_NET_CFG_CTRL_SWLM;\n \n \tupdate = NFP_NET_CFG_UPDATE_GEN;\n \tret = nfp_ext_reconfig(hw, new_ext_ctrl, update);\n@@ -150,6 +155,15 @@ nfp_vdpa_vf_config(struct nfp_hw *hw,\n \t\t\tNFP_NET_CFG_UPDATE_GEN |\n \t\t\tNFP_NET_CFG_UPDATE_RING;\n \n+\tif (relay) {\n+\t\tupdate |= NFP_NET_CFG_UPDATE_MSIX;\n+\n+\t\t/* Enable misx interrupt for vdpa relay */\n+\t\tnew_ctrl |= NFP_NET_CFG_CTRL_MSIX_TX_OFF;\n+\n+\t\tnn_cfg_writeb(hw, NFP_NET_CFG_RXR_VEC(0), 1);\n+\t}\n+\n \tret = nfp_reconfig(hw, new_ctrl, update);\n \tif (ret < 0)\n \t\treturn -EIO;\n@@ -165,20 +179,24 @@ nfp_vdpa_vf_config(struct nfp_hw *hw,\n }\n \n static void\n-nfp_vdpa_queue_config(struct nfp_vdpa_hw *vdpa_hw)\n+nfp_vdpa_queue_config(struct nfp_vdpa_hw *vdpa_hw,\n+\t\tbool relay)\n {\n \tstruct nfp_hw *hw = &vdpa_hw->super;\n \n-\tnn_cfg_writeq(hw, NFP_NET_CFG_TXR_ADDR(0), vdpa_hw->vring[1].desc);\n-\tnn_cfg_writeb(hw, NFP_NET_CFG_TXR_SZ(0),\n-\t\t\trte_log2_u32(vdpa_hw->vring[1].size));\n-\tnn_cfg_writeq(hw, NFP_NET_CFG_TXR_ADDR(1), vdpa_hw->vring[1].avail);\n-\tnn_cfg_writeq(hw, NFP_NET_CFG_TXR_ADDR(2), vdpa_hw->vring[1].used);\n+\tif (!relay) {\n+\t\tnn_cfg_writeq(hw, NFP_NET_CFG_TXR_ADDR(0), vdpa_hw->vring[1].desc);\n+\t\tnn_cfg_writeb(hw, NFP_NET_CFG_TXR_SZ(0),\n+\t\t\t\trte_log2_u32(vdpa_hw->vring[1].size));\n+\t\tnn_cfg_writeq(hw, NFP_NET_CFG_TXR_ADDR(1), vdpa_hw->vring[1].avail);\n+\t\tnn_cfg_writeq(hw, NFP_NET_CFG_TXR_ADDR(2), vdpa_hw->vring[1].used);\n+\n+\t\tnn_cfg_writeq(hw, NFP_NET_CFG_RXR_ADDR(0), vdpa_hw->vring[0].desc);\n+\t\tnn_cfg_writeb(hw, NFP_NET_CFG_RXR_SZ(0),\n+\t\t\t\trte_log2_u32(vdpa_hw->vring[0].size));\n+\t\tnn_cfg_writeq(hw, NFP_NET_CFG_RXR_ADDR(1), vdpa_hw->vring[0].avail);\n+\t}\n \n-\tnn_cfg_writeq(hw, NFP_NET_CFG_RXR_ADDR(0), vdpa_hw->vring[0].desc);\n-\tnn_cfg_writeb(hw, NFP_NET_CFG_RXR_SZ(0),\n-\t\t\trte_log2_u32(vdpa_hw->vring[0].size));\n-\tnn_cfg_writeq(hw, NFP_NET_CFG_RXR_ADDR(1), vdpa_hw->vring[0].avail);\n \tnn_cfg_writeq(hw, NFP_NET_CFG_RXR_ADDR(2), vdpa_hw->vring[0].used);\n \n \trte_wmb();\n@@ -190,12 +208,23 @@ nfp_vdpa_hw_start(struct nfp_vdpa_hw *vdpa_hw,\n {\n \tstruct nfp_hw *hw = &vdpa_hw->super;\n \n-\tnfp_vdpa_queue_config(vdpa_hw);\n+\tnfp_vdpa_queue_config(vdpa_hw, false);\n \n \tnfp_disable_queues(hw);\n \tnfp_enable_queues(hw, NFP_VDPA_MAX_QUEUES, NFP_VDPA_MAX_QUEUES);\n \n-\treturn nfp_vdpa_vf_config(hw, vid);\n+\treturn nfp_vdpa_vf_config(hw, vid, false);\n+}\n+\n+int\n+nfp_vdpa_relay_hw_start(struct nfp_vdpa_hw *vdpa_hw,\n+\t\tint vid)\n+{\n+\tstruct nfp_hw *hw = &vdpa_hw->super;\n+\n+\tnfp_vdpa_queue_config(vdpa_hw, true);\n+\n+\treturn nfp_vdpa_vf_config(hw, vid, true);\n }\n \n void\ndiff --git a/drivers/vdpa/nfp/nfp_vdpa_core.h b/drivers/vdpa/nfp/nfp_vdpa_core.h\nindex 0f880fc0c6..a339ace601 100644\n--- a/drivers/vdpa/nfp/nfp_vdpa_core.h\n+++ b/drivers/vdpa/nfp/nfp_vdpa_core.h\n@@ -9,12 +9,15 @@\n #include <bus_pci_driver.h>\n #include <nfp_common.h>\n #include <rte_ether.h>\n+#include <rte_vhost.h>\n \n #define NFP_VDPA_MAX_QUEUES         1\n \n #define NFP_VDPA_NOTIFY_ADDR_BASE        0x4000\n #define NFP_VDPA_NOTIFY_ADDR_INTERVAL    0x1000\n \n+#define NFP_VDPA_RELAY_VRING             0xd0000000\n+\n struct nfp_vdpa_vring {\n \tuint64_t desc;\n \tuint64_t avail;\n@@ -40,12 +43,17 @@ struct nfp_vdpa_hw {\n \t/** Software Live Migration */\n \tbool sw_lm;\n \tbool sw_fallback_running;\n+\n+\t/** Mediated vring for SW fallback */\n+\tstruct vring m_vring[NFP_VDPA_MAX_QUEUES * 2];\n };\n \n int nfp_vdpa_hw_init(struct nfp_vdpa_hw *vdpa_hw, struct rte_pci_device *dev);\n \n int nfp_vdpa_hw_start(struct nfp_vdpa_hw *vdpa_hw, int vid);\n \n+int nfp_vdpa_relay_hw_start(struct nfp_vdpa_hw *vdpa_hw, int vid);\n+\n void nfp_vdpa_hw_stop(struct nfp_vdpa_hw *vdpa_hw);\n \n void nfp_vdpa_notify_queue(struct nfp_vdpa_hw *vdpa_hw, uint16_t qid);\n",
    "prefixes": [
        "07/10"
    ]
}