#include "CProfile.h"
#include <linux/notifier.h>
+#ifdef OVERHEAD_DEBUG
+extern unsigned long swap_sum_time;
+extern unsigned long swap_sum_hit;
+#endif
+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17)
static BLOCKING_NOTIFIER_HEAD(swap_notifier_list);
#endif
case EC_IOCTL_STOP_AND_DETACH:
{
unsigned long nIgnoredBytes = 0;
+
+#ifdef OVERHEAD_DEBUG
+ printk("\nswap_sum_time = %ld in kprobe_handler()\n", swap_sum_time);
+ printk("swap_sum_hit = %ld in kprobe_handler()\n", swap_sum_hit);
+ swap_sum_time = 0;
+ swap_sum_hit = 0;
+#endif
if(ec_user_stop() != 0) {
result = -1;
break;
return -EINVAL;
}
- rcu_read_lock ();
+ rcu_read_lock();
for_each_process (task) {
if ( 0 != inst_pid && ( inst_pid != task->pid ) )
continue;
- mm = get_task_mm (task);
+ mm = get_task_mm(task);
if (!mm)
continue;
- down_read (&mm->mmap_sem);
vma = mm->mmap;
while (vma) {
if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) {
}
vma = vma->vm_next;
}
- up_read (&mm->mmap_sem);
- mmput (mm);
+ // only decrement usage count on mm since we cannot sleep here
+ atomic_dec(&mm->mm_users);
if (found)
break;
}
- rcu_read_unlock ();
+ rcu_read_unlock();
if (*p_task) {
DPRINTF ("found pid %d for %s.", (*p_task)->pid, path);
* 2010 Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
*
* 2010-2011 Alexander Shirshikov <a.shirshikov@samsung.com>: initial implementation for Thumb
+ * 2012 Stanislav Andreev <s.andreev@samsung.com>: added time debug profiling support; BUG() message fix
*/
-#include<linux/module.h>
-
+#include <linux/module.h>
#include <linux/mm.h>
#include "dbi_kprobes.h"
#include "../dbi_kprobes.h"
-
#include "../../dbi_kdebug.h"
#include "../../dbi_insn_slots.h"
#include "../../dbi_kprobes_deps.h"
#include <asm/cacheflush.h>
+#ifdef OVERHEAD_DEBUG
+#include <linux/time.h>
+#endif
+
+#define SUPRESS_BUG_MESSAGES
+
unsigned int *arr_traps_original;
extern unsigned int *sched_addr;
extern void reset_current_kprobe (void);
extern struct kprobe * current_kprobe;
-
+#ifdef OVERHEAD_DEBUG
+unsigned long swap_sum_time = 0;
+unsigned long swap_sum_hit = 0;
+EXPORT_SYMBOL_GPL (swap_sum_time);
+EXPORT_SYMBOL_GPL (swap_sum_hit);
+#endif
unsigned int arr_traps_template[] = {
0xe1a0c00d, // mov ip, sp
kprobe_opcode_t *addr = NULL, *ssaddr = 0;
struct kprobe_ctlblk *kcb;
int i = 0;
+#ifdef OVERHEAD_DEBUG
+ struct timeval swap_tv1;
+ struct timeval swap_tv2;
+#endif
+#ifdef SUPRESS_BUG_MESSAGES
+ int swap_oops_in_progress;
+#endif
+#ifdef SUPRESS_BUG_MESSAGES
+ // oops_in_progress used to avoid BUG() messages that slow down kprobe_handler() execution
+ swap_oops_in_progress = oops_in_progress;
+ oops_in_progress = 1;
+#endif
+#ifdef OVERHEAD_DEBUG
+#define USEC_IN_SEC_NUM 1000000
+ do_gettimeofday(&swap_tv1);
+#endif
preempt_disable ();
if (user_mode(regs))
if(!p->ainsn.boostable)
kcb->kprobe_status = KPROBE_REENTER;
preempt_enable_no_resched ();
+#ifdef OVERHEAD_DEBUG
+ do_gettimeofday(&swap_tv2);
+ swap_sum_hit++;
+ swap_sum_time += ((swap_tv2.tv_sec - swap_tv1.tv_sec) * USEC_IN_SEC_NUM +
+ (swap_tv2.tv_usec - swap_tv1.tv_usec));
+#endif
+#ifdef SUPRESS_BUG_MESSAGES
+ oops_in_progress = swap_oops_in_progress;
+#endif
return 1;
}
}
ret = p->pre_handler (p, regs);
if(!p->ainsn.boostable)
kcb->kprobe_status = KPROBE_HIT_SS;
- else if(p->pre_handler != trampoline_probe_handler)
- reset_current_kprobe ();
+ else if(p->pre_handler != trampoline_probe_handler) {
+#ifdef SUPRESS_BUG_MESSAGES
+ preempt_disable();
+#endif
+ reset_current_kprobe();
+#ifdef SUPRESS_BUG_MESSAGES
+ preempt_enable_no_resched();
+#endif
+ }
}
if (ret)
{
DBPRINTF ("p->pre_handler 1");
/* handler has already set things up, so skip ss setup */
+#ifdef OVERHEAD_DEBUG
+ do_gettimeofday(&swap_tv2);
+ swap_sum_hit++;
+ swap_sum_time += ((swap_tv2.tv_sec - swap_tv1.tv_sec) * USEC_IN_SEC_NUM +
+ (swap_tv2.tv_usec - swap_tv1.tv_usec));
+#endif
+#ifdef SUPRESS_BUG_MESSAGES
+ oops_in_progress = swap_oops_in_progress;
+#endif
return 1;
}
DBPRINTF ("p->pre_handler 0");
no_kprobe:
preempt_enable_no_resched ();
+#ifdef OVERHEAD_DEBUG
+ do_gettimeofday(&swap_tv2);
+ swap_sum_hit++;
+ swap_sum_time += ((swap_tv2.tv_sec - swap_tv1.tv_sec) * USEC_IN_SEC_NUM +
+ (swap_tv2.tv_usec - swap_tv1.tv_usec));
+#endif
+#ifdef SUPRESS_BUG_MESSAGES
+ oops_in_progress = swap_oops_in_progress;
+#endif
return ret;
}
* 2006-2007 Ekaterina Gorelkina <e.gorelkina@samsung.com>: initial implementation for ARM/MIPS
* 2008-2009 Alexey Gerenkov <a.gerenkov@samsung.com> User-Space
* Probes initial implementation; Support x86/ARM/MIPS for both user-space and kernel space.
- * 2010 Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
- *
+ * 2010 Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
+ * 2012 Stanislav Andreev <s.andreev@samsung.com>: added time debug profiling support; BUG() message fix
*/
#include "dbi_kprobes.h"
#include "../../dbi_kprobes_deps.h"
#include "../../dbi_uprobes.h"
+#ifdef OVERHEAD_DEBUG
+#include <linux/time.h>
+#endif
+
+#define SUPRESS_BUG_MESSAGES
+
unsigned int *arr_traps_original;
extern unsigned int *sched_addr;
extern unsigned long (*kallsyms_search) (const char *name);
+#ifdef OVERHEAD_DEBUG
+unsigned long swap_sum_time = 0;
+unsigned long swap_sum_hit = 0;
+EXPORT_SYMBOL_GPL (swap_sum_time);
+EXPORT_SYMBOL_GPL (swap_sum_hit);
+#endif
+
unsigned int arr_traps_template[] = { 0x3c010000, // lui a1 [0]
0x24210000, // addiu a1, a1 [1]
0x00200008, // jr a1 [2]
0xffffffff // end
};
-
/*
* Function return probe trampoline:
* - init_kprobes() establishes a probepoint here
int ret = 0, pid = 0, retprobe = 0, reenter = 0;
kprobe_opcode_t *addr = NULL, *ssaddr = 0;
struct kprobe_ctlblk *kcb;
+#ifdef OVERHEAD_DEBUG
+ struct timeval swap_tv1;
+ struct timeval swap_tv2;
+#endif
+#ifdef SUPRESS_BUG_MESSAGES
+ int swap_oops_in_progress;
+#endif
/* We're in an interrupt, but this is clear and BUG()-safe. */
addr = (kprobe_opcode_t *) regs->cp0_epc;
DBPRINTF ("regs->regs[ 31 ] = 0x%lx\n", regs->regs[31]);
+#ifdef SUPRESS_BUG_MESSAGES
+ // oops_in_progress used to avoid BUG() messages that slow down kprobe_handler() execution
+ swap_oops_in_progress = oops_in_progress;
+ oops_in_progress = 1;
+#endif
+#ifdef OVERHEAD_DEBUG
+#define USEC_IN_SEC_NUM 1000000
+ do_gettimeofday(&swap_tv1);
+#endif
preempt_disable ();
kcb = get_kprobe_ctlblk ();
if(!p->ainsn.boostable)
kcb->kprobe_status = KPROBE_REENTER;
preempt_enable_no_resched ();
+#ifdef OVERHEAD_DEBUG
+ do_gettimeofday(&swap_tv2);
+ swap_sum_hit++;
+ swap_sum_time += ((swap_tv2.tv_sec - swap_tv1.tv_sec) * USEC_IN_SEC_NUM +
+ (swap_tv2.tv_usec - swap_tv1.tv_usec));
+#endif
+#ifdef SUPRESS_BUG_MESSAGES
+ oops_in_progress = swap_oops_in_progress;
+#endif
return 1;
}
}
ret = p->pre_handler (p, regs);
if(!p->ainsn.boostable)
kcb->kprobe_status = KPROBE_HIT_SS;
- else if(p->pre_handler != trampoline_probe_handler)
- reset_current_kprobe ();
+ else if(p->pre_handler != trampoline_probe_handler) {
+#ifdef SUPRESS_BUG_MESSAGES
+ preempt_disable();
+#endif
+ reset_current_kprobe ();
+#ifdef SUPRESS_BUG_MESSAGES
+ preempt_enable_no_resched();
+#endif
+ }
}
if (ret)
{
DBPRINTF ("p->pre_handler[] 1");
+#ifdef OVERHEAD_DEBUG
+ do_gettimeofday(&swap_tv2);
+ swap_sum_hit++;
+ swap_sum_time += ((swap_tv2.tv_sec - swap_tv1.tv_sec) * USEC_IN_SEC_NUM +
+ (swap_tv2.tv_usec - swap_tv1.tv_usec));
+#endif
+#ifdef SUPRESS_BUG_MESSAGES
+ oops_in_progress = swap_oops_in_progress;
+#endif
/* handler has already set things up, so skip ss setup */
return 1;
}
no_kprobe:
preempt_enable_no_resched ();
+#ifdef OVERHEAD_DEBUG
+ do_gettimeofday(&swap_tv2);
+ swap_sum_hit++;
+ swap_sum_time += ((swap_tv2.tv_sec - swap_tv1.tv_sec) * USEC_IN_SEC_NUM +
+ (swap_tv2.tv_usec - swap_tv1.tv_usec));
+#endif
+#ifdef SUPRESS_BUG_MESSAGES
+ oops_in_progress = swap_oops_in_progress;
+#endif
return ret;
}
* 2008-2009 Alexey Gerenkov <a.gerenkov@samsung.com> User-Space
* Probes initial implementation; Support x86/ARM/MIPS for both user and kernel spaces.
* 2010 Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
- *
-
+ * 2012 Stanislav Andreev <s.andreev@samsung.com>: added time debug profiling support; BUG() message fix
*/
-
#include<linux/module.h>
#include <linux/kdebug.h>
#include "../../dbi_kprobes_deps.h"
#include "../../dbi_uprobes.h"
+#ifdef OVERHEAD_DEBUG
+#include <linux/time.h>
+#endif
+
+#define SUPRESS_BUG_MESSAGES
extern struct kprobe * per_cpu__current_kprobe;
extern void reset_current_kprobe (void);
extern struct kprobe * current_kprobe;
+#ifdef OVERHEAD_DEBUG
+unsigned long swap_sum_time = 0;
+unsigned long swap_sum_hit = 0;
+EXPORT_SYMBOL_GPL (swap_sum_time);
+EXPORT_SYMBOL_GPL (swap_sum_hit);
+#endif
#define SAVE_REGS_STRING \
/* Skip cs, ip, orig_ax. */ \
/* Skip orig_ax, ip, cs */ \
" addq $24, %rsp\n"
-
DECLARE_MOD_FUNC_DEP(module_alloc, void *, unsigned long size);
DECLARE_MOD_FUNC_DEP(module_free, void, struct module *mod, void *module_region);
DECLARE_MOD_FUNC_DEP(fixup_exception, int, struct pt_regs * regs);
DECLARE_MOD_DEP_WRAPPER(show_registers, void, struct pt_regs * regs)
IMP_MOD_DEP_WRAPPER(show_registers, regs)
-
-
-
-
-
/*
* Function return probe trampoline:
* - init_kprobes() establishes a probepoint here
int ret = 0, pid = 0, retprobe = 0, reenter = 0;
kprobe_opcode_t *addr = NULL;
struct kprobe_ctlblk *kcb;
-
+#ifdef OVERHEAD_DEBUG
+ struct timeval swap_tv1;
+ struct timeval swap_tv2;
+#endif
+#ifdef SUPRESS_BUG_MESSAGES
+ int swap_oops_in_progress;
+#endif
/* We're in an interrupt, but this is clear and BUG()-safe. */
addr = (kprobe_opcode_t *) (regs->EREG (ip) - sizeof (kprobe_opcode_t));
DBPRINTF ("KPROBE: regs->eip = 0x%lx addr = 0x%p\n", regs->EREG (ip), addr);
-
+#ifdef SUPRESS_BUG_MESSAGES
+ // oops_in_progress used to avoid BUG() messages that slow down kprobe_handler() execution
+ swap_oops_in_progress = oops_in_progress;
+ oops_in_progress = 1;
+#endif
+#ifdef OVERHEAD_DEBUG
+#define USEC_IN_SEC_NUM 1000000
+ do_gettimeofday(&swap_tv1);
+#endif
preempt_disable ();
kcb = get_kprobe_ctlblk ();
kprobes_inc_nmissed_count (p);
prepare_singlestep (p, regs);
kcb->kprobe_status = KPROBE_REENTER;
+ // FIXME should we enable preemption here??...
+ //preempt_enable_no_resched ();
+#ifdef OVERHEAD_DEBUG
+ do_gettimeofday(&swap_tv2);
+ swap_sum_hit++;
+ swap_sum_time += ((swap_tv2.tv_sec - swap_tv1.tv_sec) * USEC_IN_SEC_NUM +
+ (swap_tv2.tv_usec - swap_tv1.tv_usec));
+#endif
+#ifdef SUPRESS_BUG_MESSAGES
+ oops_in_progress = swap_oops_in_progress;
+#endif
return 1;
}
else
goto ss_probe;
}
DBPRINTF ("p->pre_handler[] 1");
+ // FIXME should we enable preemption here??...
+ //preempt_enable_no_resched ();
+#ifdef OVERHEAD_DEBUG
+ do_gettimeofday(&swap_tv2);
+ swap_sum_hit++;
+ swap_sum_time += ((swap_tv2.tv_sec - swap_tv1.tv_sec) * USEC_IN_SEC_NUM +
+ (swap_tv2.tv_usec - swap_tv1.tv_usec));
+#endif
+#ifdef SUPRESS_BUG_MESSAGES
+ oops_in_progress = swap_oops_in_progress;
+#endif
/* handler has already set things up, so skip ss setup */
return 1;
}
reset_current_kprobe ();
regs->EREG (ip) = (unsigned long) p->ainsn.insn;
preempt_enable_no_resched ();
+#ifdef OVERHEAD_DEBUG
+ do_gettimeofday(&swap_tv2);
+ swap_sum_hit++;
+ swap_sum_time += ((swap_tv2.tv_sec - swap_tv1.tv_sec) * USEC_IN_SEC_NUM +
+ (swap_tv2.tv_usec - swap_tv1.tv_usec));
+#endif
+#ifdef SUPRESS_BUG_MESSAGES
+ oops_in_progress = swap_oops_in_progress;
+#endif
return 1;
}
#endif // !CONFIG_PREEMPT
prepare_singlestep (p, regs);
kcb->kprobe_status = KPROBE_HIT_SS;
+ // FIXME should we enable preemption here??...
+ //preempt_enable_no_resched ();
+#ifdef OVERHEAD_DEBUG
+ do_gettimeofday(&swap_tv2);
+ swap_sum_hit++;
+ swap_sum_time += ((swap_tv2.tv_sec - swap_tv1.tv_sec) * USEC_IN_SEC_NUM +
+ (swap_tv2.tv_usec - swap_tv1.tv_usec));
+#endif
+#ifdef SUPRESS_BUG_MESSAGES
+ oops_in_progress = swap_oops_in_progress;
+#endif
return 1;
no_kprobe:
preempt_enable_no_resched ();
+#ifdef OVERHEAD_DEBUG
+ do_gettimeofday(&swap_tv2);
+ swap_sum_hit++;
+ swap_sum_time += ((swap_tv2.tv_sec - swap_tv1.tv_sec) * USEC_IN_SEC_NUM +
+ (swap_tv2.tv_usec - swap_tv1.tv_usec));
+#endif
+#ifdef SUPRESS_BUG_MESSAGES
+ oops_in_progress = swap_oops_in_progress;
+#endif
return ret;
}