Thread (17 messages) flat view 17 messages, 4 authors, 2014-11-07

[V10 PATCH 2/2] irqchip: gicv2m: Add supports for ARM GICv2m MSI(-X)

From: suravee.suthikulpanit@amd.com (Suravee Suthikulanit)
Date: 2014-11-04 03:38:55
Also in: linux-devicetree, linux-pci, lkml

On 11/3/2014 4:51 PM, Thomas Gleixner wrote:
On Mon, 3 Nov 2014, suravee.suthikulpanit at amd.com wrote:
quoted
+static void gicv2m_teardown_msi_irq(struct msi_chip *chip, unsigned int irq)
+{
+	int pos;
+	struct v2m_data *v2m = container_of(chip, struct v2m_data, msi_chip);
+
+	spin_lock(&v2m->msi_cnt_lock);
Why do you need an extra lock here? Is that stuff not serialized from
the msi_chip layer already?

If not, why don't we have the serialization there instead of forcing
every callback to implement its own?
 From the following call paths:
   |--> pci_enable_msi_range
    |--> msi_capability_init
     |--> arch_setup_msi_irqs
      |--> arch_setup_msi_irq
and
   |--> pci_enable_msix
    |--> msix_capability_init
     |--> arch_setup_msi_irqs
      |--> arch_setup_msi_irq

It serialize when a PCI device driver tries to allocate multiple 
interrupts. However, AFAICT, it would not serialize the allocation when 
multiple drivers trying to setup MSI irqs at the same time. I needed 
that to protect the bitmap structure. I also noticed the same in other 
drivers as well.

I can look into this more to see where would be a good point.
quoted
+	pos = irq - v2m->spi_start;
So this assumes that @irq is the hwirq number, right? How does the
calling function know about that? It should only have knowledge about
the virq number if I'm not missing something.

And if I'm missing something, then that msi_chip stuff is seriously
broken.
It works this way because of the direct mapping (as you noticed). But I 
am planning to change that. See below.
quoted
+	if (pos >= 0 && pos < v2m->nr_spis)
So you simply avoid the clear bitmap instead of yelling loudly about
being called with completely wrong data?
I'll provide appropriate warnings.
I would not be surprised if that is related to my question above.
Not quite sure which of the above questions.
quoted
+	spin_lock(&v2m->msi_cnt_lock);
+	offset = bitmap_find_free_region(v2m->bm, v2m->nr_spis, 0);
+	spin_unlock(&v2m->msi_cnt_lock);
+	if (offset < 0)
+		return offset;
+
+	hwirq = v2m->spi_start + offset;
+	virq = __irq_domain_alloc_irqs(v2m->domain, hwirq,
+				       1, NUMA_NO_NODE, v2m, true);
+	if (virq < 0) {
+		gicv2m_teardown_msi_irq(chip, hwirq);
+		return virq;
+	}
+
+	irq_domain_set_hwirq_and_chip(v2m->domain, virq, hwirq,
+				&v2m_chip, v2m);
+
+	irq_set_msi_desc(hwirq, desc);
+	irq_set_irq_type(hwirq, IRQ_TYPE_EDGE_RISING);
Sure both calls work perfectly fine as long as virq == hwirq, right?
I was running into an issue when calling the 
irq_domain_alloc_irq_parent(), it requires of_phandle_args pointer to be 
passed in. However, this does not work for GICv2m since it does not have 
interrupt information in the device tree. So, I decided at first to use 
direct (virq == hwirq) mapping, which simplifies the code a bit, but 
might not be ideal solution, as you pointed out.

An alternative would be to create a temporary struct of_phandle_args, 
and populate it with the interrupt information for the requested MSI. 
Then pass it to:
   --> irq_domain_alloc_irq_parent
    |--> gic_irq_domain_alloc
      |--> gic_irq_domain_xlate
      |--> gic_irq_domain_map

However, this would still not be ideal if we want to support ACPI. 
Another alternative would be coming up with a dedicate structure to be 
used here. I noticed on X86, it uses struct irq_alloc_info. May be 
that's what we also need here.
[...]
I do not care at all how YOU waste your time. But I care very much
about the fact that YOU are wasting MY precious time by exposing me to
your patch trainwrecks.
I don't intend to waste yours or anybody's precious time. Sorry if it 
takes a couple iterations to work out the issues. Also, I will try to 
put more comment in my code to make it more clear. Let me know what 
works best for you to work out the issues.

Thanks,

Suravee
Thanks,

	tglx
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help