Show a patch.

GET /api/patches/42603/
Content-Type: application/json
Vary: Accept

    "id": 42603,
    "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-07-09T06:01:31",
    "name": "[v6,7/7] igb_uio: fix uio release issue when hot unplug",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "2f4b4c03016d47672299d5e4fb6b0823ec84e9f8",
    "submitter": {
        "id": 507,
        "url": "",
        "name": "Jeff Guo",
        "email": ""
    "delegate": null,
    "mbox": "",
    "series": [
            "id": 468,
            "url": "",
            "web_url": "",
            "date": "2018-07-09T06:01:24",
            "name": "hotplug failure handle mechanism",
            "version": 6,
            "mbox": ""
    "comments": "",
    "check": "success",
    "checks": "",
    "tags": {},
    "headers": {
        "X-Mailman-Version": "2.1.15",
        "X-ExtLoop1": "1",
        "Errors-To": "",
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Mailer": "git-send-email 2.7.4",
        "Received": [
            "from [] (localhost [])\n\tby (Postfix) with ESMTP id 74FFC1B3A1;\n\tMon,  9 Jul 2018 08:04:29 +0200 (CEST)",
            "from ( [])\n\tby (Postfix) with ESMTP id 6BAEB1B054\n\tfor <>; Mon,  9 Jul 2018 08:04:26 +0200 (CEST)",
            "from ([])\n\tby with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t08 Jul 2018 23:04:23 -0700",
            "from (HELO localhost.localdomain)\n\t([])\n\tby with ESMTP; 08 Jul 2018 23:04:11 -0700"
        "References": "<>",
        "X-Amp-File-Uploaded": "False",
        "X-BeenThere": "",
        "Message-Id": "<>",
        "X-IronPort-AV": "E=Sophos;i=\"5.51,329,1526367600\"; d=\"scan'208\";a=\"55386293\"",
        "List-Id": "DPDK patches and discussions <>",
        "Precedence": "list",
        "From": "Jeff Guo <>",
        "X-Original-To": "",
        "List-Post": "<>",
        "Return-Path": "<>",
        "Sender": "\"dev\" <>",
        "List-Help": "<>",
        "In-Reply-To": "<>",
        "List-Subscribe": "<>,\n\t<>",
        "To": ",,\n\,,\n\,,,\n\,,,\n\,,\n\,",
        "Delivered-To": "",
        "List-Unsubscribe": "<>,\n\t<>",
        "Date": "Mon,  9 Jul 2018 14:01:31 +0800",
        "Cc": ",,,\n\,",
        "List-Archive": "<>",
        "Subject": "[dpdk-dev] [PATCH v6 7/7] igb_uio: fix uio release issue when hot\n\tunplug"
    "content": "When hotplug out 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\nhotplug 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 hotplug out 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---\nv6->v5:\nno change\n---\n kernel/linux/igb_uio/igb_uio.c | 51 +++++++++++++++++++++++++++++++++++++++---\n 1 file changed, 48 insertions(+), 3 deletions(-)",
    "diff": "diff --git a/kernel/linux/igb_uio/igb_uio.c b/kernel/linux/igb_uio/igb_uio.c\nindex 3398eac..adc8cea 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 int wc_activate;\n@@ -195,12 +205,22 @@ 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+\tmutex_lock(&udev->lock);\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+\tmutex_unlock(&udev->lock);\n+\n \tuio_event_notify(info);\n \n \t/* Message signal mode, no share IRQ and automasked */\n@@ -309,7 +329,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@@ -331,20 +350,29 @@ 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\tmutex_unlock(&udev->lock);\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 \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@@ -356,7 +384,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@@ -562,6 +590,9 @@ 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+\tmutex_lock(&udev->lock);\n+\tudev->state = RTE_UDEV_PROBED;\n+\tmutex_unlock(&udev->lock);\n \treturn 0;\n \n fail_remove_group:\n@@ -579,6 +610,20 @@ static void\n igbuio_pci_remove(struct pci_dev *dev)\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\tmutex_lock(&udev->lock);\n+\t\tudev->state = RTE_UDEV_REMOVED;\n+\t\tmutex_unlock(&udev->lock);\n+\t\treturn;\n+\t}\n \n \tmutex_destroy(&udev->lock);\n \tsysfs_remove_group(&dev->dev.kobj, &dev_attr_grp);\n",
    "prefixes": [