* Re: [PATCH 1/1] irqdomain: Export __irq_domain_alloc_irqs() and irq_domain_free_irqs()
[not found] ` <578CCCDB.4050800@linux.com>
@ 2016-07-25 19:35 ` Alexander Popov
2016-07-27 11:22 ` Christoph Hellwig
0 siblings, 1 reply; 4+ messages in thread
From: Alexander Popov @ 2016-07-25 19:35 UTC (permalink / raw)
To: Marc Zyngier
Cc: Thomas Gleixner, LKML, Paolo Bonzini, Radim Krčmář,
Joerg Roedel, kvm
On 18.07.2016 15:34, Alexander Popov wrote:
> On 16.07.2016 11:22, Marc Zyngier wrote:
>> On Sat, 16 Jul 2016 04:33:59 +0300
>> Alexander Popov <alex.popov@linux.com> wrote:
>>
>>> On 08.07.2016 11:34, Alexander Popov wrote:
>>>> On 06.07.2016 14:17, Thomas Gleixner wrote:
>>>>> On Fri, 1 Jul 2016, Alexander Popov wrote:
>>>>>
>>>>>> Export __irq_domain_alloc_irqs() and irq_domain_free_irqs() for being
>>>>>> able to work with irq_domain hierarchy in modules.
>>>>>
>>>>> We usually export only when we have a proper use case which is supposed to go
>>>>> into the kernel tree proper. What's yours?
>
> ...
>
>>> Did I properly answer your question? Will you accept my patch exporting these
>>> two functions?
>>
>> I think that without any in-tree modular users of these symbols, the
>> incentive for exporting those is pretty low. I can't really say
>> anything about your particular use-case, but I'd really to see some
>> code before taking that kind of patch.
>
> Thanks for your answer, Mark.
>
> Here is the module which uses __irq_domain_alloc_irqs() and
> irq_domain_free_irqs() and allows registering IRQ handlers for interrupts
> injected by the hypervisor on x86_64. Large hypervisors usually emulate
> an MSI-capable PCI device to do this job, but that way is inappropriate
> for lightweight hypervisors.
I hope that the code below is a valid use-case of irq_domain hierarchy API.
Such simple registration of IRQ handlers for interrupts injected by a hypervisor
is great for lightweight hypervisors, which avoid as much emulation as possible.
It only needs __irq_domain_alloc_irqs() and irq_domain_free_irqs() to be
exported to modules. Will you apply my patch which exports them?
[Add CC to KVM people to share the idea and, hopefully, find anybody interested]
> /*
> * The module for registering IRQ handlers for interrupts injected
> * by the hypervisor using Intel VT-x technology. This module targets
> * x86_64 platform.
> *
> * It works fine if __irq_domain_alloc_irqs() and irq_domain_free_irqs()
> * are exported.
> */
>
> #include <linux/module.h>
> #include <linux/irq.h>
> #include <linux/irqdesc.h>
> #include <linux/irqnr.h>
> #include <linux/irqdomain.h>
> #include <linux/interrupt.h>
> #include <asm/hw_irq.h>
> #include <asm/irqdomain.h>
>
> #define PARAVIRT_IRQS_N 10
>
> struct irq_domain *paravirq_domain = NULL;
> static int paravirq_irqbase = -EINVAL;
> static int paravirq_irqs[PARAVIRT_IRQS_N] =
> {[0 ... PARAVIRT_IRQS_N - 1] = -EINVAL};
>
> static irqreturn_t paravirq_irq_handler(int irq, void *cookie)
> {
> printk("\tparavirq_irq_handler: virq %d\n", irq);
>
> /* ... some job ... */
>
> return IRQ_HANDLED;
> }
>
> static void paravirq_chip_irq_mask(struct irq_data *data)
> {
> printk("\tparavirq_chip_irq_mask\n");
>
> /* ... tell the hypervisor not to inject the interrupt ... */
> }
>
> static void paravirq_chip_irq_unmask(struct irq_data *data)
> {
> printk("\tparavirq_chip_irq_UNmask\n");
>
> /* ... allow the hypervisor to inject the interrupt ... */
> }
>
> static void paravirq_chip_ack(struct irq_data *data)
> {
> data = data->parent_data;
> data->chip->irq_ack(data);
> }
>
> static struct irq_chip paravirq_chip __read_mostly = {
> .name = "PARAVIRQ",
> .irq_mask = paravirq_chip_irq_mask,
> .irq_unmask = paravirq_chip_irq_unmask,
> .irq_ack = paravirq_chip_ack,
> };
>
> static int paravirq_domain_alloc(struct irq_domain *domain,
> unsigned int virq, unsigned int nr_irqs, void *arg)
> {
> int ret = 0;
> unsigned int i = 0;
> unsigned int irq = 0;
>
> printk("\tparavirq_domain_alloc: virq %u, nr_irqs %u, arg 0x%p\n",
> virq, nr_irqs, arg);
> for (i = 0; i < nr_irqs; i++) {
> irq = virq + i;
>
> ret = irq_domain_set_hwirq_and_chip(domain,
> irq, i, ¶virq_chip, NULL);
> if (ret) {
> printk("\t\tsetting chip, hwirq for %d failed\n", irq);
> return ret;
> }
>
> __irq_set_handler(irq, handle_edge_irq, 0, "edge");
> }
>
> return 0;
> }
>
> static void paravirq_domain_free(struct irq_domain *domain, unsigned int virq,
> unsigned int nr_irqs)
> {
> int ret = 0;
> unsigned int i = 0;
> unsigned int irq = 0;
>
> printk("\tparavirq_domain_free: virq %u, nr_irqs %u\n", virq, nr_irqs);
>
> for (i = 0; i < nr_irqs; i++) {
> irq = virq + i;
>
> ret = irq_set_chip(irq, NULL);
> if (ret)
> printk("\t\tunsetting chip for %d failed\n", irq);
> }
> }
>
> const struct irq_domain_ops paravirq_irqdomain_ops = {
> .alloc = paravirq_domain_alloc,
> .free = paravirq_domain_free,
> };
>
> static int __init paravirq_init(void)
> {
> int ret = 0;
> int i = 0;
> struct irq_alloc_info info = { 0 };
> struct irq_cfg *cfg = NULL;
>
> printk("paravirq_init\n");
>
> paravirq_domain = irq_domain_add_linear(NULL, PARAVIRT_IRQS_N,
> ¶virq_irqdomain_ops, NULL);
> if (!paravirq_domain) {
> ret = -ENOMEM;
> goto err0;
> }
>
> paravirq_domain->name = paravirq_chip.name;
> paravirq_domain->parent = x86_vector_domain;
> paravirq_domain->flags |= IRQ_DOMAIN_FLAG_AUTO_RECURSIVE;
> printk("\tparavirq_domain %s (0x%p) is created\n",
> paravirq_domain->name, paravirq_domain);
>
> printk("\tcall irq_domain_alloc_irqs with info 0x%p\n", &info);
> paravirq_irqbase = irq_domain_alloc_irqs(paravirq_domain,
> PARAVIRT_IRQS_N, NUMA_NO_NODE, &info);
> if (paravirq_irqbase < 0) {
> printk("\tallocating irqs failed: %d\n", paravirq_irqbase);
> ret = paravirq_irqbase;
> goto err1;
> }
>
> printk("\tsuccessfully allocated %d irqs beginning from %d\n",
> PARAVIRT_IRQS_N, paravirq_irqbase);
>
> for (i = 0; i < PARAVIRT_IRQS_N; i++) {
> int irq = paravirq_irqbase + i;
>
> ret = request_irq(irq, paravirq_irq_handler,
> 0, "paravirq_mod", NULL);
> if (ret) {
> printk("\trequest_irq %d failed: %d\n", irq, ret);
> goto err2;
> } else {
> printk("\tvirq %d is requested!\n", irq);
> paravirq_irqs[i] = irq;
> }
> }
>
> printk("\tSo, paravirq_mod grabbed %d irqs:\n", PARAVIRT_IRQS_N);
> for (i = 0; i < PARAVIRT_IRQS_N; i++) {
> cfg = irqd_cfg(irq_get_irq_data(paravirq_irqs[i]));
> if (!cfg) {
> printk("\t\tirq #%d: NULL irq_cfg\n", paravirq_irqs[i]);
> goto err2;
> }
>
> printk("\t\tirq #%d: virq %d, vector %d\n",
> i, paravirq_irqs[i], cfg->vector);
> }
>
> return 0;
>
> err2:
> for (i = 0; i < PARAVIRT_IRQS_N; i++) {
> if (paravirq_irqs[i] >= 0) {
> printk("\tfreeing virq %d\n", paravirq_irqs[i]);
> free_irq(paravirq_irqs[i], NULL);
> }
> }
> irq_domain_free_irqs(paravirq_irqbase, PARAVIRT_IRQS_N);
> err1:
> irq_domain_remove(paravirq_domain);
> err0:
> return ret;
> }
>
> static void __exit paravirq_exit(void)
> {
> int i;
>
> printk("paravirq_exit\n");
>
> for (i = 0; i < PARAVIRT_IRQS_N; i++) {
> if (paravirq_irqs[i] > 0) {
> printk("\tfreeing virq %d\n", paravirq_irqs[i]);
> free_irq(paravirq_irqs[i], NULL);
> }
> }
>
> if (paravirq_irqbase >= 0)
> irq_domain_free_irqs(paravirq_irqbase, PARAVIRT_IRQS_N);
>
> if (paravirq_domain)
> irq_domain_remove(paravirq_domain);
> }
>
> module_init(paravirq_init)
> module_exit(paravirq_exit)
>
> MODULE_AUTHOR("Alexander Popov <alex.popov@linux.com>");
> MODULE_DESCRIPTION("The module for handling interrupts from the hypervisor");
> MODULE_LICENSE("GPL v2");
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 1/1] irqdomain: Export __irq_domain_alloc_irqs() and irq_domain_free_irqs()
2016-07-25 19:35 ` [PATCH 1/1] irqdomain: Export __irq_domain_alloc_irqs() and irq_domain_free_irqs() Alexander Popov
@ 2016-07-27 11:22 ` Christoph Hellwig
2016-07-29 23:21 ` Alexander Popov
0 siblings, 1 reply; 4+ messages in thread
From: Christoph Hellwig @ 2016-07-27 11:22 UTC (permalink / raw)
To: Alexander Popov
Cc: Marc Zyngier, Thomas Gleixner, LKML, Paolo Bonzini,
Radim Kr??m????, Joerg Roedel, kvm
Hi Alex,
just submit your PV irq chip for the kernel. It's so small that there
propbably is not need to even make it modular.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 1/1] irqdomain: Export __irq_domain_alloc_irqs() and irq_domain_free_irqs()
2016-07-27 11:22 ` Christoph Hellwig
@ 2016-07-29 23:21 ` Alexander Popov
2016-08-01 11:28 ` Jason Cooper
0 siblings, 1 reply; 4+ messages in thread
From: Alexander Popov @ 2016-07-29 23:21 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Marc Zyngier, Thomas Gleixner, LKML, Paolo Bonzini, Radim Krcmar,
Joerg Roedel, kvm
On 27.07.2016 14:22, Christoph Hellwig wrote:
> Hi Alex,
>
> just submit your PV irq chip for the kernel. It's so small that there
> propbably is not need to even make it modular.
Hello, Christoph,
Thanks a lot for your reply!
I'll try to do that and come up with a patch.
Best regards,
Alexander
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 1/1] irqdomain: Export __irq_domain_alloc_irqs() and irq_domain_free_irqs()
2016-07-29 23:21 ` Alexander Popov
@ 2016-08-01 11:28 ` Jason Cooper
0 siblings, 0 replies; 4+ messages in thread
From: Jason Cooper @ 2016-08-01 11:28 UTC (permalink / raw)
To: Alexander Popov
Cc: Christoph Hellwig, Marc Zyngier, Thomas Gleixner, LKML,
Paolo Bonzini, Radim Krcmar, Joerg Roedel, kvm
Hi Alexander,
On Sat, Jul 30, 2016 at 02:21:21AM +0300, Alexander Popov wrote:
> On 27.07.2016 14:22, Christoph Hellwig wrote:
> > just submit your PV irq chip for the kernel. It's so small that there
> > propbably is not need to even make it modular.
>
> Thanks a lot for your reply!
> I'll try to do that and come up with a patch.
Please include me in the Cc when you send.
thx,
Jason.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2016-08-01 11:28 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <1467401388-11221-1-git-send-email-alex.popov@linux.com>
[not found] ` <alpine.DEB.2.11.1607061316420.4083@nanos>
[not found] ` <577F6578.6030904@linux.com>
[not found] ` <57898F07.7030609@linux.com>
[not found] ` <20160716092218.3a2de5c7@arm.com>
[not found] ` <578CCCDB.4050800@linux.com>
2016-07-25 19:35 ` [PATCH 1/1] irqdomain: Export __irq_domain_alloc_irqs() and irq_domain_free_irqs() Alexander Popov
2016-07-27 11:22 ` Christoph Hellwig
2016-07-29 23:21 ` Alexander Popov
2016-08-01 11:28 ` Jason Cooper
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox