get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 41889,
    "url": "http://patches.dpdk.org/api/patches/41889/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20180628224748.19273-1-dg@adax.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": "<20180628224748.19273-1-dg@adax.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20180628224748.19273-1-dg@adax.com",
    "date": "2018-06-28T22:47:48",
    "name": "[02/10] kni: separate releasing netdev from freeing KNI interface",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "b2ece9e16da42bab9285e393642ccfe65b98c158",
    "submitter": {
        "id": 1040,
        "url": "http://patches.dpdk.org/api/people/1040/?format=api",
        "name": "Dan Gora",
        "email": "dg@adax.com"
    },
    "delegate": null,
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20180628224748.19273-1-dg@adax.com/mbox/",
    "series": [
        {
            "id": 301,
            "url": "http://patches.dpdk.org/api/series/301/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=301",
            "date": "2018-06-28T22:45:13",
            "name": "kni: Interface detach and link status fixes.",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/301/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/41889/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/41889/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 CB3741B027;\n\tFri, 29 Jun 2018 00:47:55 +0200 (CEST)",
            "from mail-ot0-f195.google.com (mail-ot0-f195.google.com\n\t[74.125.82.195]) by dpdk.org (Postfix) with ESMTP id 358608DA6\n\tfor <dev@dpdk.org>; Fri, 29 Jun 2018 00:47:54 +0200 (CEST)",
            "by mail-ot0-f195.google.com with SMTP id w13-v6so7939803ote.11\n\tfor <dev@dpdk.org>; Thu, 28 Jun 2018 15:47:54 -0700 (PDT)",
            "from linux.adax.com (172-11-198-60.lightspeed.sntcca.sbcglobal.net.\n\t[172.11.198.60]) by smtp.gmail.com with ESMTPSA id\n\tk47-v6sm7611259otb.50.2018.06.28.15.47.52\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128);\n\tThu, 28 Jun 2018 15:47:52 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;\n\th=sender:from:to:cc:subject:date:message-id;\n\tbh=ytOC7mp7wKfFaY5qMuyGH7qZSDHYGCEQGPP3dfwcCDQ=;\n\tb=EHN6+KORqM264oGHLZ2Vg+8MiIpOnfbO49KvqVJXp/fFw8yGQzDQqjpgIZ/ME8nHdU\n\tI86SR/gZ2xINcyB76hJlNqjCP94NdswAcgoOgrWH2k7to+WqbalD09i5MMtKukMqK+2K\n\txzgbe4pth2VjpLO5rJIKbfSAdODesf9s+MM7uGBA3E8DlLSgz4k3RZdKU2fwGRQMNWXz\n\tklKujDZ3UMc6PmclyLilZy3WxYvQEKSMHdPyFKxrEqI6gsTOtQ929O+hEj8Ttp+1QLcQ\n\tNZUgfuVkVn/VAGBPq+Ikynt76LC7lHhD4dpOdhlMS6gdP6+wi86SigVLY/dU2xuLyCit\n\tBTdQ==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:sender:from:to:cc:subject:date:message-id;\n\tbh=ytOC7mp7wKfFaY5qMuyGH7qZSDHYGCEQGPP3dfwcCDQ=;\n\tb=RhlWo+rpoeg2jcBDC+z/ckXk8EUEcuHpUhx5W6MyQgSWtW0J9qBCt3q1wRqwX29lhr\n\terGjdZ38uDQRc/TDy4hbG3ZBKlYTfW/lvlreI9Jwgm9qDSyTDkPX8luqqxsbEOEVpPVf\n\twmxqOt0tstaNG0cF7VKE3MMwifO5yw3Xd/HUB1ye7YuVgifOEtm1BH47XjC37WN3lXGq\n\t/hbj9ZPPpbY15RqfAY0PjKqBeC3GC/9u37odP9+tvj7CpjPqp8EvMpRlOyx1mSjNDxFG\n\tX5M3fEE+XyjMCc/ET9+9Z7Q0Na7S9zD8aFXKuN+9Skd3v1OB2SU/km8OW5pfZjB3oHyV\n\t8vpg==",
        "X-Gm-Message-State": "APt69E0L8xwSXZTPBM+TYv0vZK31RO7RnT9aU9S1tYQvlrw6ylKn+X2B\n\tX1RA7i5kggkFqrCC3FQrc9elOA==",
        "X-Google-Smtp-Source": "AAOMgpfzDurB8hcXO2E7rFfcH2lcOz/UQ2l5EF7r3heoxc9gO4/sYAeojuIEcL33NPAMItvcxdiMGw==",
        "X-Received": "by 2002:a9d:706:: with SMTP id\n\t6-v6mr3639266ote.268.1530226073337; \n\tThu, 28 Jun 2018 15:47:53 -0700 (PDT)",
        "From": "Dan Gora <dg@adax.com>",
        "To": "Ferruh Yigit <ferruh.yigit@intel.com>",
        "Cc": "dev@dpdk.org,\n\tDan Gora <dg@adax.com>",
        "Date": "Thu, 28 Jun 2018 15:47:48 -0700",
        "Message-Id": "<20180628224748.19273-1-dg@adax.com>",
        "X-Mailer": "git-send-email 2.18.0.rc1.1.g6f333ff2f",
        "Subject": "[dpdk-dev] [PATCH 02/10] kni: separate releasing netdev from\n\tfreeing KNI interface",
        "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": "Currently the rte_kni kernel driver suffers from a problem where\nwhen the interface is released, it generates a callback to the DPDK\napplication to change the interface state to Down.  However, after the\nDPDK application handles the callback and generates a response back to\nthe kernel, the rte_kni driver cannot wake the thread which is asleep\nwaiting for the response, because it is holding the kni_link_lock\nsemaphore and it has already removed the 'struct kni_dev' from the\nlist of interfaces to poll for responses.\n\nThis means that if the KNI interface is in the Up state when\nrte_kni_release() is called, it will always sleep for three seconds\nuntil kni_net_release gives up waiting for a response from the DPDK\napplication.\n\nTo fix this, we must separate the step to release the kernel network\ninterface from the steps to remove the KNI interface from the list\nof interfaces to poll.\n\nWhen the kernel network interface is removed with unregister_netdev(),\nif the interface is up, it will generate a callback to mark the\ninterface down, which calls kni_net_release().  kni_net_release() will\nblock waiting for the DPDK application to call rte_kni_handle_request()\nto handle the callback, but it also needs the thread in the KNI driver\n(either the per-dev thread for multi-thread or the per-driver thread)\nto call kni_net_poll_resp() in order to wake the thread sleeping in\nkni_net_release (actually kni_net_process_request()).\n\nSo now, KNI interfaces should be removed as such:\n\n1) The user calls rte_kni_release().  This only unregisters the\nnetdev in the kernel, but touches nothing else.  This allows all the\nthreads to run which are necessary to handle the callback into the\nDPDK application to mark the interface down.\n\n2) The user stops the thread running rte_kni_handle_request().\nAfter rte_kni_release() has been called, there will be no more\ncallbacks for that interface so it is not necessary.  It cannot be\nrunning at the same time that rte_kni_free() frees all of the FIFOs\nand DPDK memory for that KNI interface.\n\n3) The user calls rte_kni_free().  This performs the RTE_KNI_IOCTL_FREE\nioctl which calls kni_ioctl_free().  This function removes the struct\nkni_dev from the list of interfaces to poll (and kills the per-dev\nkthread, if configured for multi-thread), then frees the memory in\nthe FIFOs.\n\nSigned-off-by: Dan Gora <dg@adax.com>\n---\n kernel/linux/kni/kni_misc.c                   | 69 +++++++++++++++----\n .../eal/include/exec-env/rte_kni_common.h     |  1 +\n 2 files changed, 58 insertions(+), 12 deletions(-)",
    "diff": "diff --git a/kernel/linux/kni/kni_misc.c b/kernel/linux/kni/kni_misc.c\nindex fa69f8e63..d889ffc4b 100644\n--- a/kernel/linux/kni/kni_misc.c\n+++ b/kernel/linux/kni/kni_misc.c\n@@ -192,8 +192,6 @@ kni_dev_remove(struct kni_dev *dev)\n \t\tfree_netdev(dev->net_dev);\n \t}\n \n-\tkni_net_release_fifo_phy(dev);\n-\n \treturn 0;\n }\n \n@@ -224,6 +222,7 @@ kni_release(struct inode *inode, struct file *file)\n \t\t}\n \n \t\tkni_dev_remove(dev);\n+\t\tkni_net_release_fifo_phy(dev);\n \t\tlist_del(&dev->list);\n \t}\n \tup_write(&knet->kni_list_lock);\n@@ -263,7 +262,6 @@ kni_run_thread(struct kni_net *knet, struct kni_dev *kni, uint8_t force_bind)\n \t\tkni->pthread = kthread_create(kni_thread_multiple,\n \t\t\t(void *)kni, \"kni_%s\", kni->name);\n \t\tif (IS_ERR(kni->pthread)) {\n-\t\t\tkni_dev_remove(kni);\n \t\t\treturn -ECANCELED;\n \t\t}\n \n@@ -278,7 +276,6 @@ kni_run_thread(struct kni_net *knet, struct kni_dev *kni, uint8_t force_bind)\n \t\t\t\t(void *)knet, \"kni_single\");\n \t\t\tif (IS_ERR(knet->kni_kthread)) {\n \t\t\t\tmutex_unlock(&knet->kni_kthread_lock);\n-\t\t\t\tkni_dev_remove(kni);\n \t\t\t\treturn -ECANCELED;\n \t\t\t}\n \n@@ -460,15 +457,17 @@ kni_ioctl_create(struct net *net, uint32_t ioctl_num,\n \tif (ret) {\n \t\tpr_err(\"error %i registering device \\\"%s\\\"\\n\",\n \t\t\t\t\tret, dev_info.name);\n-\t\tkni->net_dev = NULL;\n-\t\tkni_dev_remove(kni);\n+\t\tkni_net_release_fifo_phy(kni);\n \t\tfree_netdev(net_dev);\n \t\treturn -ENODEV;\n \t}\n \n \tret = kni_run_thread(knet, kni, dev_info.force_bind);\n-\tif (ret != 0)\n+\tif (ret != 0) {\n+\t\tkni_dev_remove(kni);\n+\t\tkni_net_release_fifo_phy(kni);\n \t\treturn ret;\n+\t}\n \n \tdown_write(&knet->kni_list_lock);\n \tlist_add(&kni->list, &knet->kni_list_head);\n@@ -495,6 +494,46 @@ kni_ioctl_release(struct net *net, uint32_t ioctl_num,\n \t\treturn -EIO;\n \t}\n \n+\t/* Release the network device according to its name */\n+\tif (strlen(dev_info.name) == 0)\n+\t\treturn ret;\n+\n+\tdown_read(&knet->kni_list_lock);\n+\tlist_for_each_entry_safe(dev, n, &knet->kni_list_head, list) {\n+\t\tif (strncmp(dev->name, dev_info.name, RTE_KNI_NAMESIZE) != 0)\n+\t\t\tcontinue;\n+\n+\t\tkni_dev_remove(dev);\n+\t\tup_read(&knet->kni_list_lock);\n+\t\tpr_info(\"Successfully released kni interface: %s\\n\",\n+\t\t\tdev_info.name);\n+\t\treturn 0;\n+\t}\n+\tup_read(&knet->kni_list_lock);\n+\tpr_info(\"Error: failed to find kni interface: %s\\n\",\n+\t\tdev_info.name);\n+\n+\treturn ret;\n+}\n+\n+static int\n+kni_ioctl_free(struct net *net, uint32_t ioctl_num,\n+\t\tunsigned long ioctl_param)\n+{\n+\tstruct kni_net *knet = net_generic(net, kni_net_id);\n+\tint ret = -EINVAL;\n+\tstruct kni_dev *dev, *n;\n+\tstruct rte_kni_device_info dev_info;\n+\n+\tif (_IOC_SIZE(ioctl_num) > sizeof(dev_info))\n+\t\treturn -EINVAL;\n+\n+\tret = copy_from_user(&dev_info, (void *)ioctl_param, sizeof(dev_info));\n+\tif (ret) {\n+\t\tpr_err(\"copy_from_user in kni_ioctl_release\");\n+\t\treturn -EIO;\n+\t}\n+\n \t/* Release the network device according to its name */\n \tif (strlen(dev_info.name) == 0)\n \t\treturn ret;\n@@ -509,14 +548,17 @@ kni_ioctl_release(struct net *net, uint32_t ioctl_num,\n \t\t\tdev->pthread = NULL;\n \t\t}\n \n-\t\tkni_dev_remove(dev);\n+\t\tkni_net_release_fifo_phy(dev);\n \t\tlist_del(&dev->list);\n-\t\tret = 0;\n-\t\tbreak;\n+\t\tup_write(&knet->kni_list_lock);\n+\t\tpr_info(\"Successfully freed kni interface: %s\\n\",\n+\t\t\tdev_info.name);\n+\t\treturn 0;\n \t}\n \tup_write(&knet->kni_list_lock);\n-\tpr_info(\"%s release kni named %s\\n\",\n-\t\t(ret == 0 ? \"Successfully\" : \"Unsuccessfully\"), dev_info.name);\n+\n+\tpr_info(\"Error: failed to find kni interface: %s\\n\",\n+\t\tdev_info.name);\n \n \treturn ret;\n }\n@@ -542,6 +584,9 @@ kni_ioctl(struct inode *inode, uint32_t ioctl_num, unsigned long ioctl_param)\n \tcase _IOC_NR(RTE_KNI_IOCTL_RELEASE):\n \t\tret = kni_ioctl_release(net, ioctl_num, ioctl_param);\n \t\tbreak;\n+\tcase _IOC_NR(RTE_KNI_IOCTL_FREE):\n+\t\tret = kni_ioctl_free(net, ioctl_num, ioctl_param);\n+\t\tbreak;\n \tdefault:\n \t\tpr_debug(\"IOCTL default\\n\");\n \t\tbreak;\ndiff --git a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h\nindex cfa9448bd..318a3f939 100644\n--- a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h\n+++ b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h\n@@ -129,5 +129,6 @@ struct rte_kni_device_info {\n #define RTE_KNI_IOCTL_TEST    _IOWR(0, 1, int)\n #define RTE_KNI_IOCTL_CREATE  _IOWR(0, 2, struct rte_kni_device_info)\n #define RTE_KNI_IOCTL_RELEASE _IOWR(0, 3, struct rte_kni_device_info)\n+#define RTE_KNI_IOCTL_FREE    _IOWR(0, 4, struct rte_kni_device_info)\n \n #endif /* _RTE_KNI_COMMON_H_ */\n",
    "prefixes": [
        "02/10"
    ]
}