The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
To: Ciju Rajan K <crajank@nvidia.com>
Cc: hdegoede@redhat.com, ilpo.jarvinen@linux.intel.com,
	tglx@linutronix.de, christophe.jaillet@wanadoo.fr,
	vadimp@nvidia.com, platform-driver-x86@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH platform-next v4 1/2] kernel/irq: Add generic interrupt storm detection mechanism
Date: Thu, 15 Jan 2026 10:29:14 +0200	[thread overview]
Message-ID: <aWilWsTaAZeH8x1x@smile.fi.intel.com> (raw)
In-Reply-To: <20260115074909.245852-2-crajank@nvidia.com>

On Thu, Jan 15, 2026 at 09:49:08AM +0200, Ciju Rajan K wrote:
> If the hardware is broken, it is possible that faulty device will
> flood interrupt handler with false events. For example, if fan or
> power supply has damaged presence pin, it will cause permanent

I would say "has a floating presence pin" as the term floating is
well established and describes the case exactly how you put it further
in the text.

> generation of plugged in / plugged out events. As a result, interrupt
> handler will consume a lot of CPU resources and will keep raising
> "UDEV" events to the user space.
> 
> This patch provides a mechanism for detecting interrupt storm.
> Use the following criteria: if the specific interrupt was generated
> 'N' times during 'T' seconds, such device is to be considered as
> broken and user will be notified through a call back function.
> This feature can be used by any kernel subsystems or drivers.
> 
> The implementation includes:
> 
> - irq_storm_cb_t: Callback function type for storm notifications
> - struct irq_storm: Per-IRQ storm detection data structure
> - irq_register_storm_detection(): Register storm detection with
> 				  configurable parameters
> - irq_unregister_storm_detection(): Unregister storm detection
> - Integration with note_interrupt() for automatic storm checking
> 
> Callback API parameters:
> - irq: interrupt number to monitor
> - max_freq: maximum allowed frequency (interrupts per second)
> - dev_id: device identifier passed to callback

...

> --- a/include/linux/interrupt.h
> +++ b/include/linux/interrupt.h
> @@ -20,6 +20,7 @@
>  #include <asm/ptrace.h>
>  #include <asm/irq.h>
>  #include <asm/sections.h>
> +#include <linux/jiffies.h>

I would not mix linux/* group with asm/* group and to me the best location for
this inclusion is just before kref.h. Note, this header needs a bit more of
a cleanup, as it includes basically everything (due to kernel.h and maybe other
messed up headers). But this is out of scope of your series.

...

>  extern int irq_can_set_affinity(unsigned int irq);
>  extern int irq_select_affinity(unsigned int irq);

> +extern bool irq_register_storm_detection(unsigned int irq, unsigned int max_freq,
> +					 irq_storm_cb_t cb, void *dev_id);
> +extern void irq_unregister_storm_detection(unsigned int irq);

Do we still need "extern" keyword?

>  extern int __irq_apply_affinity_hint(unsigned int irq, const struct cpumask *m,
>  				     bool setaffinity);

...

> +struct irq_storm {
> +	unsigned long		max_cnt;
> +	unsigned long		last_cnt;
> +	unsigned long		next_period;
> +	irq_storm_cb_t		cb;
> +	void			*dev_id;
> +};

I'm wondering if you have tried to shuffle this layout based on the frequency
of a use of each member. In some cases it might generate less code (can be
measured with bloat-o-meter).

...

> static struct irqaction *__free_irq(struct irq_desc *desc, void *dev_id)

>  		irq_release_resources(desc);
>  		chip_bus_sync_unlock(desc);
>  		irq_remove_timings(desc);

> +		if (desc->irq_storm) {

Unneeded (duplicate) check.

> +			kfree(desc->irq_storm);

> +			desc->irq_storm = NULL;

Do we need this? If so, still can be done unconditionally.

> +		}
>  	}

> +/* Minimum frequency threshold */
> +#define IRQ_STORM_MIN_FREQ_HZ		50
> +#define IRQ_STORM_MAX_FREQ_SCALE	(IRQ_STORM_MIN_FREQ_HZ * 2)

Plain numbers are easier to read, hence 100

> +/* Time window over which storm check is performed */
> +#define IRQ_STORM_PERIOD_WINDOW_MS	(IRQ_STORM_MIN_FREQ_HZ * 20)

