public inbox for linux-arm-kernel@lists.infradead.org
 help / color / mirror / Atom feed
From: Lokesh Vutla <lokeshvutla@ti.com>
To: Marc Zyngier <Marc.Zyngier@arm.com>, Nishanth Menon <nm@ti.com>,
	Santosh Shilimkar <ssantosh@kernel.org>,
	Rob Herring <robh+dt@kernel.org>,
	"tglx@linutronix.de" <tglx@linutronix.de>,
	"jason@lakedaemon.net" <jason@lakedaemon.net>
Cc: Device Tree Mailing List <devicetree@vger.kernel.org>,
	Peter Ujfalusi <peter.ujfalusi@ti.com>,
	Sekhar Nori <nsekhar@ti.com>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	Tero Kristo <t-kristo@ti.com>,
	Linux ARM Mailing List <linux-arm-kernel@lists.infradead.org>
Subject: Re: [RFC PATCH v4 08/13] genirq/msi: Add support for allocating single MSI for a device
Date: Thu, 24 Jan 2019 15:49:31 +0530	[thread overview]
Message-ID: <faad8e90-2f97-1dbb-fb98-e0f1462e29c5@ti.com> (raw)
In-Reply-To: <5be38277-3348-a6d9-4b67-3ead308c009a@arm.com>

Hi Marc,
	Sorry for the delayed response. Just back from vacation.

