get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 63064,
    "url": "http://patches.dpdk.org/api/patches/63064/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20191117151244.3854-2-david.marchand@redhat.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": "<20191117151244.3854-2-david.marchand@redhat.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20191117151244.3854-2-david.marchand@redhat.com",
    "date": "2019-11-17T15:12:43",
    "name": "[v15,1/2] kni: support userspace VA",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "bba1b885cc2334d7406bba98070c40258cb60bbd",
    "submitter": {
        "id": 1173,
        "url": "http://patches.dpdk.org/api/people/1173/?format=api",
        "name": "David Marchand",
        "email": "david.marchand@redhat.com"
    },
    "delegate": {
        "id": 24651,
        "url": "http://patches.dpdk.org/api/users/24651/?format=api",
        "username": "dmarchand",
        "first_name": "David",
        "last_name": "Marchand",
        "email": "david.marchand@redhat.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20191117151244.3854-2-david.marchand@redhat.com/mbox/",
    "series": [
        {
            "id": 7486,
            "url": "http://patches.dpdk.org/api/series/7486/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=7486",
            "date": "2019-11-17T15:12:42",
            "name": "kni: support IOVA mode",
            "version": 15,
            "mbox": "http://patches.dpdk.org/series/7486/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/63064/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/63064/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 dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 1A469A04B4;\n\tSun, 17 Nov 2019 16:13:12 +0100 (CET)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id A1B1458C4;\n\tSun, 17 Nov 2019 16:13:06 +0100 (CET)",
            "from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com\n [207.211.31.120]) by dpdk.org (Postfix) with ESMTP id 9D5EE54AE\n for <dev@dpdk.org>; Sun, 17 Nov 2019 16:13:04 +0100 (CET)",
            "from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com\n [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id\n us-mta-273-2lE0cyWkMBGiZcJZPT5BjQ-1; Sun, 17 Nov 2019 10:13:00 -0500",
            "from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com\n [10.5.11.11])\n (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))\n (No client certificate requested)\n by mimecast-mx01.redhat.com (Postfix) with ESMTPS id BC2FA1800D4F;\n Sun, 17 Nov 2019 15:12:58 +0000 (UTC)",
            "from dmarchan.remote.csb (unknown [10.40.205.71])\n by smtp.corp.redhat.com (Postfix) with ESMTP id 0969160171;\n Sun, 17 Nov 2019 15:12:55 +0000 (UTC)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1574003584;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:cc:mime-version:mime-version:content-type:content-type:\n content-transfer-encoding:content-transfer-encoding:\n in-reply-to:in-reply-to:references:references;\n bh=v+qXnrcQ30tnw0rHLHFBmijOSwhm+XiUaf0EoUzPWEM=;\n b=B9gQ/DOsAT6ZoT89Z+/ptvs2Irorx4OEBtL1fSnvqdzd16hVnDX50cYETKAj1CYsV+qrN5\n WKwmvexRihYOFbdd9eK1j5kKJ+kJWa9bi+ehZ7q5E2pt/lT3f1/nxj+iAdAA7YNoVh8gnd\n DJgKeNrBtE9WJVGq3mZEvud+Mn3TCVM=",
        "From": "David Marchand <david.marchand@redhat.com>",
        "To": "dev@dpdk.org",
        "Cc": "thomas@monjalon.net, kirankumark@marvell.com, olivier.matz@6wind.com,\n ferruh.yigit@intel.com, anatoly.burakov@intel.com,\n arybchenko@solarflare.com, stephen@networkplumber.org,\n vattunuru@marvell.com",
        "Date": "Sun, 17 Nov 2019 16:12:43 +0100",
        "Message-Id": "<20191117151244.3854-2-david.marchand@redhat.com>",
        "In-Reply-To": "<20191117151244.3854-1-david.marchand@redhat.com>",
        "References": "<20191117151244.3854-1-david.marchand@redhat.com>",
        "MIME-Version": "1.0",
        "X-Scanned-By": "MIMEDefang 2.79 on 10.5.11.11",
        "X-MC-Unique": "2lE0cyWkMBGiZcJZPT5BjQ-1",
        "X-Mimecast-Spam-Score": "0",
        "Content-Type": "text/plain; charset=US-ASCII",
        "Content-Transfer-Encoding": "quoted-printable",
        "Subject": "[dpdk-dev] [PATCH v15 1/2] kni: support userspace VA",
        "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 <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",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Vamsi Attunuru <vattunuru@marvell.com>\n\nPatch adds support for kernel module to work in IOVA = VA mode by\nproviding address translation routines to convert userspace VA to\nkernel VA.\n\nKNI performance using PA is not changed by this patch.\nBut comparing KNI using PA to KNI using VA, the latter will have lower\nperformance due to the cost of the added translation.\n\nThis translation is implemented only with kernel versions starting 4.6.0.\n\nSigned-off-by: Vamsi Attunuru <vattunuru@marvell.com>\nSigned-off-by: Kiran Kumar K <kirankumark@marvell.com>\n---\nChangelog since v14:\n- reworded commitlog,\n\n---\n kernel/linux/kni/compat.h                     | 14 +++++\n kernel/linux/kni/kni_dev.h                    | 42 +++++++++++++\n kernel/linux/kni/kni_misc.c                   | 39 +++++++++---\n kernel/linux/kni/kni_net.c                    | 62 +++++++++++++++----\n .../linux/eal/include/rte_kni_common.h        |  1 +\n 5 files changed, 136 insertions(+), 22 deletions(-)",
    "diff": "diff --git a/kernel/linux/kni/compat.h b/kernel/linux/kni/compat.h\nindex 562d8bf94..062b170ef 100644\n--- a/kernel/linux/kni/compat.h\n+++ b/kernel/linux/kni/compat.h\n@@ -121,3 +121,17 @@\n #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)\n #define HAVE_SIGNAL_FUNCTIONS_OWN_HEADER\n #endif\n+\n+#if KERNEL_VERSION(4, 6, 0) <= LINUX_VERSION_CODE\n+\n+#define HAVE_IOVA_TO_KVA_MAPPING_SUPPORT\n+\n+#if KERNEL_VERSION(4, 9, 0) > LINUX_VERSION_CODE\n+#define GET_USER_PAGES_REMOTE_API_V1\n+#elif KERNEL_VERSION(4, 9, 0) == LINUX_VERSION_CODE\n+#define GET_USER_PAGES_REMOTE_API_V2\n+#else\n+#define GET_USER_PAGES_REMOTE_API_V3\n+#endif\n+\n+#endif\ndiff --git a/kernel/linux/kni/kni_dev.h b/kernel/linux/kni/kni_dev.h\nindex c1ca6789c..fb641b696 100644\n--- a/kernel/linux/kni/kni_dev.h\n+++ b/kernel/linux/kni/kni_dev.h\n@@ -41,6 +41,8 @@ struct kni_dev {\n \t/* kni list */\n \tstruct list_head list;\n \n+\tuint8_t iova_mode;\n+\n \tuint32_t core_id;            /* Core ID to bind */\n \tchar name[RTE_KNI_NAMESIZE]; /* Network device name */\n \tstruct task_struct *pthread;\n@@ -84,8 +86,48 @@ struct kni_dev {\n \tvoid *va[MBUF_BURST_SZ];\n \tvoid *alloc_pa[MBUF_BURST_SZ];\n \tvoid *alloc_va[MBUF_BURST_SZ];\n+\n+\tstruct task_struct *usr_tsk;\n };\n \n+#ifdef HAVE_IOVA_TO_KVA_MAPPING_SUPPORT\n+static inline phys_addr_t iova_to_phys(struct task_struct *tsk,\n+\t\t\t\t       unsigned long iova)\n+{\n+\tphys_addr_t offset, phys_addr;\n+\tstruct page *page = NULL;\n+\tlong ret;\n+\n+\toffset = iova & (PAGE_SIZE - 1);\n+\n+\t/* Read one page struct info */\n+#ifdef GET_USER_PAGES_REMOTE_API_V3\n+\tret = get_user_pages_remote(tsk, tsk->mm, iova, 1,\n+\t\t\t\t    FOLL_TOUCH, &page, NULL, NULL);\n+#endif\n+#ifdef GET_USER_PAGES_REMOTE_API_V2\n+\tret = get_user_pages_remote(tsk, tsk->mm, iova, 1,\n+\t\t\t\t    FOLL_TOUCH, &page, NULL);\n+#endif\n+#ifdef GET_USER_PAGES_REMOTE_API_V1\n+\tret = get_user_pages_remote(tsk, tsk->mm, iova, 1\n+\t\t\t\t    0, 0, &page, NULL);\n+#endif\n+\tif (ret < 0)\n+\t\treturn 0;\n+\n+\tphys_addr = page_to_phys(page) | offset;\n+\tput_page(page);\n+\n+\treturn phys_addr;\n+}\n+\n+static inline void *iova_to_kva(struct task_struct *tsk, unsigned long iova)\n+{\n+\treturn phys_to_virt(iova_to_phys(tsk, iova));\n+}\n+#endif\n+\n void kni_net_release_fifo_phy(struct kni_dev *kni);\n void kni_net_rx(struct kni_dev *kni);\n void kni_net_init(struct net_device *dev);\ndiff --git a/kernel/linux/kni/kni_misc.c b/kernel/linux/kni/kni_misc.c\nindex 84ef03b5f..cda71bde0 100644\n--- a/kernel/linux/kni/kni_misc.c\n+++ b/kernel/linux/kni/kni_misc.c\n@@ -348,15 +348,36 @@ kni_ioctl_create(struct net *net, uint32_t ioctl_num,\n \tstrncpy(kni->name, dev_info.name, RTE_KNI_NAMESIZE);\n \n \t/* Translate user space info into kernel space info */\n-\tkni->tx_q = phys_to_virt(dev_info.tx_phys);\n-\tkni->rx_q = phys_to_virt(dev_info.rx_phys);\n-\tkni->alloc_q = phys_to_virt(dev_info.alloc_phys);\n-\tkni->free_q = phys_to_virt(dev_info.free_phys);\n-\n-\tkni->req_q = phys_to_virt(dev_info.req_phys);\n-\tkni->resp_q = phys_to_virt(dev_info.resp_phys);\n-\tkni->sync_va = dev_info.sync_va;\n-\tkni->sync_kva = phys_to_virt(dev_info.sync_phys);\n+\tif (dev_info.iova_mode) {\n+#ifdef HAVE_IOVA_TO_KVA_MAPPING_SUPPORT\n+\t\tkni->tx_q = iova_to_kva(current, dev_info.tx_phys);\n+\t\tkni->rx_q = iova_to_kva(current, dev_info.rx_phys);\n+\t\tkni->alloc_q = iova_to_kva(current, dev_info.alloc_phys);\n+\t\tkni->free_q = iova_to_kva(current, dev_info.free_phys);\n+\n+\t\tkni->req_q = iova_to_kva(current, dev_info.req_phys);\n+\t\tkni->resp_q = iova_to_kva(current, dev_info.resp_phys);\n+\t\tkni->sync_va = dev_info.sync_va;\n+\t\tkni->sync_kva = iova_to_kva(current, dev_info.sync_phys);\n+\t\tkni->usr_tsk = current;\n+\t\tkni->iova_mode = 1;\n+#else\n+\t\tpr_err(\"KNI module does not support IOVA to VA translation\\n\");\n+\t\treturn -EINVAL;\n+#endif\n+\t} else {\n+\n+\t\tkni->tx_q = phys_to_virt(dev_info.tx_phys);\n+\t\tkni->rx_q = phys_to_virt(dev_info.rx_phys);\n+\t\tkni->alloc_q = phys_to_virt(dev_info.alloc_phys);\n+\t\tkni->free_q = phys_to_virt(dev_info.free_phys);\n+\n+\t\tkni->req_q = phys_to_virt(dev_info.req_phys);\n+\t\tkni->resp_q = phys_to_virt(dev_info.resp_phys);\n+\t\tkni->sync_va = dev_info.sync_va;\n+\t\tkni->sync_kva = phys_to_virt(dev_info.sync_phys);\n+\t\tkni->iova_mode = 0;\n+\t}\n \n \tkni->mbuf_size = dev_info.mbuf_size;\n \ndiff --git a/kernel/linux/kni/kni_net.c b/kernel/linux/kni/kni_net.c\nindex f25b1277b..1ba9b1b99 100644\n--- a/kernel/linux/kni/kni_net.c\n+++ b/kernel/linux/kni/kni_net.c\n@@ -36,6 +36,22 @@ static void kni_net_rx_normal(struct kni_dev *kni);\n /* kni rx function pointer, with default to normal rx */\n static kni_net_rx_t kni_net_rx_func = kni_net_rx_normal;\n \n+#ifdef HAVE_IOVA_TO_KVA_MAPPING_SUPPORT\n+/* iova to kernel virtual address */\n+static inline void *\n+iova2kva(struct kni_dev *kni, void *iova)\n+{\n+\treturn phys_to_virt(iova_to_phys(kni->usr_tsk, (unsigned long)iova));\n+}\n+\n+static inline void *\n+iova2data_kva(struct kni_dev *kni, struct rte_kni_mbuf *m)\n+{\n+\treturn phys_to_virt(iova_to_phys(kni->usr_tsk, m->buf_physaddr) +\n+\t\t\t    m->data_off);\n+}\n+#endif\n+\n /* physical address to kernel virtual address */\n static void *\n pa2kva(void *pa)\n@@ -62,6 +78,26 @@ kva2data_kva(struct rte_kni_mbuf *m)\n \treturn phys_to_virt(m->buf_physaddr + m->data_off);\n }\n \n+static inline void *\n+get_kva(struct kni_dev *kni, void *pa)\n+{\n+#ifdef HAVE_IOVA_TO_KVA_MAPPING_SUPPORT\n+\tif (kni->iova_mode == 1)\n+\t\treturn iova2kva(kni, pa);\n+#endif\n+\treturn pa2kva(pa);\n+}\n+\n+static inline void *\n+get_data_kva(struct kni_dev *kni, void *pkt_kva)\n+{\n+#ifdef HAVE_IOVA_TO_KVA_MAPPING_SUPPORT\n+\tif (kni->iova_mode == 1)\n+\t\treturn iova2data_kva(kni, pkt_kva);\n+#endif\n+\treturn kva2data_kva(pkt_kva);\n+}\n+\n /*\n  * It can be called to process the request.\n  */\n@@ -178,7 +214,7 @@ kni_fifo_trans_pa2va(struct kni_dev *kni,\n \t\t\treturn;\n \n \t\tfor (i = 0; i < num_rx; i++) {\n-\t\t\tkva = pa2kva(kni->pa[i]);\n+\t\t\tkva = get_kva(kni, kni->pa[i]);\n \t\t\tkni->va[i] = pa2va(kni->pa[i], kva);\n \n \t\t\tkva_nb_segs = kva->nb_segs;\n@@ -266,8 +302,8 @@ kni_net_tx(struct sk_buff *skb, struct net_device *dev)\n \tif (likely(ret == 1)) {\n \t\tvoid *data_kva;\n \n-\t\tpkt_kva = pa2kva(pkt_pa);\n-\t\tdata_kva = kva2data_kva(pkt_kva);\n+\t\tpkt_kva = get_kva(kni, pkt_pa);\n+\t\tdata_kva = get_data_kva(kni, pkt_kva);\n \t\tpkt_va = pa2va(pkt_pa, pkt_kva);\n \n \t\tlen = skb->len;\n@@ -338,9 +374,9 @@ kni_net_rx_normal(struct kni_dev *kni)\n \n \t/* Transfer received packets to netif */\n \tfor (i = 0; i < num_rx; i++) {\n-\t\tkva = pa2kva(kni->pa[i]);\n+\t\tkva = get_kva(kni, kni->pa[i]);\n \t\tlen = kva->pkt_len;\n-\t\tdata_kva = kva2data_kva(kva);\n+\t\tdata_kva = get_data_kva(kni, kva);\n \t\tkni->va[i] = pa2va(kni->pa[i], kva);\n \n \t\tskb = netdev_alloc_skb(dev, len);\n@@ -437,9 +473,9 @@ kni_net_rx_lo_fifo(struct kni_dev *kni)\n \t\tnum = ret;\n \t\t/* Copy mbufs */\n \t\tfor (i = 0; i < num; i++) {\n-\t\t\tkva = pa2kva(kni->pa[i]);\n+\t\t\tkva = get_kva(kni, kni->pa[i]);\n \t\t\tlen = kva->data_len;\n-\t\t\tdata_kva = kva2data_kva(kva);\n+\t\t\tdata_kva = get_data_kva(kni, kva);\n \t\t\tkni->va[i] = pa2va(kni->pa[i], kva);\n \n \t\t\twhile (kva->next) {\n@@ -449,8 +485,8 @@ kni_net_rx_lo_fifo(struct kni_dev *kni)\n \t\t\t\tkva = next_kva;\n \t\t\t}\n \n-\t\t\talloc_kva = pa2kva(kni->alloc_pa[i]);\n-\t\t\talloc_data_kva = kva2data_kva(alloc_kva);\n+\t\t\talloc_kva = get_kva(kni, kni->alloc_pa[i]);\n+\t\t\talloc_data_kva = get_data_kva(kni, alloc_kva);\n \t\t\tkni->alloc_va[i] = pa2va(kni->alloc_pa[i], alloc_kva);\n \n \t\t\tmemcpy(alloc_data_kva, data_kva, len);\n@@ -517,9 +553,9 @@ kni_net_rx_lo_fifo_skb(struct kni_dev *kni)\n \n \t/* Copy mbufs to sk buffer and then call tx interface */\n \tfor (i = 0; i < num; i++) {\n-\t\tkva = pa2kva(kni->pa[i]);\n+\t\tkva = get_kva(kni, kni->pa[i]);\n \t\tlen = kva->pkt_len;\n-\t\tdata_kva = kva2data_kva(kva);\n+\t\tdata_kva = get_data_kva(kni, kva);\n \t\tkni->va[i] = pa2va(kni->pa[i], kva);\n \n \t\tskb = netdev_alloc_skb(dev, len);\n@@ -550,8 +586,8 @@ kni_net_rx_lo_fifo_skb(struct kni_dev *kni)\n \t\t\t\t\tbreak;\n \n \t\t\t\tprev_kva = kva;\n-\t\t\t\tkva = pa2kva(kva->next);\n-\t\t\t\tdata_kva = kva2data_kva(kva);\n+\t\t\t\tkva = get_kva(kni, kva->next);\n+\t\t\t\tdata_kva = get_data_kva(kni, kva);\n \t\t\t\t/* Convert physical address to virtual address */\n \t\t\t\tprev_kva->next = pa2va(prev_kva->next, kva);\n \t\t\t}\ndiff --git a/lib/librte_eal/linux/eal/include/rte_kni_common.h b/lib/librte_eal/linux/eal/include/rte_kni_common.h\nindex 46f75a710..2427a965c 100644\n--- a/lib/librte_eal/linux/eal/include/rte_kni_common.h\n+++ b/lib/librte_eal/linux/eal/include/rte_kni_common.h\n@@ -125,6 +125,7 @@ struct rte_kni_device_info {\n \tunsigned int min_mtu;\n \tunsigned int max_mtu;\n \tuint8_t mac_addr[6];\n+\tuint8_t iova_mode;\n };\n \n #define KNI_DEVICE \"kni\"\n",
    "prefixes": [
        "v15",
        "1/2"
    ]
}