Re: [PATCH v1 4/6] LoongArch: Only send SIGTRAP signal if necessary in do_watch()
From: Tiezhu Yang
Date: Mon Aug 31 2026 - 21:14:16 EST
On 2026/8/31 下午10:02, Huacai Chen wrote:
Hi, Tiezhu,
On Wed, Aug 26, 2026 at 7:03 PM Tiezhu Yang <yangtiezhu@xxxxxxxxxxx> wrote:
In do_watch(), the kernel unconditionally forces a SIGTRAP signal at the
end of the handler via force_sig(SIGTRAP). This is essential for ptrace
operations, but it severely disrupts standard perf_event usage.
...
@@ -811,6 +811,7 @@ asmlinkage void noinstr do_bp(struct pt_regs *regs)This is not for perf only, so need_sigtrap is better.
asmlinkage void noinstr do_watch(struct pt_regs *regs)
{
irqentry_state_t state = irqentry_enter(regs);
+ bool perf_sigtrap = false;
Let breakpoint_handler() and watchpoint_handler() return "int", then
#ifndef CONFIG_HAVE_HW_BREAKPOINT
pr_warn("Hardware watch point handler not implemented!\n");
@@ -851,11 +852,12 @@ asmlinkage void noinstr do_watch(struct pt_regs *regs)
}
}
} else {
- breakpoint_handler(regs);
- watchpoint_handler(regs);
+ perf_sigtrap |= breakpoint_handler(regs);
+ perf_sigtrap |= watchpoint_handler(regs);
see below...
}Define need_sigtrap as "int" and initialize it as current->ptrace,
- force_sig(SIGTRAP);
+ if (current->ptrace || perf_sigtrap)
then we can only use "if (need_sigtrap)" here.
Thanks for your suggestion, it looks better.
But I think the type can be bool since it is either true or false.
Here is the incremental diff based on this v1 patch:
```
diff --git a/arch/loongarch/kernel/traps.c b/arch/loongarch/kernel/traps.c
index de0c9b03d551..4cbf84b148cd 100644
--- a/arch/loongarch/kernel/traps.c
+++ b/arch/loongarch/kernel/traps.c
@@ -811,7 +811,7 @@ asmlinkage void noinstr do_bp(struct pt_regs *regs)
asmlinkage void noinstr do_watch(struct pt_regs *regs)
{
irqentry_state_t state = irqentry_enter(regs);
- bool perf_sigtrap = false;
+ bool need_sigtrap = !!current->ptrace;
#ifndef CONFIG_HAVE_HW_BREAKPOINT
pr_warn("Hardware watch point handler not implemented!\n");
@@ -852,11 +852,11 @@ asmlinkage void noinstr do_watch(struct pt_regs *regs)
}
}
} else {
- perf_sigtrap |= breakpoint_handler(regs);
- perf_sigtrap |= watchpoint_handler(regs);
+ need_sigtrap |= breakpoint_handler(regs);
+ need_sigtrap |= watchpoint_handler(regs);
}
- if (current->ptrace || perf_sigtrap)
+ if (need_sigtrap)
force_sig(SIGTRAP);
out:
#endif
```
If you are OK with the above changes, I will send out v2 later.
Thanks,
Tiezhu