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
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
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ciju Rajan K <crajank@nvidia.com>
---
include/linux/interrupt.h | 13 ++++++
include/linux/irqdesc.h | 20 +++++++++
kernel/irq/manage.c | 4 ++
kernel/irq/spurious.c | 87 +++++++++++++++++++++++++++++++++++++++
4 files changed, 124 insertions(+)
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 266f2b39213a..9fbda5d08a8f 100644
--- 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>
/*
* These correspond to the IORESOURCE_IRQ_* defines in
@@ -139,6 +140,14 @@ struct irqaction {
struct proc_dir_entry *dir;
} ____cacheline_internodealigned_in_smp;
+/**
+ * irq_storm_cb_t - callback function type for interrupt storm detection
+ * @irq: interrupt number that is storming
+ * @freq: detected frequency (interrupts per second)
+ * @dev_id: device identifier passed during registration
+ */
+typedef void (*irq_storm_cb_t)(unsigned int irq, unsigned int freq, void *dev_id);
+
extern irqreturn_t no_action(int cpl, void *dev_id);
/*
@@ -331,6 +340,10 @@ extern int irq_force_affinity(unsigned int irq, const struct cpumask *cpumask);
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);
+
extern int __irq_apply_affinity_hint(unsigned int irq, const struct cpumask *m,
bool setaffinity);
diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index 17902861de76..d27f02371a6c 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -17,6 +17,9 @@ struct irq_desc;
struct irq_domain;
struct pt_regs;
+/* Forward declaration - full definition in interrupt.h */
+typedef void (*irq_storm_cb_t)(unsigned int, unsigned int, void *);
+
/**
* struct irqstat - interrupt statistics
* @cnt: real-time interrupt count
@@ -29,6 +32,22 @@ struct irqstat {
#endif
};
+/**
+ * struct irq_storm - interrupt storm detection data
+ * @max_cnt: maximum interrupt count per time window
+ * @last_cnt: last total interrupt count snapshot
+ * @next_period: next time period boundary (jiffies)
+ * @cb: callback function to invoke on storm detection
+ * @dev_id: device identifier for callback
+ */
+struct irq_storm {
+ unsigned long max_cnt;
+ unsigned long last_cnt;
+ unsigned long next_period;
+ irq_storm_cb_t cb;
+ void *dev_id;
+};
+
/**
* struct irq_desc - interrupt descriptor
* @irq_common_data: per irq and chip data passed down to chip functions
@@ -101,6 +120,7 @@ struct irq_desc {
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *dir;
#endif
+ struct irq_storm *irq_storm;
#ifdef CONFIG_GENERIC_IRQ_DEBUGFS
struct dentry *debugfs_file;
const char *dev_name;
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 349ae7979da0..d413bf11ffde 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -1951,6 +1951,10 @@ 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) {
+ kfree(desc->irq_storm);
+ desc->irq_storm = NULL;
+ }
}
mutex_unlock(&desc->request_mutex);
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
index 73280ccb74b0..525dc0e384f1 100644
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -22,6 +22,90 @@ static DEFINE_TIMER(poll_spurious_irq_timer, poll_spurious_irqs);
int irq_poll_cpu;
static atomic_t irq_poll_active;
+/* Minimum frequency threshold */
+#define IRQ_STORM_MIN_FREQ_HZ 50
+#define IRQ_STORM_MAX_FREQ_SCALE (IRQ_STORM_MIN_FREQ_HZ * 2)
+/* Time window over which storm check is performed */
+#define IRQ_STORM_PERIOD_WINDOW_MS (IRQ_STORM_MIN_FREQ_HZ * 20)
+
+
+/**
+ * irq_register_storm_detection - register interrupt storm detection for an IRQ
+ * @irq: interrupt number
+ * @max_freq: maximum allowed frequency (interrupts per second)
+ * @cb: callback function to invoke when storm is detected
+ * @dev_id: device identifier passed to callback
+ *
+ * Returns: true on success, false on failure
+ */
+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;
+}
+EXPORT_SYMBOL_GPL(irq_register_storm_detection);
+
+/**
+ * irq_unregister_storm_detection - unregister interrupt storm detection
+ * @irq: interrupt number
+ */
+void irq_unregister_storm_detection(unsigned int irq)
+{
+ scoped_irqdesc_get_and_buslock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
+ if (scoped_irqdesc->irq_storm) {
+ kfree(scoped_irqdesc->irq_storm);
+ scoped_irqdesc->irq_storm = NULL;
+ }
+ }
+}
+EXPORT_SYMBOL_GPL(irq_unregister_storm_detection);
+
+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);
+ 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);
+ }
+}
+
/*
* Recovery handler for misrouted interrupts.
*/
@@ -231,6 +315,9 @@ void note_interrupt(struct irq_desc *desc, irqreturn_t action_ret)
return;
}
+ if (desc->irq_storm && action_ret == IRQ_HANDLED)
+ irq_storm_check(desc);
+
/*
* We cannot call note_interrupt from the threaded handler
* because we need to look at the compound of all handlers
--
2.47.3
Hi Ciju,
kernel test robot noticed the following build warnings:
[auto build test WARNING on linus/master]
[also build test WARNING on v6.19-rc5]
[cannot apply to tip/irq/core next-20260115]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Ciju-Rajan-K/kernel-irq-Add-generic-interrupt-storm-detection-mechanism/20260115-155438
base: linus/master
patch link: https://lore.kernel.org/r/20260115074909.245852-2-crajank%40nvidia.com
patch subject: [PATCH platform-next v4 1/2] kernel/irq: Add generic interrupt storm detection mechanism
config: arm-allnoconfig (https://download.01.org/0day-ci/archive/20260115/202601152104.pBPeNPHR-lkp@intel.com/config)
compiler: clang version 22.0.0git (https://github.com/llvm/llvm-project 9b8addffa70cee5b2acc5454712d9cf78ce45710)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260115/202601152104.pBPeNPHR-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202601152104.pBPeNPHR-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> kernel/irq/spurious.c:41:6: warning: no previous prototype for function 'irq_register_storm_detection' [-Wmissing-prototypes]
41 | bool irq_register_storm_detection(unsigned int irq, unsigned int max_freq,
| ^
kernel/irq/spurious.c:41:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
41 | bool irq_register_storm_detection(unsigned int irq, unsigned int max_freq,
| ^
| static
>> kernel/irq/spurious.c:79:6: warning: no previous prototype for function 'irq_unregister_storm_detection' [-Wmissing-prototypes]
79 | void irq_unregister_storm_detection(unsigned int irq)
| ^
kernel/irq/spurious.c:79:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
79 | void irq_unregister_storm_detection(unsigned int irq)
| ^
| static
2 warnings generated.
vim +/irq_register_storm_detection +41 kernel/irq/spurious.c
30
31
32 /**
33 * irq_register_storm_detection - register interrupt storm detection for an IRQ
34 * @irq: interrupt number
35 * @max_freq: maximum allowed frequency (interrupts per second)
36 * @cb: callback function to invoke when storm is detected
37 * @dev_id: device identifier passed to callback
38 *
39 * Returns: true on success, false on failure
40 */
> 41 bool irq_register_storm_detection(unsigned int irq, unsigned int max_freq,
42 irq_storm_cb_t cb, void *dev_id)
43 {
44 struct irq_storm *storm;
45 bool ret = false;
46
47 if (max_freq < IRQ_STORM_MIN_FREQ_HZ || !cb)
48 return false;
49
50 storm = kzalloc(sizeof(*storm), GFP_KERNEL);
51 if (!storm)
52 return false;
53
54 /* Adjust to count per 10ms */
55 storm->max_cnt = max_freq / (IRQ_STORM_MAX_FREQ_SCALE);
56 storm->cb = cb;
57 storm->dev_id = dev_id;
58
59 scoped_irqdesc_get_and_buslock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
60 if (scoped_irqdesc->action && !scoped_irqdesc->irq_storm) {
61 storm->last_cnt = scoped_irqdesc->tot_count;
62 storm->next_period = jiffies + msecs_to_jiffies(IRQ_STORM_PERIOD_WINDOW_MS);
63 scoped_irqdesc->irq_storm = storm;
64 ret = true;
65 }
66 }
67
68 if (!ret)
69 kfree(storm);
70
71 return ret;
72 }
73 EXPORT_SYMBOL_GPL(irq_register_storm_detection);
74
75 /**
76 * irq_unregister_storm_detection - unregister interrupt storm detection
77 * @irq: interrupt number
78 */
> 79 void irq_unregister_storm_detection(unsigned int irq)
80 {
81 scoped_irqdesc_get_and_buslock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
82 if (scoped_irqdesc->irq_storm) {
83 kfree(scoped_irqdesc->irq_storm);
84 scoped_irqdesc->irq_storm = NULL;
85 }
86 }
87 }
88 EXPORT_SYMBOL_GPL(irq_unregister_storm_detection);
89
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Hi Ciju,
kernel test robot noticed the following build warnings:
[auto build test WARNING on linus/master]
[also build test WARNING on v6.19-rc5]
[cannot apply to tip/irq/core next-20260115]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Ciju-Rajan-K/kernel-irq-Add-generic-interrupt-storm-detection-mechanism/20260115-155438
base: linus/master
patch link: https://lore.kernel.org/r/20260115074909.245852-2-crajank%40nvidia.com
patch subject: [PATCH platform-next v4 1/2] kernel/irq: Add generic interrupt storm detection mechanism
config: arc-allnoconfig (https://download.01.org/0day-ci/archive/20260115/202601152136.LGHBo3k1-lkp@intel.com/config)
compiler: arc-linux-gcc (GCC) 15.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260115/202601152136.LGHBo3k1-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202601152136.LGHBo3k1-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> kernel/irq/spurious.c:41:6: warning: no previous prototype for 'irq_register_storm_detection' [-Wmissing-prototypes]
41 | bool irq_register_storm_detection(unsigned int irq, unsigned int max_freq,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> kernel/irq/spurious.c:79:6: warning: no previous prototype for 'irq_unregister_storm_detection' [-Wmissing-prototypes]
79 | void irq_unregister_storm_detection(unsigned int irq)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
vim +/irq_register_storm_detection +41 kernel/irq/spurious.c
30
31
32 /**
33 * irq_register_storm_detection - register interrupt storm detection for an IRQ
34 * @irq: interrupt number
35 * @max_freq: maximum allowed frequency (interrupts per second)
36 * @cb: callback function to invoke when storm is detected
37 * @dev_id: device identifier passed to callback
38 *
39 * Returns: true on success, false on failure
40 */
> 41 bool irq_register_storm_detection(unsigned int irq, unsigned int max_freq,
42 irq_storm_cb_t cb, void *dev_id)
43 {
44 struct irq_storm *storm;
45 bool ret = false;
46
47 if (max_freq < IRQ_STORM_MIN_FREQ_HZ || !cb)
48 return false;
49
50 storm = kzalloc(sizeof(*storm), GFP_KERNEL);
51 if (!storm)
52 return false;
53
54 /* Adjust to count per 10ms */
55 storm->max_cnt = max_freq / (IRQ_STORM_MAX_FREQ_SCALE);
56 storm->cb = cb;
57 storm->dev_id = dev_id;
58
59 scoped_irqdesc_get_and_buslock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
60 if (scoped_irqdesc->action && !scoped_irqdesc->irq_storm) {
61 storm->last_cnt = scoped_irqdesc->tot_count;
62 storm->next_period = jiffies + msecs_to_jiffies(IRQ_STORM_PERIOD_WINDOW_MS);
63 scoped_irqdesc->irq_storm = storm;
64 ret = true;
65 }
66 }
67
68 if (!ret)
69 kfree(storm);
70
71 return ret;
72 }
73 EXPORT_SYMBOL_GPL(irq_register_storm_detection);
74
75 /**
76 * irq_unregister_storm_detection - unregister interrupt storm detection
77 * @irq: interrupt number
78 */
> 79 void irq_unregister_storm_detection(unsigned int irq)
80 {
81 scoped_irqdesc_get_and_buslock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
82 if (scoped_irqdesc->irq_storm) {
83 kfree(scoped_irqdesc->irq_storm);
84 scoped_irqdesc->irq_storm = NULL;
85 }
86 }
87 }
88 EXPORT_SYMBOL_GPL(irq_unregister_storm_detection);
89
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
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
© 2016 - 2026 Red Hat, Inc.