On 17/01/19 12:00 AM, Marc Zyngier wrote:
> On 27/12/2018 06:13, Lokesh Vutla wrote:
>> Previously all msi for a device are allocated in one go
>> by calling msi_domain_alloc_irq() from a bus layer. This might
>> not be the case when a device is trying to allocate interrupts
>> dynamically based on a request to it.
>>
>> So introduce msi_domain_alloc/free_irq() apis to allocate a single
>> msi. prepare and activate operations to be handled by bus layer
>> calling msi_domain_alloc/free_irq() apis.
>>
>> Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
>> ---
>>  include/linux/msi.h |  3 +++
>>  kernel/irq/msi.c    | 62 +++++++++++++++++++++++++++++----------------
>>  2 files changed, 43 insertions(+), 22 deletions(-)
>>
>> diff --git a/include/linux/msi.h b/include/linux/msi.h
>> index 784fb52b9900..474490826f8c 100644
>> --- a/include/linux/msi.h
>> +++ b/include/linux/msi.h
>> @@ -301,8 +301,11 @@ int msi_domain_set_affinity(struct irq_data *data, const struct cpumask *mask,
>>  struct irq_domain *msi_create_irq_domain(struct fwnode_handle *fwnode,
>>   struct msi_domain_info *info,
>>   struct irq_domain *parent);
>> +int msi_domain_alloc_irq(struct irq_domain *domain, struct device *dev,
>> + struct msi_desc *desc,  msi_alloc_info_t *arg);
>>  int msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev,
>>    int nvec);
>> +void msi_domain_free_irq(struct msi_desc *desc);
>>  void msi_domain_free_irqs(struct irq_domain *domain, struct device *dev);
>>  struct msi_domain_info *msi_get_domain_info(struct irq_domain *domain);
>>
>> diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c
>> index ad26fbcfbfc8..eb7459324113 100644
>> --- a/kernel/irq/msi.c
>> +++ b/kernel/irq/msi.c
>> @@ -387,6 +387,35 @@ static bool msi_check_reservation_mode(struct irq_domain *domain,
>>  return desc->msi_attrib.is_msix || desc->msi_attrib.maskbit;
>>  }
>>
>> +int msi_domain_alloc_irq(struct irq_domain *domain, struct device *dev,
>> + struct msi_desc *desc,  msi_alloc_info_t *arg)
>> +{
>> +struct msi_domain_info *info = domain->host_data;
>> +struct msi_domain_ops *ops = info->ops;
>> +int i, ret, virq;
>> +
>> +ops->set_desc(arg, desc);
>> +
>> +virq = __irq_domain_alloc_irqs(domain, -1, desc->nvec_used,
>> +       dev_to_node(dev), arg, false,
>> +       desc->affinity);
>> +if (virq < 0) {
>> +ret = -ENOSPC;
>> +if (ops->handle_error)
>> +ret = ops->handle_error(domain, desc, ret);
>> +if (ops->msi_finish)
>> +ops->msi_finish(arg, ret);
>> +return ret;
>> +}
>> +
>> +for (i = 0; i < desc->nvec_used; i++) {
>> +irq_set_msi_desc_off(virq, i, desc);
>> +irq_debugfs_copy_devname(virq + i, dev);
>> +}
>> +
>> +return 0;
>> +}
>> +
>>  /**
>>   * msi_domain_alloc_irqs - Allocate interrupts from a MSI interrupt domain
>>   * @domain:The domain to allocate from
>> @@ -404,7 +433,7 @@ int msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev,
>>  struct irq_data *irq_data;
>>  struct msi_desc *desc;
>>  msi_alloc_info_t arg;
>> -int i, ret, virq;
>> +int ret, virq;
>>  bool can_reserve;
>>
>>  ret = msi_domain_prepare_irqs(domain, dev, nvec, &arg);
>> @@ -412,24 +441,9 @@ int msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev,
>>  return ret;
>>
>>  for_each_msi_entry(desc, dev) {
>> -ops->set_desc(&arg, desc);
>> -
>> -virq = __irq_domain_alloc_irqs(domain, -1, desc->nvec_used,
>> -       dev_to_node(dev), &arg, false,
>> -       desc->affinity);
>> -if (virq < 0) {
>> -ret = -ENOSPC;
>> -if (ops->handle_error)
>> -ret = ops->handle_error(domain, desc, ret);
>> -if (ops->msi_finish)
>> -ops->msi_finish(&arg, ret);
>> +ret = msi_domain_alloc_irq(domain, dev, desc, &arg);
>> +if (ret)
>>  return ret;
>> -}
>> -
>> -for (i = 0; i < desc->nvec_used; i++) {
>> -irq_set_msi_desc_off(virq, i, desc);
>> -irq_debugfs_copy_devname(virq + i, dev);
>> -}
>>  }
>>
>>  if (ops->msi_finish)
>> @@ -487,6 +501,12 @@ int msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev,
>>  return ret;
>>  }
>>
>> +void msi_domain_free_irq(struct msi_desc *desc)
>> +{
>> +irq_domain_free_irqs(desc->irq, desc->nvec_used);
>> +desc->irq = 0;
>> +}
>> +
>>  /**
>>   * msi_domain_free_irqs - Free interrupts from a MSI interrupt @domain associated tp @dev
>>   * @domain:The domain to managing the interrupts
>> @@ -503,10 +523,8 @@ void msi_domain_free_irqs(struct irq_domain *domain, struct device *dev)
>>   * enough that there is no IRQ associated to this
>>   * entry. If that's the case, don't do anything.
>>   */
>> -if (desc->irq) {
>> -irq_domain_free_irqs(desc->irq, desc->nvec_used);
>> -desc->irq = 0;
>> -}
>> +if (desc->irq)
>> +msi_domain_free_irq(desc);
>>  }
>>  }
>>
>>
> 
> I can see some interesting issues with this API.
> 
> At the moment, MSIs are allocated upfront, and that's usually done
> before the driver can do anything else. With what you're suggesting
> here, MSIs can now be allocated at any time, which sounds great. But how
> does it work when MSIs get added/freed in parallel? I can't see any
> locking here...
> 
> It is also pretty nasty that the user of this API has to know about the
> MSI descriptor. Really, nobody should have to deal with this outside of
> the MSI layer.
> 
> The real question is why you need to need to allocate MSIs on demand for
> a given device. Usually, you allocate them because this is a per-CPU
> resource, or something similar. What makes it so variable that you need
> to resort to fine grained MSI allocation?

I added this after the discussion we had in the previous version[1] of this
series. Let me provide the details again:

As you must be aware INTR is interrupt re-director and INTA is the interrupt
multiplexer is the SoC. Here we are trying to address the interrupt connection
route as below:
Device(Global event) --> INTA --> INTR --> GIC

For the above case you suggested to have the following sw IRQ domain hierarchy:
INTA multi MSI --> INTA  -->  INTR  --> GIC

The problem here with the INTA MSI is that all the interrupts for a device
should be pre-allocated during the device probe time. But this is not what we
wanted especially for the DMA case.

An example DMA ring connection would look like below[2]:

                      +---------------------+
                       |         IA                |
+--------+        |            +------+   |        +--------+         +------+
| ring 1 +----->evtA+->VintX+-------->+   IR   +-- --->  GIC +-->
+--------+       |             +------+   |        +--------+         +------+
Linux IRQ Y
   evtA            |                             |
                       |                             |
                      +----------------------+

