get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 44507,
    "url": "https://patches.dpdk.org/api/patches/44507/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20180910110123.138273-1-xiao.w.wang@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": "<20180910110123.138273-1-xiao.w.wang@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20180910110123.138273-1-xiao.w.wang@intel.com",
    "date": "2018-09-10T11:01:23",
    "name": "net/ifc: add live migration support",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "6c77960287f51f86b9a2f7068a01556c773fa6f4",
    "submitter": {
        "id": 281,
        "url": "https://patches.dpdk.org/api/people/281/?format=api",
        "name": "Xiao Wang",
        "email": "xiao.w.wang@intel.com"
    },
    "delegate": {
        "id": 1540,
        "url": "https://patches.dpdk.org/api/users/1540/?format=api",
        "username": "qzhan15",
        "first_name": "Qi",
        "last_name": "Zhang",
        "email": "qi.z.zhang@intel.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20180910110123.138273-1-xiao.w.wang@intel.com/mbox/",
    "series": [
        {
            "id": 1246,
            "url": "https://patches.dpdk.org/api/series/1246/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=1246",
            "date": "2018-09-10T11:01:23",
            "name": "net/ifc: add live migration support",
            "version": 1,
            "mbox": "https://patches.dpdk.org/series/1246/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/44507/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/44507/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 59EDA378B;\n\tMon, 10 Sep 2018 13:09:04 +0200 (CEST)",
            "from mga06.intel.com (mga06.intel.com [134.134.136.31])\n\tby dpdk.org (Postfix) with ESMTP id EF6C51B19\n\tfor <dev@dpdk.org>; Mon, 10 Sep 2018 13:09:01 +0200 (CEST)",
            "from fmsmga005.fm.intel.com ([10.253.24.32])\n\tby orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t10 Sep 2018 04:09:00 -0700",
            "from dpdk-xiao-1.sh.intel.com ([10.67.111.123])\n\tby fmsmga005.fm.intel.com with ESMTP; 10 Sep 2018 04:08:56 -0700"
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.53,355,1531810800\"; d=\"scan'208\";a=\"261306743\"",
        "From": "Xiao Wang <xiao.w.wang@intel.com>",
        "To": "tiwei.bie@intel.com",
        "Cc": "dev@dpdk.org, xiaolong.ye@intel.com, zhihong.wang@intel.com,\n\tXiao Wang <xiao.w.wang@intel.com>",
        "Date": "Mon, 10 Sep 2018 19:01:23 +0800",
        "Message-Id": "<20180910110123.138273-1-xiao.w.wang@intel.com>",
        "X-Mailer": "git-send-email 2.15.1",
        "Subject": "[dpdk-dev] [PATCH] net/ifc: add live migration support",
        "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": "IFCVF can help to log dirty page in live migration stage,\neach queue's index can be read and configured to support\nVHOST_USER_GET_VRING_BASE and VHOST_USER_SET_VRING_BASE.\n\nSigned-off-by: Xiao Wang <xiao.w.wang@intel.com>\n---\n drivers/net/ifc/base/ifcvf.c | 33 +++++++++++++++++++-\n drivers/net/ifc/base/ifcvf.h |  7 +++++\n drivers/net/ifc/ifcvf_vdpa.c | 71 ++++++++++++++++++++++++++++++++++++++++++--\n 3 files changed, 108 insertions(+), 3 deletions(-)",
    "diff": "diff --git a/drivers/net/ifc/base/ifcvf.c b/drivers/net/ifc/base/ifcvf.c\nindex 4b22d9ed1..3c0b2dff6 100644\n--- a/drivers/net/ifc/base/ifcvf.c\n+++ b/drivers/net/ifc/base/ifcvf.c\n@@ -249,7 +249,7 @@ ifcvf_hw_disable(struct ifcvf_hw *hw)\n \t\tIFCVF_WRITE_REG16(IFCVF_MSI_NO_VECTOR, &cfg->queue_msix_vector);\n \t\tring_state = *(u32 *)(hw->lm_cfg + IFCVF_LM_RING_STATE_OFFSET +\n \t\t\t\t(i / 2) * IFCVF_LM_CFG_SIZE + (i % 2) * 4);\n-\t\thw->vring[i].last_avail_idx = (u16)ring_state;\n+\t\thw->vring[i].last_avail_idx = (u16)(ring_state >> 16);\n \t\thw->vring[i].last_used_idx = (u16)(ring_state >> 16);\n \t}\n }\n@@ -278,6 +278,37 @@ ifcvf_stop_hw(struct ifcvf_hw *hw)\n \tifcvf_reset(hw);\n }\n \n+void\n+ifcvf_enable_logging(struct ifcvf_hw *hw, u64 log_base, u64 log_size)\n+{\n+\tu8 *lm_cfg;\n+\n+\tlm_cfg = hw->lm_cfg;\n+\n+\t*(u32 *)(lm_cfg + IFCVF_LM_BASE_ADDR_LOW) =\n+\t\tlog_base & IFCVF_32_BIT_MASK;\n+\n+\t*(u32 *)(lm_cfg + IFCVF_LM_BASE_ADDR_HIGH) =\n+\t\t(log_base >> 32) & IFCVF_32_BIT_MASK;\n+\n+\t*(u32 *)(lm_cfg + IFCVF_LM_END_ADDR_LOW) =\n+\t\t(log_base + log_size) & IFCVF_32_BIT_MASK;\n+\n+\t*(u32 *)(lm_cfg + IFCVF_LM_END_ADDR_HIGH) =\n+\t\t((log_base + log_size) >> 32) & IFCVF_32_BIT_MASK;\n+\n+\t*(u32 *)(lm_cfg + IFCVF_LM_LOGGING_CTRL) = IFCVF_LM_ENABLE_VF;\n+}\n+\n+void\n+ifcvf_disable_logging(struct ifcvf_hw *hw)\n+{\n+\tu8 *lm_cfg;\n+\n+\tlm_cfg = hw->lm_cfg;\n+\t*(u32 *)(lm_cfg + IFCVF_LM_LOGGING_CTRL) = IFCVF_LM_DISABLE;\n+}\n+\n void\n ifcvf_notify_queue(struct ifcvf_hw *hw, u16 qid)\n {\ndiff --git a/drivers/net/ifc/base/ifcvf.h b/drivers/net/ifc/base/ifcvf.h\nindex badacb615..f026c70ab 100644\n--- a/drivers/net/ifc/base/ifcvf.h\n+++ b/drivers/net/ifc/base/ifcvf.h\n@@ -49,6 +49,7 @@\n #define IFCVF_LM_DISABLE\t\t0x0\n #define IFCVF_LM_ENABLE_VF\t\t0x1\n #define IFCVF_LM_ENABLE_PF\t\t0x3\n+#define IFCVF_LOG_BASE\t\t\t0x100000000000\n \n #define IFCVF_32_BIT_MASK\t\t0xffffffff\n \n@@ -142,6 +143,12 @@ ifcvf_start_hw(struct ifcvf_hw *hw);\n void\n ifcvf_stop_hw(struct ifcvf_hw *hw);\n \n+void\n+ifcvf_enable_logging(struct ifcvf_hw *hw, u64 log_base, u64 log_size);\n+\n+void\n+ifcvf_disable_logging(struct ifcvf_hw *hw);\n+\n void\n ifcvf_notify_queue(struct ifcvf_hw *hw, u16 qid);\n \ndiff --git a/drivers/net/ifc/ifcvf_vdpa.c b/drivers/net/ifc/ifcvf_vdpa.c\nindex 88d814037..3c5430dc0 100644\n--- a/drivers/net/ifc/ifcvf_vdpa.c\n+++ b/drivers/net/ifc/ifcvf_vdpa.c\n@@ -7,6 +7,7 @@\n #include <fcntl.h>\n #include <sys/ioctl.h>\n #include <sys/epoll.h>\n+#include <linux/virtio_net.h>\n \n #include <rte_malloc.h>\n #include <rte_memory.h>\n@@ -276,12 +277,30 @@ vdpa_ifcvf_start(struct ifcvf_internal *internal)\n \treturn ifcvf_start_hw(&internal->hw);\n }\n \n+static void\n+ifcvf_used_ring_log(struct ifcvf_hw *hw, uint32_t queue, uint8_t *log_buf)\n+{\n+\tuint32_t i, size;\n+\tuint64_t pfn;\n+\n+\tpfn = hw->vring[queue].used / PAGE_SIZE;\n+\tsize = hw->vring[queue].size * sizeof(struct vring_used_elem) +\n+\t\t\tsizeof(__virtio16) * 3;\n+\n+\tfor (i = 0; i <= size / PAGE_SIZE; i++)\n+\t\t__sync_fetch_and_or_8(&log_buf[(pfn + i) / 8],\n+\t\t\t\t1 << ((pfn + i) % 8));\n+}\n+\n static void\n vdpa_ifcvf_stop(struct ifcvf_internal *internal)\n {\n \tstruct ifcvf_hw *hw = &internal->hw;\n \tuint32_t i;\n \tint vid;\n+\tuint64_t features;\n+\tuint64_t log_base, log_size;\n+\tuint8_t *log_buf;\n \n \tvid = internal->vid;\n \tifcvf_stop_hw(hw);\n@@ -289,6 +308,21 @@ vdpa_ifcvf_stop(struct ifcvf_internal *internal)\n \tfor (i = 0; i < hw->nr_vring; i++)\n \t\trte_vhost_set_vring_base(vid, i, hw->vring[i].last_avail_idx,\n \t\t\t\thw->vring[i].last_used_idx);\n+\n+\trte_vhost_get_negotiated_features(vid, &features);\n+\tif (RTE_VHOST_NEED_LOG(features)) {\n+\t\tifcvf_disable_logging(hw);\n+\t\trte_vhost_get_log_base(internal->vid, &log_base, &log_size);\n+\t\trte_vfio_container_dma_unmap(internal->vfio_container_fd,\n+\t\t\t\tlog_base, IFCVF_LOG_BASE, log_size);\n+\t\t/*\n+\t\t * IFCVF marks dirty memory pages for only packet buffer,\n+\t\t * SW helps to mark the used ring as dirty after device stops.\n+\t\t */\n+\t\tlog_buf = (uint8_t *)(uintptr_t)log_base;\n+\t\tfor (i = 0; i < hw->nr_vring; i++)\n+\t\t\tifcvf_used_ring_log(hw, i, log_buf);\n+\t}\n }\n \n #define MSIX_IRQ_SET_BUF_LEN (sizeof(struct vfio_irq_set) + \\\n@@ -548,6 +582,35 @@ ifcvf_dev_close(int vid)\n \treturn 0;\n }\n \n+static int\n+ifcvf_set_features(int vid)\n+{\n+\tuint64_t features;\n+\tint did;\n+\tstruct internal_list *list;\n+\tstruct ifcvf_internal *internal;\n+\tuint64_t log_base, log_size;\n+\n+\tdid = rte_vhost_get_vdpa_device_id(vid);\n+\tlist = find_internal_resource_by_did(did);\n+\tif (list == NULL) {\n+\t\tDRV_LOG(ERR, \"Invalid device id: %d\", did);\n+\t\treturn -1;\n+\t}\n+\n+\tinternal = list->internal;\n+\trte_vhost_get_negotiated_features(vid, &features);\n+\n+\tif (RTE_VHOST_NEED_LOG(features)) {\n+\t\trte_vhost_get_log_base(vid, &log_base, &log_size);\n+\t\trte_vfio_container_dma_map(internal->vfio_container_fd,\n+\t\t\t\tlog_base, IFCVF_LOG_BASE, log_size);\n+\t\tifcvf_enable_logging(&internal->hw, IFCVF_LOG_BASE, log_size);\n+\t}\n+\n+\treturn 0;\n+}\n+\n static int\n ifcvf_get_vfio_group_fd(int vid)\n {\n@@ -664,7 +727,7 @@ struct rte_vdpa_dev_ops ifcvf_ops = {\n \t.dev_conf = ifcvf_dev_config,\n \t.dev_close = ifcvf_dev_close,\n \t.set_vring_state = NULL,\n-\t.set_features = NULL,\n+\t.set_features = ifcvf_set_features,\n \t.migration_done = NULL,\n \t.get_vfio_group_fd = ifcvf_get_vfio_group_fd,\n \t.get_vfio_device_fd = ifcvf_get_vfio_device_fd,\n@@ -699,7 +762,11 @@ ifcvf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,\n \tfeatures = ifcvf_get_features(&internal->hw);\n \tinternal->features = (features &\n \t\t~(1ULL << VIRTIO_F_IOMMU_PLATFORM)) |\n-\t\t(1ULL << VHOST_USER_F_PROTOCOL_FEATURES);\n+\t\t(1ULL << VIRTIO_NET_F_GUEST_ANNOUNCE) |\n+\t\t(1ULL << VIRTIO_NET_F_CTRL_VQ) |\n+\t\t(1ULL << VIRTIO_NET_F_STATUS) |\n+\t\t(1ULL << VHOST_USER_F_PROTOCOL_FEATURES) |\n+\t\t(1ULL << VHOST_F_LOG_ALL);\n \n \tinternal->dev_addr.pci_addr = pci_dev->addr;\n \tinternal->dev_addr.type = PCI_ADDR;\n",
    "prefixes": []
}