linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Jinchao Wang <wangjinchao600@gmail.com>
To: akpm@linux-foundation.org
Cc: mhiramat@kernel.org, naveen@kernel.org, davem@davemloft.net,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org,
	linux-trace-kernel@vger.kernel.org,
	Jinchao Wang <wangjinchao600@gmail.com>
Subject: [RFC PATCH 10/13] mm/kstackwatch: Handle nested function calls
Date: Mon, 18 Aug 2025 20:26:15 +0800	[thread overview]
Message-ID: <20250818122720.434981-11-wangjinchao600@gmail.com> (raw)
In-Reply-To: <20250818122720.434981-10-wangjinchao600@gmail.com>

This patch adds support for watching specific depths of nested function calls.
The Kernel Stack Watch tool currently watchs the first entry of a probed
function, but this is insufficient for functions that are called recursively or
that call themselves indirectly.

To address this, a per-CPU variable `monitor_depth` is introduced to track
the nesting level of the function being watched. When a function's entry
handler is triggered, the depth is incremented, and the tool only arms the
hardware breakpoint if the current depth matches the configured `depth`.
The exit handler decrements the depth, disarming the breakpoint on the
correct return.

This ensures the watch mechanism only activates at the desired nesting level,
making the tool more precise and versatile for debugging complex stack issues.

Signed-off-by: Jinchao Wang <wangjinchao600@gmail.com>
---
 mm/kstackwatch/stack.c | 36 ++++++++++++++++++++++++++++++++++--
 1 file changed, 34 insertions(+), 2 deletions(-)

diff --git a/mm/kstackwatch/stack.c b/mm/kstackwatch/stack.c
index ba5280787e8f..86847c2e4506 100644
--- a/mm/kstackwatch/stack.c
+++ b/mm/kstackwatch/stack.c
@@ -6,6 +6,8 @@
 
 #include "kstackwatch.h"
 
+/* Per-CPU watching state */
+static DEFINE_PER_CPU(int, monitor_depth);
 struct ksw_config *probe_config;
 
 /* Find canary address in current stack frame */
@@ -120,10 +122,22 @@ static struct kretprobe exit_probe;
 static void ksw_stack_entry_handler(struct kprobe *p, struct pt_regs *regs,
 				    unsigned long flags)
 {
+	int *depth, cur_depth;
 	int ret;
 	u64 watch_addr;
 	u64 watch_len;
 
+	/* Handle nested calls - only monitor outermost */
+	depth = this_cpu_ptr(&monitor_depth);
+	cur_depth = (*depth)++;
+
+	if (cur_depth != probe_config->depth) {
+		/* depth start from 0 */
+		pr_info("KSW: config_depth:%u cur_depth:%d skipping %s\n",
+			probe_config->depth, cur_depth, __func__);
+		return;
+	}
+
 	/* Setup breakpoints for all active watches */
 	ret = ksw_stack_prepare_watch(regs, probe_config, &watch_addr,
 				      &watch_len);
@@ -136,14 +150,25 @@ static void ksw_stack_entry_handler(struct kprobe *p, struct pt_regs *regs,
 		pr_err("KSW: Failed to arm hwbp: %d\n", ret);
 		return;
 	}
-	pr_info("KSW: Armed for %s at addr:0x%llx len:%llu\n",
-		probe_config->function, watch_addr, watch_len);
+	pr_info("KSW: Armed for %s at depth %d addr:0x%llx len:%llu\n",
+		probe_config->function, cur_depth, watch_addr, watch_len);
 }
 
 /* Function exit handler */
 static int ksw_stack_exit_handler(struct kretprobe_instance *ri,
 				  struct pt_regs *regs)
 {
+	int *depth, cur_depth;
+
+	depth = this_cpu_ptr(&monitor_depth);
+	cur_depth = --(*depth);
+	if (cur_depth != probe_config->depth) {
+		/* depth start from 0 */
+		pr_info("KSW: %s config depth:%u cur_depth:%d skipping\n",
+			__func__, probe_config->depth, cur_depth);
+		return 0;
+	}
+
 	ksw_watch_off();
 	pr_info("KSW: Disarmed for %s\n", probe_config->function);
 
@@ -153,6 +178,13 @@ static int ksw_stack_exit_handler(struct kretprobe_instance *ri,
 int ksw_stack_init(struct ksw_config *config)
 {
 	int ret;
+	int cpu;
+	int *depth;
+
+	for_each_possible_cpu(cpu) {
+		depth = per_cpu_ptr(&monitor_depth, cpu);
+		WRITE_ONCE(*depth, 0);
+	}
 
 	/* Setup entry probe */
 	memset(&entry_probe, 0, sizeof(entry_probe));
-- 
2.43.0



  reply	other threads:[~2025-08-18 12:28 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-18 12:26 [RFC PATCH 00/13] mm: Introduce Kernel Stack Watch debugging tool Jinchao Wang
2025-08-18 12:26 ` [RFC PATCH 01/13] mm: Add kstackwatch build infrastructure Jinchao Wang
2025-08-18 12:26   ` [RFC PATCH 02/13] x86/HWBP: Add arch_reinstall_hw_breakpoint() for atomic updates Jinchao Wang
2025-08-18 12:26     ` [RFC PATCH 03/13] mm/kstackwatch: Add module core and configuration interface Jinchao Wang
2025-08-18 12:26       ` [RFC PATCH 04/13] mm/kstackwatch: Add HWBP pre-allocation infrastructure Jinchao Wang
2025-08-18 12:26         ` [RFC PATCH 05/13] mm/kstackwatch: Add atomic HWBP arm/disarm operations Jinchao Wang
2025-08-18 12:26           ` [RFC PATCH 06/13] mm/kstackwatch: Add stack address resolution functions Jinchao Wang
2025-08-18 12:26             ` [RFC PATCH 07/13] mm/kstackwatch: Add kprobe and stack watch control Jinchao Wang
2025-08-18 12:26               ` [RFC PATCH 08/13] mm/kstackwatch: Wire up watch and stack subsystems in module core Jinchao Wang
2025-08-18 12:26                 ` [RFC PATCH 09/13] mm/kstackwatch: Add architecture support validation Jinchao Wang
2025-08-18 12:26                   ` Jinchao Wang [this message]
2025-08-18 12:26                     ` [RFC PATCH 11/13] mm/kstackwatch: Ignore corruption in kretprobe trampolines Jinchao Wang
2025-08-18 12:26                       ` [RFC PATCH 12/13] mm/kstackwatch: Add debug and test functions Jinchao Wang
2025-08-18 12:26                         ` [RFC PATCH 13/13] mm/kstackwatch: Add a test module and script Jinchao Wang
2025-08-25 10:31               ` [RFC PATCH 07/13] mm/kstackwatch: Add kprobe and stack watch control Masami Hiramatsu
2025-08-25 13:11                 ` Jinchao Wang
2025-09-01  7:06     ` [RFC PATCH 02/13] x86/HWBP: Add arch_reinstall_hw_breakpoint() for atomic updates Masami Hiramatsu
2025-09-01 10:23       ` Jinchao Wang
2025-09-02 14:11         ` Masami Hiramatsu
2025-09-03  7:58           ` Jinchao Wang
2025-09-04  0:53             ` Jinchao Wang
2025-09-04  1:02             ` Masami Hiramatsu
2025-09-04  1:15               ` Jinchao Wang

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=20250818122720.434981-11-wangjinchao600@gmail.com \
    --to=wangjinchao600@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=davem@davemloft.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=linux-trace-kernel@vger.kernel.org \
    --cc=mhiramat@kernel.org \
    --cc=naveen@kernel.org \
    /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