Added functionality for trap (undef. instr) overhead calculation (ARM)
authorAndreev S.V <s.andreev@samsung.com>
Fri, 1 Mar 2013 08:05:06 +0000 (12:05 +0400)
committerAndreev S.V <s.andreev@samsung.com>
Fri, 1 Mar 2013 08:05:06 +0000 (12:05 +0400)
When compiled with support of this functionality swap kprobe module will send
SIGUSR1 signal to userspace application after triggering 100000 traps
(undef.instructions). After that it can calculate the overhead of one trap
(transition from user to kernel and from kernel to user) as a difference of
time when catching signal SIGUSR1 in signal handler and time before first
undef.instruction which is divided on amount of traps (100000).

kprobe/arch/asm-arm/dbi_kprobes.c

index 2d32bcc..a1d3e6a 100644 (file)
 
 #include <asm/cacheflush.h>
 
+#ifdef TRAP_OVERHEAD_DEBUG
+#include <linux/pid.h>
+#include <linux/signal.h>
+#endif
+
 #ifdef OVERHEAD_DEBUG
 #include <linux/time.h>
 #endif
@@ -1037,6 +1042,11 @@ static int kprobe_trap_handler(struct pt_regs *regs, unsigned int instr)
         return ret;
 }
 
+#ifdef TRAP_OVERHEAD_DEBUG
+static unsigned long trap_handler_counter_debug = 0;
+#define SAMPLING_COUNTER                               100000
+#endif
+
 int kprobe_handler(struct pt_regs *regs)
 {
        int err_out = 0;
@@ -1056,6 +1066,20 @@ int kprobe_handler(struct pt_regs *regs)
        swap_oops_in_progress = oops_in_progress;
        oops_in_progress = 1;
 #endif
+#ifdef TRAP_OVERHEAD_DEBUG
+       trap_handler_counter_debug++;
+       if ( trap_handler_counter_debug < SAMPLING_COUNTER ) {
+               err_out = 0;
+       }
+       else {
+               // XXX NOTE - user must care about catching signal via signal handler to avoid hanging!
+               printk("Trap %ld reached - send SIGUSR1\n", trap_handler_counter_debug);
+               kill_pid(get_task_pid(current, PIDTYPE_PID), SIGUSR1, 1);
+               trap_handler_counter_debug = 0;
+               err_out = 0;
+       }
+       return err_out;
+#endif
 #ifdef OVERHEAD_DEBUG
        struct timeval swap_tv1;
        struct timeval swap_tv2;