Show a patch.

GET /api/patches/41945/?format=api
Content-Type: application/json
Vary: Accept

    "id": 41945,
    "url": "",
    "web_url": "",
    "project": {
        "id": 1,
        "url": "",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "",
        "list_email": "",
        "web_url": "",
        "scm_url": "git://",
        "webscm_url": ""
    "msgid": "<>",
    "date": "2018-06-29T10:24:29",
    "name": "[V4,7/9] igb_uio: fix uio release issue when hot unplug",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "da52176a74a980828afad0260a14c0a5755d2db3",
    "submitter": {
        "id": 507,
        "url": "",
        "name": "Guo, Jia",
        "email": ""
    "delegate": null,
    "mbox": "",
    "series": [
            "id": 314,
            "url": "",
            "web_url": "",
            "date": "2018-06-29T10:24:22",
            "name": "hot plug failure handle mechanism",
            "version": 4,
            "mbox": ""
    "comments": "",
    "check": "success",
    "checks": "",
    "tags": {},
    "headers": {
        "X-Mailer": "git-send-email 2.7.4",
        "List-Id": "DPDK patches and discussions <>",
        "Precedence": "list",
        "List-Help": "<>",
        "Date": "Fri, 29 Jun 2018 18:24:29 +0800",
        "X-Mailman-Version": "2.1.15",
        "Delivered-To": "",
        "List-Unsubscribe": "<>,\n\t<>",
        "List-Subscribe": "<>,\n\t<>",
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "Cc": ",,,\n\,",
        "To": ",,\n\,,\n\,,,\n\,,,\n\,,",
        "Errors-To": "",
        "References": "<>",
        "Sender": "\"dev\" <>",
        "From": "Jeff Guo <>",
        "Return-Path": "<>",
        "X-IronPort-AV": "E=Sophos;i=\"5.51,285,1526367600\"; d=\"scan'208\";a=\"241324456\"",
        "List-Post": "<>",
        "Received": [
            "from [] (localhost [])\n\tby (Postfix) with ESMTP id 7267E1B554;\n\tFri, 29 Jun 2018 12:27:15 +0200 (CEST)",
            "from ( [])\n\tby (Postfix) with ESMTP id C21D31B539\n\tfor <>; Fri, 29 Jun 2018 12:27:12 +0200 (CEST)",
            "from ([])\n\tby with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t29 Jun 2018 03:27:12 -0700",
            "from (HELO localhost.localdomain)\n\t([])\n\tby with ESMTP; 29 Jun 2018 03:27:09 -0700"
        "List-Archive": "<>",
        "X-Amp-File-Uploaded": "False",
        "Subject": "[dpdk-dev] [PATCH V4 7/9] igb_uio: fix uio release issue when hot\n\tunplug",
        "In-Reply-To": "<>",
        "Message-Id": "<>",
        "X-ExtLoop1": "1",
        "X-BeenThere": "",
        "X-Original-To": ""
    "content": "When hot unplug device, the kernel will release the device resource in the\nkernel side, such as the fd sys file will disappear, and the irq will be\nreleased. At this time, if igb uio driver still try to release this\nresource, it will cause kernel crash. On the other hand, something like\ninterrupt disabling do not automatically process in kernel side. If not\nhandler it, this redundancy and dirty thing will affect the interrupt\nresource be used by other device. So the igb_uio driver have to check the\nhot plug status, and the corresponding process should be taken in igb uio\ndriver.\n\nThis patch propose to add structure of rte_udev_state into rte_uio_pci_dev\nof igb_uio kernel driver, which will record the state of uio device, such\nas probed/opened/released/removed/unplug. When detect the unexpected\nremoval which cause of hot unplug behavior, it will corresponding disable\ninterrupt resource, while for the part of releasement which kernel have\nalready handle, just skip it to avoid double free or null pointer kernel\ncrash issue.\n\nSigned-off-by: Jeff Guo <>\n---\nv4->v3:\nno change\n---\n kernel/linux/igb_uio/igb_uio.c | 50 +++++++++++++++++++++++++++++++++++++-----\n 1 file changed, 45 insertions(+), 5 deletions(-)",
    "diff": "diff --git a/kernel/linux/igb_uio/igb_uio.c b/kernel/linux/igb_uio/igb_uio.c\nindex b3233f1..d301302 100644\n--- a/kernel/linux/igb_uio/igb_uio.c\n+++ b/kernel/linux/igb_uio/igb_uio.c\n@@ -19,6 +19,15 @@\n \n #include \"compat.h\"\n \n+/* uio pci device state */\n+enum rte_udev_state {\n+\tRTE_UDEV_PROBED,\n+\tRTE_UDEV_OPENNED,\n+\tRTE_UDEV_RELEASED,\n+\tRTE_UDEV_REMOVED,\n+\tRTE_UDEV_UNPLUG\n+};\n+\n /**\n  * A structure describing the private information for a uio device.\n  */\n@@ -28,6 +37,7 @@ struct rte_uio_pci_dev {\n \tenum rte_intr_mode mode;\n \tstruct mutex lock;\n \tint refcnt;\n+\tenum rte_udev_state state;\n };\n \n static char *intr_mode;\n@@ -194,12 +204,20 @@ igbuio_pci_irqhandler(int irq, void *dev_id)\n {\n \tstruct rte_uio_pci_dev *udev = (struct rte_uio_pci_dev *)dev_id;\n \tstruct uio_info *info = &udev->info;\n+\tstruct pci_dev *pdev = udev->pdev;\n \n \t/* Legacy mode need to mask in hardware */\n \tif (udev->mode == RTE_INTR_MODE_LEGACY &&\n \t    !pci_check_and_mask_intx(udev->pdev))\n \t\treturn IRQ_NONE;\n \n+\t/* check the uevent of the kobj */\n+\tif ((&pdev->dev.kobj)->state_remove_uevent_sent == 1) {\n+\t\tdev_notice(&pdev->dev, \"device:%s, sent remove uevent!\\n\",\n+\t\t\t   (&pdev->dev.kobj)->name);\n+\t\tudev->state = RTE_UDEV_UNPLUG;\n+\t}\n+\n \tuio_event_notify(info);\n \n \t/* Message signal mode, no share IRQ and automasked */\n@@ -308,7 +326,6 @@ igbuio_pci_disable_interrupts(struct rte_uio_pci_dev *udev)\n #endif\n }\n \n-\n /**\n  * This gets called while opening uio device file.\n  */\n@@ -330,24 +347,33 @@ igbuio_pci_open(struct uio_info *info, struct inode *inode)\n \n \t/* enable interrupts */\n \terr = igbuio_pci_enable_interrupts(udev);\n-\tmutex_unlock(&udev->lock);\n \tif (err) {\n \t\tdev_err(&dev->dev, \"Enable interrupt fails\\n\");\n+\t\tpci_clear_master(dev);\n \t\treturn err;\n \t}\n+\tudev->state = RTE_UDEV_OPENNED;\n+\tmutex_unlock(&udev->lock);\n \treturn 0;\n }\n \n+/**\n+ * This gets called while closing uio device file.\n+ */\n static int\n igbuio_pci_release(struct uio_info *info, struct inode *inode)\n {\n+\n \tstruct rte_uio_pci_dev *udev = info->priv;\n \tstruct pci_dev *dev = udev->pdev;\n \n+\tif (udev->state == RTE_UDEV_REMOVED)\n+\t\treturn 0;\n+\n \tmutex_lock(&udev->lock);\n \tif (--udev->refcnt > 0) {\n \t\tmutex_unlock(&udev->lock);\n-\t\treturn 0;\n+\t\treturn -1;\n \t}\n \n \t/* disable interrupts */\n@@ -355,7 +381,7 @@ igbuio_pci_release(struct uio_info *info, struct inode *inode)\n \n \t/* stop the device from further DMA */\n \tpci_clear_master(dev);\n-\n+\tudev->state = RTE_UDEV_RELEASED;\n \tmutex_unlock(&udev->lock);\n \treturn 0;\n }\n@@ -557,6 +583,7 @@ igbuio_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)\n \t\t\t (unsigned long long)map_dma_addr, map_addr);\n \t}\n \n+\tudev->state = RTE_UDEV_PROBED;\n \treturn 0;\n \n fail_remove_group:\n@@ -573,11 +600,24 @@ igbuio_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)\n static void\n igbuio_pci_remove(struct pci_dev *dev)\n {\n+\n \tstruct rte_uio_pci_dev *udev = pci_get_drvdata(dev);\n+\tint ret;\n+\n+\t/* handler hot unplug */\n+\tif (udev->state == RTE_UDEV_OPENNED ||\n+\t\tudev->state == RTE_UDEV_UNPLUG) {\n+\t\tdev_notice(&dev->dev, \"Unexpected removal!\\n\");\n+\t\tret = igbuio_pci_release(&udev->info, NULL);\n+\t\tif (ret)\n+\t\t\treturn;\n+\t\tudev->state = RTE_UDEV_REMOVED;\n+\t\treturn;\n+\t}\n \n \tmutex_destroy(&udev->lock);\n-\tsysfs_remove_group(&dev->dev.kobj, &dev_attr_grp);\n \tuio_unregister_device(&udev->info);\n+\tsysfs_remove_group(&dev->dev.kobj, &dev_attr_grp);\n \tigbuio_pci_release_iomem(&udev->info);\n \tpci_disable_device(dev);\n \tpci_set_drvdata(dev, NULL);\n",
    "prefixes": [