2022-05-13 07:15:20

by Marc Zyngier

[permalink] [raw]
Subject: [PATCH] gpio: Remove dynamic allocation from populate_parent_alloc_arg()

The gpiolib is unique in the way it uses intermediate fwspecs
when feeding an interrupt specifier to the parent domain, as it
relies on the populate_parent_alloc_arg() callback to perform
a dynamic allocation.

THis is pretty inefficient (we free the structure almost immediately),
and the only reason this isn't a stack allocation is that our
ThunderX friend uses MSIs rather than a FW-constructed structure.

Let's solve it by providing a new type composed of the union
of a struct irq_fwspec and a msi_info_t, which satisfies both
requirements. This allows us to use a stack allocation, and we
can move the handful of users to this new scheme.

Also perform some additional cleanup, such as getting rid of the
stub versions of the irq_domain_translate_*cell helpers, which
are never used when CONFIG_IRQ_DOMAIN_HIERARCHY isn't selected.

Tested on a Tegra186.

Signed-off-by: Marc Zyngier <[email protected]>
Cc: Daniel Palmer <[email protected]>
Cc: Romain Perier <[email protected]>
Cc: Linus Walleij <[email protected]>
Cc: Bartosz Golaszewski <[email protected]>
Cc: Thierry Reding <[email protected]>
Cc: Jonathan Hunter <[email protected]>
Cc: Robert Richter <[email protected]>
Cc: Nobuhiro Iwamatsu <[email protected]>
Cc: Andy Gross <[email protected]>
Cc: Bjorn Andersson <[email protected]>
---
drivers/gpio/gpio-msc313.c | 15 ++++-----
drivers/gpio/gpio-tegra.c | 15 ++++-----
drivers/gpio/gpio-tegra186.c | 15 ++++-----
drivers/gpio/gpio-thunderx.c | 15 ++++-----
drivers/gpio/gpio-visconti.c | 15 ++++-----
drivers/gpio/gpiolib.c | 42 ++++++++++--------------
drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 15 ++++-----
include/linux/gpio/driver.h | 42 +++++++++++-------------
8 files changed, 73 insertions(+), 101 deletions(-)

diff --git a/drivers/gpio/gpio-msc313.c b/drivers/gpio/gpio-msc313.c
index b2c90bdd39d0..52d7b8d99170 100644
--- a/drivers/gpio/gpio-msc313.c
+++ b/drivers/gpio/gpio-msc313.c
@@ -550,15 +550,12 @@ static struct irq_chip msc313_gpio_irqchip = {
* so we need to provide the fwspec. Essentially gpiochip_populate_parent_fwspec_twocell
* that puts GIC_SPI into the first cell.
*/
-static void *msc313_gpio_populate_parent_fwspec(struct gpio_chip *gc,
- unsigned int parent_hwirq,
- unsigned int parent_type)
+static int msc313_gpio_populate_parent_fwspec(struct gpio_chip *gc,
+ union gpio_irq_fwspec *gfwspec,
+ unsigned int parent_hwirq,
+ unsigned int parent_type)
{
- struct irq_fwspec *fwspec;
-
- fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL);
- if (!fwspec)
- return NULL;
+ struct irq_fwspec *fwspec = &gfwspec->fwspec;

fwspec->fwnode = gc->irq.parent_domain->fwnode;
fwspec->param_count = 3;
@@ -566,7 +563,7 @@ static void *msc313_gpio_populate_parent_fwspec(struct gpio_chip *gc,
fwspec->param[1] = parent_hwirq;
fwspec->param[2] = parent_type;

- return fwspec;
+ return 0;
}

static int msc313e_gpio_child_to_parent_hwirq(struct gpio_chip *chip,
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c
index ff2d2a1f9c73..e4fb4cb38a0f 100644
--- a/drivers/gpio/gpio-tegra.c
+++ b/drivers/gpio/gpio-tegra.c
@@ -443,15 +443,12 @@ static int tegra_gpio_child_to_parent_hwirq(struct gpio_chip *chip,
return 0;
}

-static void *tegra_gpio_populate_parent_fwspec(struct gpio_chip *chip,
- unsigned int parent_hwirq,
- unsigned int parent_type)
+static int tegra_gpio_populate_parent_fwspec(struct gpio_chip *chip,
+ union gpio_irq_fwspec *gfwspec,
+ unsigned int parent_hwirq,
+ unsigned int parent_type)
{
- struct irq_fwspec *fwspec;
-
- fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL);
- if (!fwspec)
- return NULL;
+ struct irq_fwspec *fwspec = &gfwspec->fwspec;

fwspec->fwnode = chip->irq.parent_domain->fwnode;
fwspec->param_count = 3;
@@ -459,7 +456,7 @@ static void *tegra_gpio_populate_parent_fwspec(struct gpio_chip *chip,
fwspec->param[1] = parent_hwirq;
fwspec->param[2] = parent_type;

- return fwspec;
+ return 0;
}

#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/gpio/gpio-tegra186.c b/drivers/gpio/gpio-tegra186.c
index 84c4f1e9fb0c..9beb689cffbc 100644
--- a/drivers/gpio/gpio-tegra186.c
+++ b/drivers/gpio/gpio-tegra186.c
@@ -547,16 +547,13 @@ static int tegra186_gpio_irq_domain_translate(struct irq_domain *domain,
return 0;
}

-static void *tegra186_gpio_populate_parent_fwspec(struct gpio_chip *chip,
- unsigned int parent_hwirq,
- unsigned int parent_type)
+static int tegra186_gpio_populate_parent_fwspec(struct gpio_chip *chip,
+ union gpio_irq_fwspec *gfwspec,
+ unsigned int parent_hwirq,
+ unsigned int parent_type)
{
struct tegra_gpio *gpio = gpiochip_get_data(chip);
- struct irq_fwspec *fwspec;
-
- fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL);
- if (!fwspec)
- return NULL;
+ struct irq_fwspec *fwspec = &gfwspec->fwspec;

fwspec->fwnode = chip->irq.parent_domain->fwnode;
fwspec->param_count = 3;
@@ -564,7 +561,7 @@ static void *tegra186_gpio_populate_parent_fwspec(struct gpio_chip *chip,
fwspec->param[1] = parent_hwirq;
fwspec->param[2] = parent_type;

- return fwspec;
+ return 0;
}

static int tegra186_gpio_child_to_parent_hwirq(struct gpio_chip *chip,
diff --git a/drivers/gpio/gpio-thunderx.c b/drivers/gpio/gpio-thunderx.c
index 9f66deab46ea..e1dedbca0c85 100644
--- a/drivers/gpio/gpio-thunderx.c
+++ b/drivers/gpio/gpio-thunderx.c
@@ -408,18 +408,15 @@ static int thunderx_gpio_child_to_parent_hwirq(struct gpio_chip *gc,
return 0;
}

-static void *thunderx_gpio_populate_parent_alloc_info(struct gpio_chip *chip,
- unsigned int parent_hwirq,
- unsigned int parent_type)
+static int thunderx_gpio_populate_parent_alloc_info(struct gpio_chip *chip,
+ union gpio_irq_fwspec *gfwspec,
+ unsigned int parent_hwirq,
+ unsigned int parent_type)
{
- msi_alloc_info_t *info;
-
- info = kmalloc(sizeof(*info), GFP_KERNEL);
- if (!info)
- return NULL;
+ msi_alloc_info_t *info = &gfwspec->msiinfo;

info->hwirq = parent_hwirq;
- return info;
+ return 0;
}

static int thunderx_gpio_probe(struct pci_dev *pdev,
diff --git a/drivers/gpio/gpio-visconti.c b/drivers/gpio/gpio-visconti.c
index 47455810bdb9..1d281156ca2a 100644
--- a/drivers/gpio/gpio-visconti.c
+++ b/drivers/gpio/gpio-visconti.c
@@ -103,15 +103,12 @@ static int visconti_gpio_child_to_parent_hwirq(struct gpio_chip *gc,
return -EINVAL;
}

-static void *visconti_gpio_populate_parent_fwspec(struct gpio_chip *chip,
- unsigned int parent_hwirq,
- unsigned int parent_type)
+static int visconti_gpio_populate_parent_fwspec(struct gpio_chip *chip,
+ union gpio_irq_fwspec *gfwspec,
+ unsigned int parent_hwirq,
+ unsigned int parent_type)
{
- struct irq_fwspec *fwspec;
-
- fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL);
- if (!fwspec)
- return NULL;
+ struct irq_fwspec *fwspec = &gfwspec->fwspec;

fwspec->fwnode = chip->irq.parent_domain->fwnode;
fwspec->param_count = 3;
@@ -119,7 +116,7 @@ static void *visconti_gpio_populate_parent_fwspec(struct gpio_chip *chip,
fwspec->param[1] = parent_hwirq;
fwspec->param[2] = parent_type;

- return fwspec;
+ return 0;
}

static int visconti_gpio_probe(struct platform_device *pdev)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index c813a6adbb6e..ed26608fc93a 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1113,7 +1113,7 @@ static int gpiochip_hierarchy_irq_domain_alloc(struct irq_domain *d,
irq_hw_number_t hwirq;
unsigned int type = IRQ_TYPE_NONE;
struct irq_fwspec *fwspec = data;
- void *parent_arg;
+ union gpio_irq_fwspec gpio_parent_fwspec = {};
unsigned int parent_hwirq;
unsigned int parent_type;
struct gpio_irq_chip *girq = &gc->irq;
@@ -1153,14 +1153,15 @@ static int gpiochip_hierarchy_irq_domain_alloc(struct irq_domain *d,
irq_set_probe(irq);

/* This parent only handles asserted level IRQs */
- parent_arg = girq->populate_parent_alloc_arg(gc, parent_hwirq, parent_type);
- if (!parent_arg)
- return -ENOMEM;
+ ret = girq->populate_parent_alloc_arg(gc, &gpio_parent_fwspec,
+ parent_hwirq, parent_type);
+ if (ret)
+ return ret;

chip_dbg(gc, "alloc_irqs_parent for %d parent hwirq %d\n",
irq, parent_hwirq);
irq_set_lockdep_class(irq, gc->irq.lock_key, gc->irq.request_key);
- ret = irq_domain_alloc_irqs_parent(d, irq, 1, parent_arg);
+ ret = irq_domain_alloc_irqs_parent(d, irq, 1, &gpio_parent_fwspec);
/*
* If the parent irqdomain is msi, the interrupts have already
* been allocated, so the EEXIST is good.
@@ -1172,7 +1173,6 @@ static int gpiochip_hierarchy_irq_domain_alloc(struct irq_domain *d,
"failed to allocate parent hwirq %d for hwirq %lu\n",
parent_hwirq, hwirq);

- kfree(parent_arg);
return ret;
}

@@ -1236,34 +1236,28 @@ static bool gpiochip_hierarchy_is_hierarchical(struct gpio_chip *gc)
return !!gc->irq.parent_domain;
}

-void *gpiochip_populate_parent_fwspec_twocell(struct gpio_chip *gc,
- unsigned int parent_hwirq,
- unsigned int parent_type)
+int gpiochip_populate_parent_fwspec_twocell(struct gpio_chip *gc,
+ union gpio_irq_fwspec *gfwspec,
+ unsigned int parent_hwirq,
+ unsigned int parent_type)
{
- struct irq_fwspec *fwspec;
-
- fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL);
- if (!fwspec)
- return NULL;
+ struct irq_fwspec *fwspec = &gfwspec->fwspec;

fwspec->fwnode = gc->irq.parent_domain->fwnode;
fwspec->param_count = 2;
fwspec->param[0] = parent_hwirq;
fwspec->param[1] = parent_type;

- return fwspec;
+ return 0;
}
EXPORT_SYMBOL_GPL(gpiochip_populate_parent_fwspec_twocell);

-void *gpiochip_populate_parent_fwspec_fourcell(struct gpio_chip *gc,
- unsigned int parent_hwirq,
- unsigned int parent_type)
+int gpiochip_populate_parent_fwspec_fourcell(struct gpio_chip *gc,
+ union gpio_irq_fwspec *gfwspec,
+ unsigned int parent_hwirq,
+ unsigned int parent_type)
{
- struct irq_fwspec *fwspec;
-
- fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL);
- if (!fwspec)
- return NULL;
+ struct irq_fwspec *fwspec = &gfwspec->fwspec;

fwspec->fwnode = gc->irq.parent_domain->fwnode;
fwspec->param_count = 4;
@@ -1272,7 +1266,7 @@ void *gpiochip_populate_parent_fwspec_fourcell(struct gpio_chip *gc,
fwspec->param[2] = 0;
fwspec->param[3] = parent_type;

- return fwspec;
+ return 0;
}
EXPORT_SYMBOL_GPL(gpiochip_populate_parent_fwspec_fourcell);

diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
index 4fbf8d3938ef..6d27d1b00ddf 100644
--- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
+++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
@@ -966,16 +966,13 @@ static int pmic_gpio_child_to_parent_hwirq(struct gpio_chip *chip,
return 0;
}

-static void *pmic_gpio_populate_parent_fwspec(struct gpio_chip *chip,
- unsigned int parent_hwirq,
- unsigned int parent_type)
+static int pmic_gpio_populate_parent_fwspec(struct gpio_chip *chip,
+ union gpio_irq_fwspec *gfwspec,
+ unsigned int parent_hwirq,
+ unsigned int parent_type)
{
struct pmic_gpio_state *state = gpiochip_get_data(chip);
- struct irq_fwspec *fwspec;
-
- fwspec = kzalloc(sizeof(*fwspec), GFP_KERNEL);
- if (!fwspec)
- return NULL;
+ struct irq_fwspec *fwspec = &gfwspec->fwspec;

fwspec->fwnode = chip->irq.parent_domain->fwnode;

@@ -985,7 +982,7 @@ static void *pmic_gpio_populate_parent_fwspec(struct gpio_chip *chip,
/* param[2] must be left as 0 */
fwspec->param[3] = parent_type;

- return fwspec;
+ return 0;
}

static int pmic_gpio_probe(struct platform_device *pdev)
diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
index cb689264f3e9..600b3af1320f 100644
--- a/include/linux/gpio/driver.h
+++ b/include/linux/gpio/driver.h
@@ -11,6 +11,8 @@
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinconf-generic.h>

+#include <asm/msi.h>
+
struct gpio_desc;
struct of_phandle_args;
struct device_node;
@@ -22,6 +24,13 @@ enum gpio_lookup_flags;

struct gpio_chip;

+union gpio_irq_fwspec {
+ struct irq_fwspec fwspec;
+#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
+ msi_alloc_info_t msiinfo;
+#endif
+};
+
#define GPIO_LINE_DIRECTION_IN 1
#define GPIO_LINE_DIRECTION_OUT 0

@@ -102,9 +111,10 @@ struct gpio_irq_chip {
* variant named &gpiochip_populate_parent_fwspec_fourcell is also
* available.
*/
- void *(*populate_parent_alloc_arg)(struct gpio_chip *gc,
- unsigned int parent_hwirq,
- unsigned int parent_type);
+ int (*populate_parent_alloc_arg)(struct gpio_chip *gc,
+ union gpio_irq_fwspec *fwspec,
+ unsigned int parent_hwirq,
+ unsigned int parent_type);

/**
* @child_offset_to_irq:
@@ -623,28 +633,14 @@ struct bgpio_pdata {

#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY

-void *gpiochip_populate_parent_fwspec_twocell(struct gpio_chip *gc,
+int gpiochip_populate_parent_fwspec_twocell(struct gpio_chip *gc,
+ union gpio_irq_fwspec *gfwspec,
+ unsigned int parent_hwirq,
+ unsigned int parent_type);
+int gpiochip_populate_parent_fwspec_fourcell(struct gpio_chip *gc,
+ union gpio_irq_fwspec *gfwspec,
unsigned int parent_hwirq,
unsigned int parent_type);
-void *gpiochip_populate_parent_fwspec_fourcell(struct gpio_chip *gc,
- unsigned int parent_hwirq,
- unsigned int parent_type);
-
-#else
-
-static inline void *gpiochip_populate_parent_fwspec_twocell(struct gpio_chip *gc,
- unsigned int parent_hwirq,
- unsigned int parent_type)
-{
- return NULL;
-}
-
-static inline void *gpiochip_populate_parent_fwspec_fourcell(struct gpio_chip *gc,
- unsigned int parent_hwirq,
- unsigned int parent_type)
-{
- return NULL;
-}

#endif /* CONFIG_IRQ_DOMAIN_HIERARCHY */

--
2.34.1



2022-05-14 01:52:42

by Daniel Palmer

[permalink] [raw]
Subject: Re: [PATCH] gpio: Remove dynamic allocation from populate_parent_alloc_arg()

Hi March,

On Fri, 13 May 2022 at 01:23, Marc Zyngier <[email protected]> wrote:
> diff --git a/drivers/gpio/gpio-msc313.c b/drivers/gpio/gpio-msc313.c
> index b2c90bdd39d0..52d7b8d99170 100644
> --- a/drivers/gpio/gpio-msc313.c
> +++ b/drivers/gpio/gpio-msc313.c
> @@ -550,15 +550,12 @@ static struct irq_chip msc313_gpio_irqchip = {
> * so we need to provide the fwspec. Essentially gpiochip_populate_parent_fwspec_twocell
> * that puts GIC_SPI into the first cell.
> */
> -static void *msc313_gpio_populate_parent_fwspec(struct gpio_chip *gc,
> - unsigned int parent_hwirq,
> - unsigned int parent_type)
> +static int msc313_gpio_populate_parent_fwspec(struct gpio_chip *gc,
> + union gpio_irq_fwspec *gfwspec,
> + unsigned int parent_hwirq,
> + unsigned int parent_type)
> {
> - struct irq_fwspec *fwspec;
> -
> - fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL);
> - if (!fwspec)
> - return NULL;
> + struct irq_fwspec *fwspec = &gfwspec->fwspec;
>
> fwspec->fwnode = gc->irq.parent_domain->fwnode;
> fwspec->param_count = 3;
> @@ -566,7 +563,7 @@ static void *msc313_gpio_populate_parent_fwspec(struct gpio_chip *gc,
> fwspec->param[1] = parent_hwirq;
> fwspec->param[2] = parent_type;
>
> - return fwspec;
> + return 0;
> }
>
> static int msc313e_gpio_child_to_parent_hwirq(struct gpio_chip *chip,

This bit looks fine to me. I will test it over the weekend.

Cheers,

Daniel

2022-05-14 04:15:42

by Linus Walleij

[permalink] [raw]
Subject: Re: [PATCH] gpio: Remove dynamic allocation from populate_parent_alloc_arg()

On Thu, May 12, 2022 at 6:23 PM Marc Zyngier <[email protected]> wrote:

> The gpiolib is unique in the way it uses intermediate fwspecs
> when feeding an interrupt specifier to the parent domain, as it
> relies on the populate_parent_alloc_arg() callback to perform
> a dynamic allocation.
>
> THis is pretty inefficient (we free the structure almost immediately),
> and the only reason this isn't a stack allocation is that our
> ThunderX friend uses MSIs rather than a FW-constructed structure.
>
> Let's solve it by providing a new type composed of the union
> of a struct irq_fwspec and a msi_info_t, which satisfies both
> requirements. This allows us to use a stack allocation, and we
> can move the handful of users to this new scheme.
>
> Also perform some additional cleanup, such as getting rid of the
> stub versions of the irq_domain_translate_*cell helpers, which
> are never used when CONFIG_IRQ_DOMAIN_HIERARCHY isn't selected.
>
> Tested on a Tegra186.
>
> Signed-off-by: Marc Zyngier <[email protected]>
> Cc: Daniel Palmer <[email protected]>
> Cc: Romain Perier <[email protected]>
> Cc: Linus Walleij <[email protected]>
> Cc: Bartosz Golaszewski <[email protected]>
> Cc: Thierry Reding <[email protected]>
> Cc: Jonathan Hunter <[email protected]>
> Cc: Robert Richter <[email protected]>
> Cc: Nobuhiro Iwamatsu <[email protected]>
> Cc: Andy Gross <[email protected]>
> Cc: Bjorn Andersson <[email protected]>

This looks very appetizing to me but:

drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 15 ++++-----

This seems to have some changes to
->populate_parent_alloc_arg not even in linux-next,
so I get confused, what are the prerequisites? (Probably
something I already reviewed, but...)

Also: don't you also need to fix something in
drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c?
the way I remember it it was quite similar to spmi-gpio
but I may be mistaken.

Yours,
Linus Walleij

2022-05-14 14:55:14

by Marc Zyngier

[permalink] [raw]
Subject: Re: [PATCH] gpio: Remove dynamic allocation from populate_parent_alloc_arg()

Hey Linus,

On Fri, 13 May 2022 22:24:40 +0100,
Linus Walleij <[email protected]> wrote:
>
> On Thu, May 12, 2022 at 6:23 PM Marc Zyngier <[email protected]> wrote:
>
> > The gpiolib is unique in the way it uses intermediate fwspecs
> > when feeding an interrupt specifier to the parent domain, as it
> > relies on the populate_parent_alloc_arg() callback to perform
> > a dynamic allocation.
> >
> > THis is pretty inefficient (we free the structure almost immediately),
> > and the only reason this isn't a stack allocation is that our
> > ThunderX friend uses MSIs rather than a FW-constructed structure.
> >
> > Let's solve it by providing a new type composed of the union
> > of a struct irq_fwspec and a msi_info_t, which satisfies both
> > requirements. This allows us to use a stack allocation, and we
> > can move the handful of users to this new scheme.
> >
> > Also perform some additional cleanup, such as getting rid of the
> > stub versions of the irq_domain_translate_*cell helpers, which
> > are never used when CONFIG_IRQ_DOMAIN_HIERARCHY isn't selected.
> >
> > Tested on a Tegra186.
> >
> > Signed-off-by: Marc Zyngier <[email protected]>
> > Cc: Daniel Palmer <[email protected]>
> > Cc: Romain Perier <[email protected]>
> > Cc: Linus Walleij <[email protected]>
> > Cc: Bartosz Golaszewski <[email protected]>
> > Cc: Thierry Reding <[email protected]>
> > Cc: Jonathan Hunter <[email protected]>
> > Cc: Robert Richter <[email protected]>
> > Cc: Nobuhiro Iwamatsu <[email protected]>
> > Cc: Andy Gross <[email protected]>
> > Cc: Bjorn Andersson <[email protected]>
>
> This looks very appetizing to me but:
>
> drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 15 ++++-----
>
> This seems to have some changes to
> ->populate_parent_alloc_arg not even in linux-next,
> so I get confused, what are the prerequisites? (Probably
> something I already reviewed, but...)

Odd. This patch is on top of irqchip-next, which is itself already in
-next (you got me worried and I just pulled everything to check).

> Also: don't you also need to fix something in
> drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c?
> the way I remember it it was quite similar to spmi-gpio
> but I may be mistaken.

No, this one is graceful enough to use
gpiochip_populate_parent_fwspec_twocell(), which is directly provided
by gpiolib and thus addressed directly by this patch. Same thing for
the spmi-mpp version, which uses the fourcell variant.

HTH,

M.

--
Without deviation from the norm, progress is not possible.

2022-05-16 00:50:50

by Linus Walleij

[permalink] [raw]
Subject: Re: [PATCH] gpio: Remove dynamic allocation from populate_parent_alloc_arg()

On Sat, May 14, 2022 at 12:36 PM Marc Zyngier <[email protected]> wrote:
> On Fri, 13 May 2022 22:24:40 +0100,
> Linus Walleij <[email protected]> wrote:
> >
> > On Thu, May 12, 2022 at 6:23 PM Marc Zyngier <[email protected]> wrote:
> >
> > > The gpiolib is unique in the way it uses intermediate fwspecs
> > > when feeding an interrupt specifier to the parent domain, as it
> > > relies on the populate_parent_alloc_arg() callback to perform
> > > a dynamic allocation.
> > >
> > > THis is pretty inefficient (we free the structure almost immediately),
> > > and the only reason this isn't a stack allocation is that our
> > > ThunderX friend uses MSIs rather than a FW-constructed structure.
> > >
> > > Let's solve it by providing a new type composed of the union
> > > of a struct irq_fwspec and a msi_info_t, which satisfies both
> > > requirements. This allows us to use a stack allocation, and we
> > > can move the handful of users to this new scheme.
> > >
> > > Also perform some additional cleanup, such as getting rid of the
> > > stub versions of the irq_domain_translate_*cell helpers, which
> > > are never used when CONFIG_IRQ_DOMAIN_HIERARCHY isn't selected.
> > >
> > > Tested on a Tegra186.
> > >
> > > Signed-off-by: Marc Zyngier <[email protected]>
> > > Cc: Daniel Palmer <[email protected]>
> > > Cc: Romain Perier <[email protected]>
> > > Cc: Linus Walleij <[email protected]>
> > > Cc: Bartosz Golaszewski <[email protected]>
> > > Cc: Thierry Reding <[email protected]>
> > > Cc: Jonathan Hunter <[email protected]>
> > > Cc: Robert Richter <[email protected]>
> > > Cc: Nobuhiro Iwamatsu <[email protected]>
> > > Cc: Andy Gross <[email protected]>
> > > Cc: Bjorn Andersson <[email protected]>
> >
> > This looks very appetizing to me but:
> >
> > drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 15 ++++-----
> >
> > This seems to have some changes to
> > ->populate_parent_alloc_arg not even in linux-next,
> > so I get confused, what are the prerequisites? (Probably
> > something I already reviewed, but...)
>
> Odd. This patch is on top of irqchip-next, which is itself already in
> -next (you got me worried and I just pulled everything to check).

I confused it with pinctrl-ssbi-gpio.c. Simple beginners mistake.
Reviewed-by: Linus Walleij <[email protected]>

Yours,
Linus Walleij