Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1622759 > unrolled thread
| Started by | Christoph Hellwig <hch@lst.de> |
|---|---|
| First post | 2017-04-13 09:10 +0200 |
| Last post | 2017-04-18 20:50 +0200 |
| Articles | 12 — 4 participants |
Back to article view | Back to linux.kernel
provide pci_request_irq / pci_free_irq helpers Christoph Hellwig <hch@lst.de> - 2017-04-13 09:10 +0200
[PATCH 1/4] genirq: fix indentation in remove_irq Christoph Hellwig <hch@lst.de> - 2017-04-13 09:10 +0200
Re: [PATCH 1/4] genirq: fix indentation in remove_irq Thomas Gleixner <tglx@linutronix.de> - 2017-04-14 19:30 +0200
Re: [PATCH 1/4] genirq: fix indentation in remove_irq Sagi Grimberg <sagi@grimberg.me> - 2017-04-20 15:30 +0200
[PATCH 3/4] PCI/irq: add pci_request_irq and pci_free_irq helpers Christoph Hellwig <hch@lst.de> - 2017-04-13 09:10 +0200
Re: [PATCH 3/4] PCI/irq: add pci_request_irq and pci_free_irq helpers Bjorn Helgaas <helgaas@kernel.org> - 2017-04-14 16:50 +0200
Re: [PATCH 3/4] PCI/irq: add pci_request_irq and pci_free_irq helpers Christoph Hellwig <hch@lst.de> - 2017-04-14 18:00 +0200
[PATCH 2/4] genirq: return the irq name from free_irq Christoph Hellwig <hch@lst.de> - 2017-04-13 09:10 +0200
Re: [PATCH 2/4] genirq: return the irq name from free_irq Thomas Gleixner <tglx@linutronix.de> - 2017-04-14 19:30 +0200
Re: [PATCH 2/4] genirq: return the irq name from free_irq Christoph Hellwig <hch@lst.de> - 2017-04-14 19:40 +0200
Re: [PATCH 2/4] genirq: return the irq name from free_irq Thomas Gleixner <tglx@linutronix.de> - 2017-04-14 20:00 +0200
Re: provide pci_request_irq / pci_free_irq helpers Bjorn Helgaas <helgaas@kernel.org> - 2017-04-18 20:50 +0200
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2017-04-13 09:10 +0200 |
| Subject | provide pci_request_irq / pci_free_irq helpers |
| Message-ID | <tvH3c-7S2-5@gated-at.bofh.it> |
PCI drivers that support multiple MSI or MSI-X vectors currently have a
lot of boileplate code to generate names for each vector (or simply use
the same name for all of them, which isn't nice either). This series
adds new helpers that allocate and free a name based on a format string
passed to the request_irq wrapper.
They also hide the [pci_dev,vector] to Linux irq number translation,
in fact the example NVMe driver conversion now never sees the Linux irq
number. That might be useful to isolate PCI drivers from our IRQ numbers,
although to have a full abstraction we'd need similar wrappers for
{enable,disable,synchronize}_irq as well.
[toc] | [next] | [standalone]
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2017-04-13 09:10 +0200 |
| Subject | [PATCH 1/4] genirq: fix indentation in remove_irq |
| Message-ID | <tvH3c-7S2-9@gated-at.bofh.it> |
| In reply to | #1622759 |
Signed-off-by: Christoph Hellwig <hch@lst.de> --- kernel/irq/manage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index a4afe5cc5af1..391cb738b2db 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -1557,7 +1557,7 @@ void remove_irq(unsigned int irq, struct irqaction *act) struct irq_desc *desc = irq_to_desc(irq); if (desc && !WARN_ON(irq_settings_is_per_cpu_devid(desc))) - __free_irq(irq, act->dev_id); + __free_irq(irq, act->dev_id); } EXPORT_SYMBOL_GPL(remove_irq); -- 2.11.0
[toc] | [prev] | [next] | [standalone]
| From | Thomas Gleixner <tglx@linutronix.de> |
|---|---|
| Date | 2017-04-14 19:30 +0200 |
| Subject | Re: [PATCH 1/4] genirq: fix indentation in remove_irq |
| Message-ID | <twdcJ-3T6-11@gated-at.bofh.it> |
| In reply to | #1622760 |
On Thu, 13 Apr 2017, Christoph Hellwig wrote: > Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
[toc] | [prev] | [next] | [standalone]
| From | Sagi Grimberg <sagi@grimberg.me> |
|---|---|
| Date | 2017-04-20 15:30 +0200 |
| Subject | Re: [PATCH 1/4] genirq: fix indentation in remove_irq |
| Message-ID | <tykjL-11j-3@gated-at.bofh.it> |
| In reply to | #1622760 |
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
[toc] | [prev] | [next] | [standalone]
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2017-04-13 09:10 +0200 |
| Subject | [PATCH 3/4] PCI/irq: add pci_request_irq and pci_free_irq helpers |
| Message-ID | <tvH3c-7S2-19@gated-at.bofh.it> |
| In reply to | #1622759 |
These are small wrappers around request_threaded_irq and free_irq,
which dynamically allocate space for the device name so that drivers
don't need to keep static buffers for these around. Additionally it
works with device-relative vector numbers to make the usage easier,
and force the IRQF_SHARED flag on given that it has no runtime overhead
and should be supported by all PCI devices.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/pci/irq.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
include/linux/pci.h | 6 ++++++
2 files changed, 66 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/irq.c b/drivers/pci/irq.c
index 6684f153ab57..53e7f30d9461 100644
--- a/drivers/pci/irq.c
+++ b/drivers/pci/irq.c
@@ -1,7 +1,8 @@
/*
- * PCI IRQ failure handing code
+ * PCI IRQ handing code
*
* Copyright (c) 2008 James Bottomley <James.Bottomley@HansenPartnership.com>
+ * Copyright (C) 2017 Christoph Hellwig.
*/
#include <linux/acpi.h>
@@ -59,3 +60,61 @@ enum pci_lost_interrupt_reason pci_lost_interrupt(struct pci_dev *pdev)
return PCI_LOST_IRQ_NO_INFORMATION;
}
EXPORT_SYMBOL(pci_lost_interrupt);
+
+/**
+ * pci_request_irq - allocate an interrupt line for a PCI device
+ * @dev: PCI device to operate on
+ * @nr: device-relative interrupt vector index (0-based).
+ * @handler: Function to be called when the IRQ occurs.
+ * Primary handler for threaded interrupts.
+ * If NULL and thread_fn != NULL the default primary handler is
+ * installed.
+ * @thread_fn: Function called from the irq handler thread
+ * If NULL, no irq thread is created
+ * @dev_id: Cookie passed back to the handler function
+ * @fmt: Printf-like format string naming the handler
+ *
+ * This call allocates interrupt resources and enables the interrupt line and
+ * IRQ handling. From the point this call is made @handler and @thread_fn may
+ * be invoked. All interrupt requsted using this function might be shared.
+ *
+ * @dev_id must not ne NULL and be globally unique.
+ */
+int pci_request_irq(struct pci_dev *dev, unsigned int nr, irq_handler_t handler,
+ irq_handler_t thread_fn, void *dev_id, const char *fmt, ...)
+{
+ va_list ap;
+ int ret;
+ char *devname;
+
+ va_start(ap, fmt);
+ devname = kvasprintf(GFP_KERNEL, fmt, ap);
+ va_end(ap);
+
+ ret = request_threaded_irq(pci_irq_vector(dev, nr), handler, thread_fn,
+ IRQF_SHARED, devname, dev_id);
+ if (ret)
+ kfree(devname);
+ return ret;
+}
+EXPORT_SYMBOL(pci_request_irq);
+
+/**
+ * pci_free_irq - free an interrupt allocated with pci_request_irq
+ * @dev: PCI device to operate on
+ * @nr: device-relative interrupt vector index (0-based).
+ * @dev_id: Device identity to free
+ *
+ * Remove an interrupt handler. The handler is removed and if the interrupt
+ * line is no longer in use by any driver it is disabled. The caller must
+ * ensure the interrupt is disabled on the device before calling this function.
+ * The function does not return until any executing interrupts for this IRQ
+ * have completed.
+ *
+ * This function must not be called from interrupt context.
+ */
+void pci_free_irq(struct pci_dev *dev, unsigned int nr, void *dev_id)
+{
+ kfree(free_irq(pci_irq_vector(dev, nr), dev_id));
+}
+EXPORT_SYMBOL(pci_free_irq);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index eb3da1a04e6c..b23f81b583ab 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -28,6 +28,7 @@
#include <linux/kobject.h>
#include <linux/atomic.h>
#include <linux/device.h>
+#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/resource_ext.h>
#include <uapi/linux/pci.h>
@@ -1072,6 +1073,11 @@ int pci_select_bars(struct pci_dev *dev, unsigned long flags);
bool pci_device_is_present(struct pci_dev *pdev);
void pci_ignore_hotplug(struct pci_dev *dev);
+int __printf(6, 7) pci_request_irq(struct pci_dev *dev, unsigned int nr,
+ irq_handler_t handler, irq_handler_t thread_fn, void *dev_id,
+ const char *fmt, ...);
+void pci_free_irq(struct pci_dev *dev, unsigned int nr, void *dev_id);
+
/* ROM control related routines */
int pci_enable_rom(struct pci_dev *pdev);
void pci_disable_rom(struct pci_dev *pdev);
--
2.11.0
[toc] | [prev] | [next] | [standalone]
| From | Bjorn Helgaas <helgaas@kernel.org> |
|---|---|
| Date | 2017-04-14 16:50 +0200 |
| Subject | Re: [PATCH 3/4] PCI/irq: add pci_request_irq and pci_free_irq helpers |
| Message-ID | <twaHT-2g9-7@gated-at.bofh.it> |
| In reply to | #1622766 |
On Thu, Apr 13, 2017 at 09:06:42AM +0200, Christoph Hellwig wrote:
> These are small wrappers around request_threaded_irq and free_irq,
> which dynamically allocate space for the device name so that drivers
> don't need to keep static buffers for these around. Additionally it
> works with device-relative vector numbers to make the usage easier,
> and force the IRQF_SHARED flag on given that it has no runtime overhead
> and should be supported by all PCI devices.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Let me know if you'd like me to take this series (given an appropriate
ack for the genirq parts).
> ---
> drivers/pci/irq.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
> include/linux/pci.h | 6 ++++++
> 2 files changed, 66 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/pci/irq.c b/drivers/pci/irq.c
> index 6684f153ab57..53e7f30d9461 100644
> --- a/drivers/pci/irq.c
> +++ b/drivers/pci/irq.c
> @@ -1,7 +1,8 @@
> /*
> - * PCI IRQ failure handing code
> + * PCI IRQ handing code
> *
> * Copyright (c) 2008 James Bottomley <James.Bottomley@HansenPartnership.com>
> + * Copyright (C) 2017 Christoph Hellwig.
> */
>
> #include <linux/acpi.h>
> @@ -59,3 +60,61 @@ enum pci_lost_interrupt_reason pci_lost_interrupt(struct pci_dev *pdev)
> return PCI_LOST_IRQ_NO_INFORMATION;
> }
> EXPORT_SYMBOL(pci_lost_interrupt);
> +
> +/**
> + * pci_request_irq - allocate an interrupt line for a PCI device
> + * @dev: PCI device to operate on
> + * @nr: device-relative interrupt vector index (0-based).
> + * @handler: Function to be called when the IRQ occurs.
> + * Primary handler for threaded interrupts.
> + * If NULL and thread_fn != NULL the default primary handler is
> + * installed.
> + * @thread_fn: Function called from the irq handler thread
> + * If NULL, no irq thread is created
> + * @dev_id: Cookie passed back to the handler function
> + * @fmt: Printf-like format string naming the handler
> + *
> + * This call allocates interrupt resources and enables the interrupt line and
> + * IRQ handling. From the point this call is made @handler and @thread_fn may
> + * be invoked. All interrupt requsted using this function might be shared.
> + *
> + * @dev_id must not ne NULL and be globally unique.
> + */
> +int pci_request_irq(struct pci_dev *dev, unsigned int nr, irq_handler_t handler,
> + irq_handler_t thread_fn, void *dev_id, const char *fmt, ...)
> +{
> + va_list ap;
> + int ret;
> + char *devname;
> +
> + va_start(ap, fmt);
> + devname = kvasprintf(GFP_KERNEL, fmt, ap);
> + va_end(ap);
> +
> + ret = request_threaded_irq(pci_irq_vector(dev, nr), handler, thread_fn,
> + IRQF_SHARED, devname, dev_id);
> + if (ret)
> + kfree(devname);
> + return ret;
> +}
> +EXPORT_SYMBOL(pci_request_irq);
> +
> +/**
> + * pci_free_irq - free an interrupt allocated with pci_request_irq
> + * @dev: PCI device to operate on
> + * @nr: device-relative interrupt vector index (0-based).
> + * @dev_id: Device identity to free
> + *
> + * Remove an interrupt handler. The handler is removed and if the interrupt
> + * line is no longer in use by any driver it is disabled. The caller must
> + * ensure the interrupt is disabled on the device before calling this function.
> + * The function does not return until any executing interrupts for this IRQ
> + * have completed.
> + *
> + * This function must not be called from interrupt context.
> + */
> +void pci_free_irq(struct pci_dev *dev, unsigned int nr, void *dev_id)
> +{
> + kfree(free_irq(pci_irq_vector(dev, nr), dev_id));
> +}
> +EXPORT_SYMBOL(pci_free_irq);
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index eb3da1a04e6c..b23f81b583ab 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -28,6 +28,7 @@
> #include <linux/kobject.h>
> #include <linux/atomic.h>
> #include <linux/device.h>
> +#include <linux/interrupt.h>
> #include <linux/io.h>
> #include <linux/resource_ext.h>
> #include <uapi/linux/pci.h>
> @@ -1072,6 +1073,11 @@ int pci_select_bars(struct pci_dev *dev, unsigned long flags);
> bool pci_device_is_present(struct pci_dev *pdev);
> void pci_ignore_hotplug(struct pci_dev *dev);
>
> +int __printf(6, 7) pci_request_irq(struct pci_dev *dev, unsigned int nr,
> + irq_handler_t handler, irq_handler_t thread_fn, void *dev_id,
> + const char *fmt, ...);
> +void pci_free_irq(struct pci_dev *dev, unsigned int nr, void *dev_id);
> +
> /* ROM control related routines */
> int pci_enable_rom(struct pci_dev *pdev);
> void pci_disable_rom(struct pci_dev *pdev);
> --
> 2.11.0
>
[toc] | [prev] | [next] | [standalone]
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2017-04-14 18:00 +0200 |
| Subject | Re: [PATCH 3/4] PCI/irq: add pci_request_irq and pci_free_irq helpers |
| Message-ID | <twbNE-2TD-17@gated-at.bofh.it> |
| In reply to | #1623707 |
On Fri, Apr 14, 2017 at 09:46:49AM -0500, Bjorn Helgaas wrote: > Acked-by: Bjorn Helgaas <bhelgaas@google.com> > > Let me know if you'd like me to take this series (given an appropriate > ack for the genirq parts). I want to hear from Thomas on the genirq bits. But if he's fine with it might be a good idea to take it through your tree.
[toc] | [prev] | [next] | [standalone]
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2017-04-13 09:10 +0200 |
| Subject | [PATCH 2/4] genirq: return the irq name from free_irq |
| Message-ID | <tvH3c-7S2-25@gated-at.bofh.it> |
| In reply to | #1622759 |
This allows callers to get back at them instead of having to store
it in another variable.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
include/linux/interrupt.h | 2 +-
kernel/irq/manage.c | 13 ++++++++++---
2 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 53144e78a369..a6fba4804672 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -155,7 +155,7 @@ extern int __must_check
request_percpu_irq(unsigned int irq, irq_handler_t handler,
const char *devname, void __percpu *percpu_dev_id);
-extern void free_irq(unsigned int, void *);
+extern const void *free_irq(unsigned int, void *);
extern void free_percpu_irq(unsigned int, void __percpu *);
struct device;
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 391cb738b2db..e688e7e06772 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -1574,20 +1574,27 @@ EXPORT_SYMBOL_GPL(remove_irq);
* have completed.
*
* This function must not be called from interrupt context.
+ *
+ * Returns the devname argument passed to request_irq.
*/
-void free_irq(unsigned int irq, void *dev_id)
+const void *free_irq(unsigned int irq, void *dev_id)
{
struct irq_desc *desc = irq_to_desc(irq);
+ struct irqaction *action;
+ const char *devname;
if (!desc || WARN_ON(irq_settings_is_per_cpu_devid(desc)))
- return;
+ return NULL;
#ifdef CONFIG_SMP
if (WARN_ON(desc->affinity_notify))
desc->affinity_notify = NULL;
#endif
- kfree(__free_irq(irq, dev_id));
+ action = __free_irq(irq, dev_id);
+ devname = action->name;
+ kfree(action);
+ return devname;
}
EXPORT_SYMBOL(free_irq);
--
2.11.0
[toc] | [prev] | [next] | [standalone]
| From | Thomas Gleixner <tglx@linutronix.de> |
|---|---|
| Date | 2017-04-14 19:30 +0200 |
| Subject | Re: [PATCH 2/4] genirq: return the irq name from free_irq |
| Message-ID | <twdcJ-3T6-3@gated-at.bofh.it> |
| In reply to | #1622768 |
On Thu, 13 Apr 2017, Christoph Hellwig wrote: > This allows callers to get back at them instead of having to store > it in another variable. Alternatively you tell the irq code to free it for you. Patch below. Thanks, tglx 8<----------------------- --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -60,7 +60,9 @@ * IRQF_COND_SUSPEND - If the IRQ is shared with a NO_SUSPEND user, execute this * interrupt handler after suspending interrupts. For system * wakeup devices users need to implement wakeup detection in - * their interrupt handlers. + * their interrupt handlers + * IRQF_FREE_NAME - Free the memory pointed to by the @name argument of + * request_irq() in free_irq() */ #define IRQF_SHARED 0x00000080 #define IRQF_PROBE_SHARED 0x00000100 @@ -74,6 +76,7 @@ #define IRQF_NO_THREAD 0x00010000 #define IRQF_EARLY_RESUME 0x00020000 #define IRQF_COND_SUSPEND 0x00040000 +#define IRQF_FREE_NAME 0x00080000 #define IRQF_TIMER (__IRQF_TIMER | IRQF_NO_SUSPEND | IRQF_NO_THREAD) --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -1542,6 +1542,8 @@ static struct irqaction *__free_irq(unsi irq_chip_pm_put(&desc->irq_data); module_put(desc->owner); kfree(action->secondary); + if (action->flags & IRQF_FREE_NAME) + kfree(action->name); return action; }
[toc] | [prev] | [next] | [standalone]
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2017-04-14 19:40 +0200 |
| Subject | Re: [PATCH 2/4] genirq: return the irq name from free_irq |
| Message-ID | <twdmq-3Wz-5@gated-at.bofh.it> |
| In reply to | #1623801 |
On Fri, Apr 14, 2017 at 07:28:42PM +0200, Thomas Gleixner wrote: > On Thu, 13 Apr 2017, Christoph Hellwig wrote: > > > This allows callers to get back at them instead of having to store > > it in another variable. > > Alternatively you tell the irq code to free it for you. Patch below. Yes, this should work to. But I think having the same layer free something they allocated again is a tad cleaner in terms of layering. If you prefer this version I can respin the series.
[toc] | [prev] | [next] | [standalone]
| From | Thomas Gleixner <tglx@linutronix.de> |
|---|---|
| Date | 2017-04-14 20:00 +0200 |
| Subject | Re: [PATCH 2/4] genirq: return the irq name from free_irq |
| Message-ID | <twdFM-43B-15@gated-at.bofh.it> |
| In reply to | #1623805 |
On Fri, 14 Apr 2017, Christoph Hellwig wrote:
> On Fri, Apr 14, 2017 at 07:28:42PM +0200, Thomas Gleixner wrote:
> > On Thu, 13 Apr 2017, Christoph Hellwig wrote:
> >
> > > This allows callers to get back at them instead of having to store
> > > it in another variable.
> >
> > Alternatively you tell the irq code to free it for you. Patch below.
>
> Yes, this should work to. But I think having the same layer free
> something they allocated again is a tad cleaner in terms of layering.
Fair enough. Was just a thought.
Bjorn, please route it through PCI alltogether.
For the whole series:
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Thanks,
tglx
[toc] | [prev] | [next] | [standalone]
| From | Bjorn Helgaas <helgaas@kernel.org> |
|---|---|
| Date | 2017-04-18 20:50 +0200 |
| Message-ID | <txGmm-17N-25@gated-at.bofh.it> |
| In reply to | #1622759 |
On Thu, Apr 13, 2017 at 09:06:39AM +0200, Christoph Hellwig wrote:
> PCI drivers that support multiple MSI or MSI-X vectors currently have a
> lot of boileplate code to generate names for each vector (or simply use
> the same name for all of them, which isn't nice either). This series
> adds new helpers that allocate and free a name based on a format string
> passed to the request_irq wrapper.
>
> They also hide the [pci_dev,vector] to Linux irq number translation,
> in fact the example NVMe driver conversion now never sees the Linux irq
> number. That might be useful to isolate PCI drivers from our IRQ numbers,
> although to have a full abstraction we'd need similar wrappers for
> {enable,disable,synchronize}_irq as well.
Applied with reviewed-by from Thomas and Keith to pci/irq for v4.12,
thanks!
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web