[PATCH v4 13/21] mm/ksw: manage probe and HWBP lifecycle via procfs

Jinchao Wang
2025-09-12T10:13:03Z

Allow dynamic enabling/disabling of kstackwatch through user input of proc.
With this patch, the entire system becomes functional.

Signed-off-by: Jinchao Wang <wangjinchao600@gmail.com>
---
mm/kstackwatch/kernel.c | 55 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 54 insertions(+), 1 deletion(-)

diff --git a/mm/kstackwatch/kernel.c b/mm/kstackwatch/kernel.c
index 8e1dca45003e..9ef969f28e29 100644
--- a/mm/kstackwatch/kernel.c
+++ b/mm/kstackwatch/kernel.c
@@ -17,6 +17,43 @@ MODULE_LICENSE("GPL");
static struct ksw_config *ksw_config;
static atomic_t config_file_busy = ATOMIC_INIT(0);

+static bool watching_active;
+
+static int ksw_start_watching(void)
+{
+ int ret;
+
+ /*
+ * Watch init will preallocate the HWBP,
+ * so it must happen before stack init
+ */
+ ret = ksw_watch_init();
+ if (ret) {
+ pr_err("ksw_watch_init ret: %d\n", ret);
+ return ret;
+ }
+
+ ret = ksw_stack_init();
+ if (ret) {
+ pr_err("ksw_stack_init ret: %d\n", ret);
+ ksw_watch_exit();
+ return ret;
+ }
+ watching_active = true;
+
+ pr_info("start watching: %s\n", ksw_config->config_str);
+ return 0;
+}
+
+static void ksw_stop_watching(void)
+{
+ ksw_stack_exit();
+ ksw_watch_exit();
+ watching_active = false;
+
+ pr_info("stop watching: %s\n", ksw_config->config_str);
+}
+
/*
* Format of the configuration string:
* function+ip_offset[+depth] [local_var_offset:local_var_len]
@@ -109,6 +146,9 @@ static ssize_t kstackwatch_proc_write(struct file *file,
if (copy_from_user(input, buffer, count))
return -EFAULT;

+ if (watching_active)
+ ksw_stop_watching();
+
input[count] = '\0';
strim(input);

@@ -123,12 +163,22 @@ static ssize_t kstackwatch_proc_write(struct file *file,
return ret;
}

+ ret = ksw_start_watching();
+ if (ret) {
+ pr_err("Failed to start watching with %d\n", ret);
+ return ret;
+ }
+
return count;
}

static int kstackwatch_proc_show(struct seq_file *m, void *v)
{
- seq_printf(m, "%s\n", ksw_config->config_str);
+ if (watching_active)
+ seq_printf(m, "%s\n", ksw_config->config_str);
+ else
+ seq_puts(m, "not watching\n");
+
return 0;
}

@@ -176,6 +226,9 @@ static int __init kstackwatch_init(void)

static void __exit kstackwatch_exit(void)
{
+ if (watching_active)
+ ksw_stop_watching();
+
remove_proc_entry("kstackwatch", NULL);
kfree(ksw_config);

--
2.43.0