FIXED Ticket #292 (BUG() messages)
authorAndreev S.V <s.andreev@samsung.com>
Mon, 9 Apr 2012 07:28:31 +0000 (11:28 +0400)
committerAndreev S.V <s.andreev@samsung.com>
Mon, 9 Apr 2012 07:28:31 +0000 (11:28 +0400)
driver/device_driver.c
driver/us_proc_inst.c
kprobe/arch/asm-arm/dbi_kprobes.c
kprobe/arch/asm-mips/dbi_kprobes.c
kprobe/arch/asm-x86/dbi_kprobes.c

index 3270e67..e54a9d0 100644 (file)
 #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
@@ -499,6 +504,13 @@ static int device_ioctl (struct file *file UNUSED, unsigned int cmd, unsigned lo
        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;
index 29d0599..f049dd1 100644 (file)
@@ -331,16 +331,15 @@ static int find_task_by_path (const char *path, struct task_struct **p_task, str
                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) {
@@ -394,12 +393,12 @@ static int find_task_by_path (const char *path, struct task_struct **p_task, str
                        }
                        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);
index be1f3bb..4482513 100644 (file)
  * 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;
@@ -60,7 +65,12 @@ extern struct kprobe_ctlblk *get_kprobe_ctlblk (void);
 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
@@ -1026,7 +1036,23 @@ int kprobe_handler (struct pt_regs *regs)
        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))
@@ -1138,6 +1164,15 @@ int kprobe_handler (struct pt_regs *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;
                        }
                }
@@ -1250,19 +1285,44 @@ int kprobe_handler (struct pt_regs *regs)
                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;
 }
 
index 48a5dd6..6358741 100644 (file)
@@ -21,8 +21,8 @@
  * 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;
@@ -51,6 +57,13 @@ extern void reset_current_kprobe (void);
 
 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]
@@ -58,7 +71,6 @@ unsigned int arr_traps_template[] = {  0x3c010000,   // lui  a1       [0]
        0xffffffff    // end
 };
 
-
 /*
  * Function return probe trampoline:
  *     - init_kprobes() establishes a probepoint here
@@ -300,12 +312,28 @@ int kprobe_handler (struct pt_regs *regs)
        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 ();
@@ -344,6 +372,15 @@ int kprobe_handler (struct pt_regs *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;
                        }
                }
@@ -432,13 +469,29 @@ int kprobe_handler (struct pt_regs *regs)
                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;
        }
@@ -446,6 +499,15 @@ int kprobe_handler (struct pt_regs *regs)
 
 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;
 }
 
index 688e637..48ae675 100644 (file)
  * 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;
 
@@ -74,6 +77,12 @@ extern struct kprobe_ctlblk *get_kprobe_ctlblk (void);
 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. */     \
@@ -112,7 +121,6 @@ extern struct kprobe * current_kprobe;
        /* 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);
@@ -145,11 +153,6 @@ IMP_MOD_DEP_WRAPPER(text_poke, addr, opcode, len)
 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
@@ -491,12 +494,26 @@ int kprobe_handler (struct pt_regs *regs)
        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 ();
@@ -538,6 +555,17 @@ int kprobe_handler (struct pt_regs *regs)
                        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
@@ -642,6 +670,17 @@ int kprobe_handler (struct pt_regs *regs)
                        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;
        }
@@ -658,16 +697,45 @@ ss_probe:
                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;
 }