MS = HZ?! It's from some other universe with different physics laws.

...

> + * Returns: true on success, false on failure

Are the rest use "Returns" (with "s")? Because the main keyword is "Return".
(Yes, "Returns" works, but it's a secondary one, not even documented IIRC.)

...

> +bool irq_register_storm_detection(unsigned int irq, unsigned int max_freq,
> +				  irq_storm_cb_t cb, void *dev_id)
> +{
> +	struct irq_storm *storm;
> +	bool ret = false;
> +
> +	if (max_freq < IRQ_STORM_MIN_FREQ_HZ || !cb)
> +		return false;
> +
> +	storm = kzalloc(sizeof(*storm), GFP_KERNEL);
> +	if (!storm)
> +		return false;
> +
> +	/* Adjust to count per 10ms */
> +	storm->max_cnt = max_freq / (IRQ_STORM_MAX_FREQ_SCALE);
> +	storm->cb = cb;
> +	storm->dev_id = dev_id;
> +
> +	scoped_irqdesc_get_and_buslock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
> +		if (scoped_irqdesc->action && !scoped_irqdesc->irq_storm) {
> +			storm->last_cnt = scoped_irqdesc->tot_count;
> +			storm->next_period = jiffies + msecs_to_jiffies(IRQ_STORM_PERIOD_WINDOW_MS);
> +			scoped_irqdesc->irq_storm = storm;
> +			ret = true;
> +		}
> +	}

> +	if (!ret)
> +		kfree(storm);
> +
> +	return ret;

Better to avoid negative conditionals in such contexts.

	if (ret)
		return ret;

	kfree(...);

But it's boolean and assigned inside scoped section. Why we can't return true
directly from scoped section?

> +}

...

> +void irq_unregister_storm_detection(unsigned int irq)
> +{
> +	scoped_irqdesc_get_and_buslock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {

> +		if (scoped_irqdesc->irq_storm) {

Dup check, drop it.

> +			kfree(scoped_irqdesc->irq_storm);
> +			scoped_irqdesc->irq_storm = NULL;
> +		}
> +	}
> +}

...

> +static void irq_storm_check(struct irq_desc *desc)
> +{
> +	struct irq_storm *storm = desc->irq_storm;
> +	unsigned long delta, now = jiffies;
> +
> +	if (!time_after_eq(now, storm->next_period))
> +		return;

> +	storm->next_period = now + msecs_to_jiffies(IRQ_STORM_PERIOD_WINDOW_MS);

Just do

#define IRQ_STORM_PERIOD_WINDOW		msecs_to_jiffies(1000)

It will address my above comment and make this be read better.

> +	delta = desc->tot_count - storm->last_cnt;
> +	storm->last_cnt = desc->tot_count;
> +	if (delta > storm->max_cnt) {
> +		/* Calculate actual frequency: interrupts per second */
> +		storm->cb(irq_desc_get_irq(desc),
> +			(delta * (IRQ_STORM_MAX_FREQ_SCALE)),
> +			storm->dev_id);
> +	}
> +}


-- 
With Best Regards,
Andy Shevchenko



  reply	other threads:[~2026-01-15  8:29 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-15  7:49 [PATCH platform-next v4 0/2] Interrupt storm detection Ciju Rajan K
2026-01-15  7:49 ` [PATCH platform-next v4 1/2] kernel/irq: Add generic interrupt storm detection mechanism Ciju Rajan K
2026-01-15  8:29   ` Andy Shevchenko [this message]
2026-01-15 14:00   ` kernel test robot
2026-01-15 14:11   ` kernel test robot
2026-01-15  7:49 ` [PATCH platform-next v4 2/2] platform/mellanox: mlxreg-hotplug: Enabling interrupt storm detection Ciju Rajan K
2026-01-15  8:34   ` Andy Shevchenko
2026-01-15 14:43   ` kernel test robot

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=aWilWsTaAZeH8x1x@smile.fi.intel.com \
    --to=andriy.shevchenko@linux.intel.com \
    --cc=christophe.jaillet@wanadoo.fr \
    --cc=crajank@nvidia.com \
    --cc=hdegoede@redhat.com \
    --cc=ilpo.jarvinen@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=platform-driver-x86@vger.kernel.org \
    --cc=tglx@linutronix.de \
    --cc=vadimp@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