So when a DMA client driver requests a dma channel during probe, the DMA driver
gets a free ring in its allocated range. Then DMA driver requests MSI layer for
an IRQ. This is why I had to introduce on demand allocation of MSIs for a device.

The reason why we avoided DMA driver to allocate interrupts during its probe as
it is not aware of the exact no of channels that are going to be used. Also max
allocation of interrupts will overrun the gic IRQs available to this INTA and
the IPs that are connected to INTR directly will not get any interrupts.

I hope this is clear.

[1] https://lkml.org/lkml/2018/11/5/894
[2] https://pastebin.ubuntu.com/p/RTrgzfCMby/

Thanks and regards,
Lokesh

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2019-01-24 10:20 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-27  6:08 [PATCH v4 00/13] Add support for TISCI irqchip drivers Lokesh Vutla
2018-12-27  6:13 ` [PATCH v4 01/13] firmware: ti_sci: Add support to get TISCI handle using of_phandle Lokesh Vutla
2018-12-27  6:13   ` [PATCH v4 02/13] firmware: ti_sci: Add support for RM core ops Lokesh Vutla
2018-12-27  6:13   ` [PATCH v4 03/13] firmware: ti_sci: Add support for IRQ management Lokesh Vutla
2018-12-27  6:13   ` [PATCH v4 04/13] firmware: ti_sci: Add RM mapping table for am654 Lokesh Vutla
2018-12-27  6:13   ` [PATCH v4 05/13] firmware: ti_sci: Add helper apis to manage resources Lokesh Vutla
2018-12-27 16:15     ` Nishanth Menon
2018-12-27  6:13   ` [PATCH v4 06/13] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings Lokesh Vutla
2018-12-27  6:13   ` [PATCH v4 07/13] irqchip: ti-sci-intr: Add support for Interrupt Router driver Lokesh Vutla
2019-01-16 17:16     ` Marc Zyngier
2019-01-24 10:19       ` Lokesh Vutla
2018-12-27  6:13   ` [RFC PATCH v4 08/13] genirq/msi: Add support for allocating single MSI for a device Lokesh Vutla
2019-01-16 18:30     ` Marc Zyngier
2019-01-24 10:19       ` Lokesh Vutla [this message]
2019-02-04 10:33         ` Marc Zyngier
2019-02-05 13:42           ` Lokesh Vutla
2019-02-08 10:39             ` Marc Zyngier
2018-12-27  6:13   ` [RFC PATCH v4 09/13] genirq/msi: Add support for .msi_unprepare callback Lokesh Vutla
2019-01-17 10:39     ` Marc Zyngier
2018-12-27  6:13   ` [RFC PATCH v4 10/13] soc: ti: Add MSI domain support for K3 Interrupt Aggregator Lokesh Vutla
2019-01-15 14:41     ` Nishanth Menon
2018-12-27  6:13   ` [RFC PATCH v4 11/13] dt-bindings: irqchip: Introduce TISCI Interrupt Aggregator bindings Lokesh Vutla
2018-12-27  6:13   ` [RFC PATCH v4 12/13] irqchip: ti-sci-inta: Add support for Interrupt Aggregator driver Lokesh Vutla
2019-01-02 11:49     ` Peter Ujfalusi
2019-01-02 12:26       ` Lokesh Vutla
2019-01-15 12:38         ` Tero Kristo
2019-01-15 14:04           ` Nishanth Menon
2018-12-27  6:13   ` [RFC PATCH v4 13/13] soc: ti: am6: Enable interrupt controller drivers Lokesh Vutla
2019-01-15 13:54     ` Nishanth Menon
2019-01-02 11:58 ` [PATCH v4 00/13] Add support for TISCI irqchip drivers Peter Ujfalusi
2019-01-11 10:28 ` Lokesh Vutla

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=faad8e90-2f97-1dbb-fb98-e0f1462e29c5@ti.com \
    --to=lokeshvutla@ti.com \
    --cc=Marc.Zyngier@arm.com \
    --cc=devicetree@vger.kernel.org \
    --cc=jason@lakedaemon.net \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nm@ti.com \
    --cc=nsekhar@ti.com \
    --cc=peter.ujfalusi@ti.com \
    --cc=robh+dt@kernel.org \
    --cc=ssantosh@kernel.org \
    --cc=t-kristo@ti.com \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox