linux-tegra.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Thomas Gleixner <tglx@linutronix.de>
To: Marc Zyngier <maz@kernel.org>,
	linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org
Cc: Thierry Reding <thierry.reding@gmail.com>,
	Jonathan Hunter <jonathanh@nvidia.com>,
	Dmitry Osipenko <digetx@gmail.com>,
	Sowjanya Komatineni <skomatineni@nvidia.com>,
	Venkat Reddy Talla <vreddytalla@nvidia.com>,
	kernel-team@android.com
Subject: Re: [PATCH v3 1/4] genirq/irqdomain: Allow partial trimming of irq_data hierarchy
Date: Thu, 08 Oct 2020 13:22:35 +0200	[thread overview]
Message-ID: <87d01t2c90.fsf@nanos.tec.linutronix.de> (raw)
In-Reply-To: <20201007124544.1397322-2-maz@kernel.org>

On Wed, Oct 07 2020 at 13:45, Marc Zyngier wrote:
> +/**
> + * irq_domain_trim_hierarchy - Trim the uninitialized part of a irq hierarchy
> + * @virq:	IRQ number to trim where the hierarchy is to be trimmed
> + *
> + * Drop the partial irq_data hierarchy from the level where the
> + * irq_data->chip is NULL.
> + *
> + * Its only use is to be able to trim levels of hierarchy that do not
> + * have any real meaning for this interrupt, and that the driver leaves
> + * uninitialized in its .alloc() callback.
> + */
> +static void irq_domain_trim_hierarchy(unsigned int virq)
> +{
> +	struct irq_data *tail, *irq_data = irq_get_irq_data(virq);
> +
> +	/* It really needs to be a hierarchy, and not a single entry */
> +	if (!irq_data->parent_data)
> +		return;
> +
> +	/* Skip until we find a parent irq_data without a populated chip */
> +	while (irq_data->parent_data && irq_data->parent_data->chip)
> +		irq_data = irq_data->parent_data;
> +
> +	/* All levels populated */
> +	if (!irq_data->parent_data)
> +		return;
> +
> +	pr_info("IRQ%d: trimming hierarchy from %s\n",
> +		virq, irq_data->parent_data->domain->name);
> +
> +	/* Sever the inner part of the hierarchy...  */
> +	tail = irq_data->parent_data;
> +	irq_data->parent_data = NULL;
> +	__irq_domain_free_hierarchy(tail);
> +}

I like that way more than the previous version, but there are still
quite some dangeroos waiting to bite.

Just for robustness sake we should do the following:

 Let the alloc() callback which decides to break the hierarchy tell the
 core code about it.  Conveying this through an error return might be
 tedious, but the alloc() callback should call:

static inline void irq_disconnect_hierarchy(struct irq_data *irqd)
{
    irqd->chip = ERR_PTR(-ENOTCONN);
}

to signal that this is intenionally the end of the hierarchy.

Then the above function would not only trim, but also sanity check the
hierarchy.

	trim = NULL;
        
        for (irqd = irq_data; irqd; irqd = irqd->parent_data) {
                  if (!irqd->chip && !trim)
                  	return -EINVAL;

		  if (trim && irqd->chip)
                  	return -EINVAL;
                 
                  if (IS_ERR(irqd->chip) {
                  	if (PTR_ERR(irqd->chip) != -ENOTCONN)
                        	return -EINVAL;
                        trim = irqd;
                  }
        }

        for (irqd = irq_data; trim && irqd; irqd = irqd->parent_data) {
        	if (trim == irqd->parent_data) {
                	irqd->parent_data = NULL;
                        free_stuff(trim);
                }
        }

	return 0;

or some less convoluted variant of it :)

That way we catch cases which do outright stupid crap and we let the
allocation fail which needs to be handled at the outmost caller anyway
instead of crashing later in the middle of the irq chip chain.

Thanks,

        tglx

  reply	other threads:[~2020-10-08 11:22 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-07 12:45 [PATCH v3 0/4] soc/tegra: Prevent the PMC driver from corrupting interrupt routing Marc Zyngier
2020-10-07 12:45 ` [PATCH v3 1/4] genirq/irqdomain: Allow partial trimming of irq_data hierarchy Marc Zyngier
2020-10-08 11:22   ` Thomas Gleixner [this message]
2020-10-08 13:06     ` Marc Zyngier
2020-10-08 20:47       ` Thomas Gleixner
2020-10-10  9:42         ` Marc Zyngier
2020-10-07 12:45 ` [PATCH v3 2/4] gpio: tegra186: Allow optional irq parent callbacks Marc Zyngier
2020-10-07 12:45 ` [PATCH v3 3/4] soc/tegra: pmc: " Marc Zyngier
2020-10-07 12:45 ` [PATCH v3 4/4] soc/tegra: pmc: Don't create fake interrupt hierarchy levels Marc Zyngier

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=87d01t2c90.fsf@nanos.tec.linutronix.de \
    --to=tglx@linutronix.de \
    --cc=digetx@gmail.com \
    --cc=jonathanh@nvidia.com \
    --cc=kernel-team@android.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tegra@vger.kernel.org \
    --cc=maz@kernel.org \
    --cc=skomatineni@nvidia.com \
    --cc=thierry.reding@gmail.com \
    --cc=vreddytalla@nvidia.com \
    /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;
as well as URLs for NNTP newsgroup(s).