Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.1/patches/2227734/?format=api
{ "id": 2227734, "url": "http://patchwork.ozlabs.org/api/1.1/patches/2227734/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-pci/patch/1777017460-243543-6-git-send-email-shawn.lin@rock-chips.com/", "project": { "id": 28, "url": "http://patchwork.ozlabs.org/api/1.1/projects/28/?format=api", "name": "Linux PCI development", "link_name": "linux-pci", "list_id": "linux-pci.vger.kernel.org", "list_email": "linux-pci@vger.kernel.org", "web_url": null, "scm_url": null, "webscm_url": null }, "msgid": "<1777017460-243543-6-git-send-email-shawn.lin@rock-chips.com>", "date": "2026-04-24T07:57:38", "name": "[v4,5/7] PCI/MSI: Add Devres managed IRQ vectors allocation", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "ceb3d641294d3bc4c3aba45180b1682974c2ad4f", "submitter": { "id": 66993, "url": "http://patchwork.ozlabs.org/api/1.1/people/66993/?format=api", "name": "Shawn Lin", "email": "shawn.lin@rock-chips.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/linux-pci/patch/1777017460-243543-6-git-send-email-shawn.lin@rock-chips.com/mbox/", "series": [ { "id": 501313, "url": "http://patchwork.ozlabs.org/api/1.1/series/501313/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-pci/list/?series=501313", "date": "2026-04-24T07:57:33", "name": "Add Devres managed IRQ vectors allocation", "version": 4, "mbox": "http://patchwork.ozlabs.org/series/501313/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2227734/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2227734/checks/", "tags": {}, "headers": { "Return-Path": "\n <linux-pci+bounces-53117-incoming=patchwork.ozlabs.org@vger.kernel.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "linux-pci@vger.kernel.org" ], "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=rock-chips.com header.i=@rock-chips.com\n header.a=rsa-sha256 header.s=default header.b=bY8IXweD;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c0a:e001:db::12fc:5321; helo=sea.lore.kernel.org;\n envelope-from=linux-pci+bounces-53117-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)", "smtp.subspace.kernel.org;\n\tdkim=pass (1024-bit key) header.d=rock-chips.com header.i=@rock-chips.com\n header.b=\"bY8IXweD\"", "smtp.subspace.kernel.org;\n arc=none smtp.client-ip=220.197.32.86", "smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=rock-chips.com", "smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=rock-chips.com" ], "Received": [ "from sea.lore.kernel.org (sea.lore.kernel.org\n [IPv6:2600:3c0a:e001:db::12fc:5321])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g253j5m07z1yDD\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 24 Apr 2026 18:00:17 +1000 (AEST)", "from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sea.lore.kernel.org (Postfix) with ESMTP id 5530430097FA\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 24 Apr 2026 07:59:39 +0000 (UTC)", "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id E1CAB285068;\n\tFri, 24 Apr 2026 07:59:37 +0000 (UTC)", "from mail-m3286.qiye.163.com (mail-m3286.qiye.163.com\n [220.197.32.86])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id A226536C9F4\n\tfor <linux-pci@vger.kernel.org>; Fri, 24 Apr 2026 07:59:33 +0000 (UTC)", "from localhost.localdomain (unknown [61.154.14.86])\n\tby smtp.qiye.163.com (Hmail) with ESMTP id 3c02053a3;\n\tFri, 24 Apr 2026 15:59:13 +0800 (GMT+08:00)" ], "ARC-Seal": "i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1777017577; cv=none;\n b=jItA+l8uFGbHktvbb7bWo5Kc42CjICe32hw6aPM4+8hoCj1yP9vev9TuGE3RN1U107zhqxQ3wm/6g8vznmGXG5E/hLkxnKYmRWeBh0svwjj4yYICAcSdFlEaARn20Sw1jO3bAHIvSKEAixEmyCEfq0ZFXalBpP+SgWRdboNCueM=", "ARC-Message-Signature": "i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1777017577; c=relaxed/simple;\n\tbh=vK2gtdOOrsNZTYX+kl0HnKmgj3th1i3V+R9vgOBBAwk=;\n\th=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References;\n b=OajTKuQlt4mE8GfwZHTsNxkkrytl65dSQgxUJgXNQBx4j9fMfQplp6pCuKXciai2s7+pOzD6giYQ6uE7cLjfw0EVnaYzpysoCADhoOZFeqkSl6bG3a8cDRyf4usQnJOkIdSW2PMN6gx0w8QHF0ORZo7xAdvG2JUd3n6P1oYx9Bs=", "ARC-Authentication-Results": "i=1; smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=rock-chips.com;\n spf=pass smtp.mailfrom=rock-chips.com;\n dkim=pass (1024-bit key) header.d=rock-chips.com header.i=@rock-chips.com\n header.b=bY8IXweD; arc=none smtp.client-ip=220.197.32.86", "From": "Shawn Lin <shawn.lin@rock-chips.com>", "To": "Bjorn Helgaas <bhelgaas@google.com>", "Cc": "Nirmal Patel <nirmal.patel@linux.intel.com>,\n\tJonathan Derrick <jonathan.derrick@linux.dev>,\n\tKurt Schwemmer <kurt.schwemmer@microsemi.com>,\n\tLogan Gunthorpe <logang@deltatee.com>,\n\tPhilipp Stanner <phasta@kernel.org>,\n\tlinux-pci@vger.kernel.org,\n\tShawn Lin <shawn.lin@rock-chips.com>", "Subject": "[PATCH v4 5/7] PCI/MSI: Add Devres managed IRQ vectors allocation", "Date": "Fri, 24 Apr 2026 15:57:38 +0800", "Message-Id": "<1777017460-243543-6-git-send-email-shawn.lin@rock-chips.com>", "X-Mailer": "git-send-email 2.7.4", "In-Reply-To": "<1777017460-243543-1-git-send-email-shawn.lin@rock-chips.com>", "References": "<1777017460-243543-1-git-send-email-shawn.lin@rock-chips.com>", "X-HM-Tid": "0a9dbe80040f09cckunm66d640875ec20", "X-HM-MType": "1", "X-HM-Spam-Status": "e1kfGhgUHx5ZQUpXWQgPGg8OCBgUHx5ZQUlOS1dZFg8aDwILHllBWSg2Ly\n\ttZV1koWUFITzdXWRgWCB1ZQUpXWS1ZQUlXWQ8JGhUIEh9ZQVkZGU8YVk1CTU5PGR9CGksdS1YVFA\n\tkWGhdVEwETFhoSFyQUDg9ZV1kYEgtZQVlNSlVKTk9VSk9VQ01ZV1kWGg8SFR0UWUFZT0tIVUpLSU\n\t9PT0hVSktLVUpCS0tZBg++", "DKIM-Signature": "a=rsa-sha256;\n\tb=bY8IXweDRW8Oxe2OSVX+VEBUeffGJcYcHtpvGJdZ81lYo8wym/JYU9sFsdwLqlqpFfMXbaRW6BQabhxdJa+plfpNb0/3CDXM8zQPwlzA35vi2pIbFfaLMp9iCFDwHR0zx8g4VLksQZz3TepCuXKB2nRDdlsIfw6TfgAkANxPPz0=;\n c=relaxed/relaxed; s=default; d=rock-chips.com; v=1;\n\tbh=U7phM1w+8/dSJ0SfACj/OhUZrbuShDU5P7KWiVgxgiA=;\n\th=date:mime-version:subject:message-id:from;", "Precedence": "bulk", "X-Mailing-List": "linux-pci@vger.kernel.org", "List-Id": "<linux-pci.vger.kernel.org>", "List-Subscribe": "<mailto:linux-pci+subscribe@vger.kernel.org>", "List-Unsubscribe": "<mailto:linux-pci+unsubscribe@vger.kernel.org>" }, "content": "There is a long-standing design ambiguity in the PCI/MSI subsystem\nregarding the management of IRQ vectors. Currently, the management\noperates in a \"hybrid\" mode. Sometimes it's handled by devres but\nsometimes not, creating potential for resource management bugs.\n\nHistorically, pcim_enable_device() implicitly triggers automatic IRQ\nvector management when calling pci_alloc_irq_vectors[_affinity], as\npcim_enable_device() sets the is_managed flag, thus pcim_msi_release()\nwill register a cleanup action. However, using pci_enable_device()\nwill not make pci_alloc_irq_vectors[_affinity] register a cleanup\naction.\n\nThis ambiguity causes problems when drivers follow a common but\nhazardous pattern:\n1. Using pcim_enable_device() (which implicitly marks IRQs as managed)\n2. Explicitly calling pci_alloc_irq_vectors() for IRQ allocation\n3. Also calling pci_free_irq_vectors() in error paths or remove routines\n\nIn this scenario, the devres framework may attempt to free the IRQ\nvectors a second time upon device release, leading to double-free\nissues. Analysis of the tree shows this hazardous pattern exists\nin multiple drivers, while 37 other drivers correctly rely solely\non the implicit cleanup.\n\nTo resolve this ambiguity, introduce explicit managed APIs for IRQ\nvector allocation:\n- pcim_alloc_irq_vectors()\n- pcim_alloc_irq_vectors_affinity()\n\nThese functions are the devres-managed counterparts to\npci_alloc_irq_vectors[_affinity](). Drivers that wish to have\ndevres-managed IRQ vectors should use these new APIs instead.\n\nThe long-term goal is to convert all drivers which use pcim_enable_device()\nin combination with pci_alloc_irq_vectors[_affinity]() to use these managed\nfunctions, and eventually remove the problematic hybrid management\npattern from pcim_enable_device() and pcim_setup_msi_release() entirely.\nThis patch lays the foundation by introducing the APIs.\n\nSuggested-by: Philipp Stanner <phasta@kernel.org>\nSigned-off-by: Shawn Lin <shawn.lin@rock-chips.com>\n\n---\n\nChanges in v4:\n- Rework to create dedicated devres-managed function (Philipp)\n\nChanges in v3:\n- Rework the commit message and function doc (Philipp)\n- Remove setting is_msi_managed flag from new APIs (Philipp)\n\nChanges in v2:\n- Rebase\n- Introduce patches only for PCI subsystem to convert the API\n\n drivers/pci/msi/api.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++\n include/linux/pci.h | 22 ++++++++++++++\n 2 files changed, 106 insertions(+)", "diff": "diff --git a/drivers/pci/msi/api.c b/drivers/pci/msi/api.c\nindex c18559b..405da7b 100644\n--- a/drivers/pci/msi/api.c\n+++ b/drivers/pci/msi/api.c\n@@ -297,6 +297,90 @@ int pci_alloc_irq_vectors_affinity(struct pci_dev *dev, unsigned int min_vecs,\n EXPORT_SYMBOL(pci_alloc_irq_vectors_affinity);\n \n /**\n+ * pcim_alloc_irq_vectors - devres managed pci_alloc_irq_vectors()\n+ * @dev: the PCI device to operate on\n+ * @min_vecs: minimum number of vectors required (must be >= 1)\n+ * @max_vecs: maximum (desired) number of vectors\n+ * @flags: flags for this allocation, see pci_alloc_irq_vectors()\n+ *\n+ * This is a device resource managed version of pci_alloc_irq_vectors().\n+ * Interrupt vectors are automatically freed on driver detach by devres.\n+ * Drivers MUST NOT call pci_free_irq_vectors().\n+ *\n+ * Returns number of vectors allocated (which might be smaller than\n+ * @max_vecs) on success, or a negative error code on failure.\n+ */\n+int pcim_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs,\n+\t\t\t unsigned int max_vecs, unsigned int flags)\n+{\n+\treturn pcim_alloc_irq_vectors_affinity(dev, min_vecs, max_vecs,\n+\t\t\t\t\t flags, NULL);\n+}\n+EXPORT_SYMBOL(pcim_alloc_irq_vectors);\n+\n+/**\n+ * pcim_alloc_irq_vectors_affinity - devres managed pci_alloc_irq_vectors_affinity()\n+ * @dev: the PCI device to operate on\n+ * @min_vecs: minimum number of vectors required (must be >= 1)\n+ * @max_vecs: maximum (desired) number of vectors\n+ * @flags: flags for this allocation, see pci_alloc_irq_vectors()\n+ * @affd: optional description of the affinity requirements\n+ *\n+ * This is a device resource managed version of pci_alloc_irq_vectors_affinity().\n+ * Interrupt vectors are automatically freed on driver detach by devres.\n+ * Drivers MUST NOT call pci_free_irq_vectors().\n+ *\n+ * Returns number of vectors allocated (which might be smaller than\n+ * @max_vecs) on success, or a negative error code on failure.\n+ */\n+int pcim_alloc_irq_vectors_affinity(struct pci_dev *dev, unsigned int min_vecs,\n+\t\t\t\t unsigned int max_vecs, unsigned int flags,\n+\t\t\t\t struct irq_affinity *affd)\n+{\n+\tstruct irq_affinity msi_default_affd = {0};\n+\tint nvecs = -ENOSPC;\n+\n+\tif (flags & PCI_IRQ_AFFINITY) {\n+\t\tif (!affd)\n+\t\t\taffd = &msi_default_affd;\n+\t} else {\n+\t\tif (WARN_ON(affd))\n+\t\t\taffd = NULL;\n+\t}\n+\n+\tif (flags & PCI_IRQ_MSIX) {\n+\t\tnvecs = __pcim_enable_msix_range(dev, NULL, min_vecs, max_vecs,\n+\t\t\t\t\t\t affd, flags);\n+\t\tif (nvecs > 0)\n+\t\t\treturn nvecs;\n+\t}\n+\n+\tif (flags & PCI_IRQ_MSI) {\n+\t\tnvecs = __pcim_enable_msi_range(dev, min_vecs, max_vecs, affd);\n+\t\tif (nvecs > 0)\n+\t\t\treturn nvecs;\n+\t}\n+\n+\t/* use INTx IRQ if allowed */\n+\tif (flags & PCI_IRQ_INTX) {\n+\t\tif (min_vecs == 1 && dev->irq) {\n+\t\t\t/*\n+\t\t\t * Invoke the affinity spreading logic to ensure that\n+\t\t\t * the device driver can adjust queue configuration\n+\t\t\t * for the single interrupt case.\n+\t\t\t */\n+\t\t\tif (affd)\n+\t\t\t\tkfree(irq_create_affinity_masks(1, affd));\n+\t\t\tpci_intx(dev, 1);\n+\t\t\treturn 1;\n+\t\t}\n+\t}\n+\n+\treturn nvecs;\n+}\n+EXPORT_SYMBOL(pcim_alloc_irq_vectors_affinity);\n+\n+/**\n * pci_irq_vector() - Get Linux IRQ number of a device interrupt vector\n * @dev: the PCI device to operate on\n * @nr: device-relative interrupt vector index (0-based); has different\ndiff --git a/include/linux/pci.h b/include/linux/pci.h\nindex 2c44545..6eab553 100644\n--- a/include/linux/pci.h\n+++ b/include/linux/pci.h\n@@ -1770,6 +1770,12 @@ int pci_alloc_irq_vectors_affinity(struct pci_dev *dev, unsigned int min_vecs,\n \t\t\t\t unsigned int max_vecs, unsigned int flags,\n \t\t\t\t struct irq_affinity *affd);\n \n+int pcim_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs,\n+\t\t\t unsigned int max_vecs, unsigned int flags);\n+int pcim_alloc_irq_vectors_affinity(struct pci_dev *dev, unsigned int min_vecs,\n+\t\t\t\t unsigned int max_vecs, unsigned int flags,\n+\t\t\t\t struct irq_affinity *affd);\n+\n bool pci_msix_can_alloc_dyn(struct pci_dev *dev);\n struct msi_map pci_msix_alloc_irq_at(struct pci_dev *dev, unsigned int index,\n \t\t\t\t const struct irq_affinity_desc *affdesc);\n@@ -1812,6 +1818,22 @@ pci_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs,\n \t\t\t\t\t flags, NULL);\n }\n \n+static inline int\n+pcim_alloc_irq_vectors_affinity(struct pci_dev *dev, unsigned int min_vecs,\n+\t\t\t unsigned int max_vecs, unsigned int flags,\n+\t\t\t struct irq_affinity *aff_desc)\n+{\n+\treturn pci_alloc_irq_vectors_affinity(dev, min_vecs, max_vecs,\n+\t\t\t\t\t flags, aff_desc);\n+}\n+static inline int\n+pcim_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs,\n+\t\t unsigned int max_vecs, unsigned int flags)\n+{\n+\treturn pcim_alloc_irq_vectors_affinity(dev, min_vecs, max_vecs,\n+\t\t\t\t\t flags, NULL);\n+}\n+\n static inline bool pci_msix_can_alloc_dyn(struct pci_dev *dev)\n { return false; }\n static inline struct msi_map pci_msix_alloc_irq_at(struct pci_dev *dev, unsigned int index,\n", "prefixes": [ "v4", "5/7" ] }