[PATCH v5 18/24] virt/steal_monitor: Compute work at regular intervals
From: Shrikanth Hegde
Date: Thu Jun 25 2026 - 08:56:49 EST
Trigger periodic work at intervals specified in interval_ms.
schedule_delayed_work is chosen since this work need not happen at this
instant and this variant is safe w.r.t to CPU hotplug.
Reset the interval_ms to default if one sets it to 0 to avoid workqueue
stalls.
Signed-off-by: Shrikanth Hegde <sshegde@xxxxxxxxxxxxx>
---
v4->v5:
- Modified for steal_monitor
drivers/virt/steal_monitor/sm_core.c | 26 +++++++++++++++++++++++++-
drivers/virt/steal_monitor/sm_core.h | 2 ++
2 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/drivers/virt/steal_monitor/sm_core.c b/drivers/virt/steal_monitor/sm_core.c
index b95b37e37a16..fac8f4d5dac7 100644
--- a/drivers/virt/steal_monitor/sm_core.c
+++ b/drivers/virt/steal_monitor/sm_core.c
@@ -32,15 +32,39 @@ module_param_named(low_threshold, sm_core_ctx.low_threshold, uint, 0644);
MODULE_PARM_DESC(low_threshold,
"Low steal threshold (default: 200 i.e 2%)");
+static void compute_preferred_cpus_work(struct work_struct *work)
+{
+ /* At least one core is kept as preferred */
+ WARN_ON(cpumask_empty(cpu_preferred_mask));
+
+ /* Warn if interval_ms is set to 0, that might cause lockup. */
+ if (unlikely(sm_core_ctx.interval_ms == 0)) {
+ WARN_ON(1);
+ sm_core_ctx.interval_ms = 1000; /* Fallback to default */
+ }
+
+ /* Trigger for next sampling */
+ schedule_delayed_work(&sm_core_ctx.work,
+ msecs_to_jiffies(sm_core_ctx.interval_ms));
+}
+
static int __init steal_monitor_init(void)
{
- pr_info("steal_monitor is enabled\n");
+ pr_info("steal_monitor is enabled. interval: %ums, high_threshold: %u, low_threshold: %u\n",
+ sm_core_ctx.interval_ms, sm_core_ctx.high_threshold, sm_core_ctx.low_threshold);
+
+ INIT_DELAYED_WORK(&sm_core_ctx.work, compute_preferred_cpus_work);
+
+ schedule_delayed_work(&sm_core_ctx.work,
+ msecs_to_jiffies(sm_core_ctx.interval_ms));
+
return 0;
}
static void __exit steal_monitor_exit(void)
{
pr_info("steal_monitor is disabled\n");
+ cancel_delayed_work_sync(&sm_core_ctx.work);
cpumask_copy(&__cpu_preferred_mask, cpu_active_mask);
}
diff --git a/drivers/virt/steal_monitor/sm_core.h b/drivers/virt/steal_monitor/sm_core.h
index a4e813319680..d50138ad8c42 100644
--- a/drivers/virt/steal_monitor/sm_core.h
+++ b/drivers/virt/steal_monitor/sm_core.h
@@ -7,6 +7,8 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/cpumask.h>
+#include <linux/workqueue.h>
struct steal_monitor {
struct delayed_work work;
--
2.47.3