This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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();

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]