This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
[PATCH 2/2] ia64: fast syscall args fetching in utrace probe
- From: Masami Hiramatsu <mhiramat at redhat dot com>
- To: systemtap-ml <systemtap at sources dot redhat dot com>
- Date: Fri, 05 Sep 2008 11:23:44 -0400
- Subject: [PATCH 2/2] ia64: fast syscall args fetching in utrace probe
Hi,
Here is a patch which add fast syscall args fetching by using unwaddr
cache in a utrace handler on ia64.
Since syscall args can not be retrieved directly from pt_regs,
we need to unwind the register stack. This patch speeds the unwinding
up by caching unwound address in a probe handler (as same as
__ia64_fetch_register()).
Thank you,
--
Masami Hiramatsu
Software Engineer
Hitachi Computer Products (America) Inc.
Software Solutions Division
e-mail: mhiramat@redhat.com
---
runtime/regs-ia64.c | 21 +++++++++++++++------
runtime/syscall.h | 17 ++++++-----------
runtime/task_finder.c | 6 ++++++
3 files changed, 27 insertions(+), 17 deletions(-)
Index: systemtap/runtime/regs-ia64.c
===================================================================
--- systemtap.orig/runtime/regs-ia64.c
+++ systemtap/runtime/regs-ia64.c
@@ -61,27 +61,36 @@ static void ia64_stap_get_arbsp(struct u
-(__offset + (regs->cr_ifs & 127)));\
}
-static long ia64_fetch_register(int regno, struct pt_regs *pt_regs, unsigned long **cache)
+static long *
+__ia64_fetch_register(int regno, struct pt_regs *pt_regs, unsigned long **cache)
{
struct ia64_stap_get_arbsp_param pa;
if (regno == 12)
- return pt_regs->r12;
+ return &pt_regs->r12;
if (regno >= 8 && regno <= 11)
- return *(unsigned long *)(&pt_regs->r8 + regno - 8);
+ return (long *)(&pt_regs->r8 + regno - 8);
else if (regno < 32 || regno > 127)
- return 0;
+ return NULL;
if (!*cache) {
pa.ip = pt_regs->cr_iip;
unw_init_running(ia64_stap_get_arbsp, &pa);
if (pa.address == 0)
- return 0;
+ return NULL;
*cache = pa.address;
}
- return *ia64_rse_skip_regs(*cache, regno-32);
+ return ia64_rse_skip_regs(*cache, regno-32);
+}
+
+static long
+ia64_fetch_register(int regno, struct pt_regs *pt_regs, unsigned long **cache)
+{
+ long *reg;
+ reg = __ia64_fetch_register(regno, pt_regs, cache);
+ return (reg != NULL)? *reg : 0;
}
static void ia64_store_register(int regno,
Index: systemtap/runtime/syscall.h
===================================================================
--- systemtap.orig/runtime/syscall.h
+++ systemtap/runtime/syscall.h
@@ -236,23 +236,18 @@ __stp_user_syscall_arg(struct task_struc
#endif
#if defined(__ia64__)
+#define __stp_user_syscall_arg(task, regs, n) \
+ ____stp_user_syscall_arg(task, regs, n, &c->unwaddr)
+
static inline long *
-__stp_user_syscall_arg(struct task_struct *task, struct pt_regs *regs,
- unsigned int n)
+____stp_user_syscall_arg(struct task_struct *task, struct pt_regs *regs,
+ unsigned int n, unsigned long **cache)
{
- struct ia64_stap_get_arbsp_param pa;
if (n > 5) {
_stp_error("syscall arg > 5");
return NULL;
}
-
- pa.ip = regs->cr_iip;
- unw_init_running(ia64_stap_get_arbsp, &pa);
- if (pa.address == 0)
- return NULL;
-
- return ia64_rse_skip_regs(pa.address, n);
-
+ return __ia64_fetch_register(n + 32, regs, cache);
}
#endif
Index: systemtap/runtime/task_finder.c
===================================================================
--- systemtap.orig/runtime/task_finder.c
+++ systemtap/runtime/task_finder.c
@@ -843,6 +843,9 @@ __stp_utrace_task_finder_target_syscall_
struct vm_area_struct *vma;
unsigned long *arg0_addr, arg0;
int rc;
+#if defined(__ia64__)
+ struct { unsigned long *unwaddr; } _c = {.unwaddr = NULL}, *c = &_c;
+#endif
if (atomic_read(&__stp_task_finder_state) != __STP_TF_RUNNING) {
debug_task_finder_detach();
@@ -950,6 +953,9 @@ __stp_utrace_task_finder_target_syscall_
struct mm_struct *mm;
struct vm_area_struct *vma;
struct __stp_tf_vma_entry *entry = NULL;
+#if defined(__ia64__)
+ struct { unsigned long *unwaddr; } _c = {.unwaddr = NULL}, *c = &_c;
+#endif
if (atomic_read(&__stp_task_finder_state) != __STP_TF_RUNNING) {
debug_task_finder_detach();