[IMPROVE] remove preemption disabling from kprobe 19/69319/2
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>
Tue, 26 Apr 2016 16:40:21 +0000 (19:40 +0300)
committerDmitry Kovalenko <d.kovalenko@samsung.com>
Tue, 17 May 2016 14:09:29 +0000 (07:09 -0700)
Change-Id: Ie0ac12b32b4caa76fc2162b7dc467851260c9f0a
Signed-off-by: Vyacheslav Cherkashin <v.cherkashin@samsung.com>
kprobe/arch/arm/swap-asm/swap_kprobes.c
kprobe/arch/x86/swap-asm/swap_kprobes.c
kprobe/swap_kprobes.c
kprobe/swap_kprobes.h
kprobe/swap_kprobes_deps.h

index 89f0459..2a689b2 100644 (file)
@@ -343,7 +343,7 @@ int swap_arch_prepare_kprobe(struct kprobe *p, struct slot_manager *sm)
  * @param regs Pointer to CPU registers data.
  * @return Void.
  */
-void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
+static void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
 {
        int cpu = smp_processor_id();
 
@@ -354,7 +354,6 @@ void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
                regs->ARM_pc = (unsigned long)p->ainsn.insn;
        }
 }
-EXPORT_SYMBOL_GPL(prepare_singlestep);
 
 /**
  * @brief Saves previous kprobe.
@@ -458,7 +457,6 @@ int kprobe_trap_handler(struct pt_regs *regs, unsigned int instr)
        unsigned long flags;
 
        local_irq_save(flags);
-       preempt_disable();
 
        if (likely(instr == BREAKPOINT_INSTRUCTION)) {
                ret = kprobe_handler(regs);
@@ -469,7 +467,6 @@ int kprobe_trap_handler(struct pt_regs *regs, unsigned int instr)
                ret = p && (p->opcode == instr) ? 0 : 1;
        }
 
-       swap_preempt_enable_no_resched();
        local_irq_restore(flags);
 
        return ret;
index bce501a..29cd7e8 100644 (file)
@@ -239,25 +239,17 @@ int swap_arch_prepare_kprobe(struct kprobe *p, struct slot_manager *sm)
  * @param regs Pointer to CPU registers data.
  * @return Void.
  */
-void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
+static void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
 {
-       int cpu = smp_processor_id();
+       regs->flags |= TF_MASK;
+       regs->flags &= ~IF_MASK;
 
-       if (p->ss_addr[cpu]) {
-               regs->EREG(ip) = (unsigned long)p->ss_addr[cpu];
-               p->ss_addr[cpu] = NULL;
-       } else {
-               regs->EREG(flags) |= TF_MASK;
-               regs->EREG(flags) &= ~IF_MASK;
-               /* single step inline if the instruction is an int3 */
-               if (p->opcode == BREAKPOINT_INSTRUCTION) {
-                       regs->EREG(ip) = (unsigned long) p->addr;
-                       /* printk(KERN_INFO "break_insn!!!\n"); */
-               } else
-                       regs->EREG(ip) = (unsigned long) p->ainsn.insn;
-       }
+       /* single step inline if the instruction is an int3 */
+       if (p->opcode == BREAKPOINT_INSTRUCTION)
+               regs->ip = (unsigned long)p->addr;
+       else
+               regs->ip = (unsigned long)p->ainsn.insn;
 }
-EXPORT_SYMBOL_GPL(prepare_singlestep);
 
 /**
  * @brief Saves previous kprobe.
@@ -322,7 +314,6 @@ static int setup_singlestep(struct kprobe *p, struct pt_regs *regs,
                /* Boost up -- we can execute copied instructions directly */
                swap_kprobe_running_set(NULL);
                regs->ip = (unsigned long)p->ainsn.insn;
-               swap_preempt_enable_no_resched();
 
                return 1;
        }
@@ -343,8 +334,6 @@ static int __kprobe_handler(struct pt_regs *regs)
 
        addr = (kprobe_opcode_t *) (regs->EREG(ip) - sizeof(kprobe_opcode_t));
 
-       preempt_disable();
-
        kcb = swap_get_kprobe_ctlblk();
        p = swap_get_kprobe(addr);
 
@@ -430,8 +419,6 @@ ss_probe:
        return 1;
 
 no_kprobe:
-       swap_preempt_enable_no_resched();
-
        return ret;
 }
 
@@ -646,8 +633,6 @@ static int post_kprobe_handler(struct pt_regs *regs)
        }
        swap_kprobe_running_set(NULL);
 out:
-       swap_preempt_enable_no_resched();
-
        /*
         * if somebody else is singlestepping across a probe point, eflags
         * will have TF set, in which case, continue the remaining processing
@@ -680,7 +665,6 @@ static int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
                        restore_previous_kprobe(kcb);
                else
                        swap_kprobe_running_set(NULL);
-               swap_preempt_enable_no_resched();
                break;
        case KPROBE_HIT_ACTIVE:
        case KPROBE_HIT_SSDONE:
@@ -749,12 +733,9 @@ static int kprobe_exceptions_notify(struct notifier_block *self,
                        ret = NOTIFY_STOP;
                break;
        case DIE_GPF:
-               /* swap_kprobe_running() needs smp_processor_id() */
-               preempt_disable();
                if (swap_kprobe_running() &&
                    kprobe_fault_handler(args->regs, args->trapnr))
                        ret = NOTIFY_STOP;
-               preempt_enable();
                break;
        default:
                break;
@@ -803,7 +784,6 @@ int swap_longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
                *regs = kcb->jprobe_saved_regs;
                memcpy((kprobe_opcode_t *) stack_addr, kcb->jprobes_stack,
                       MIN_STACK_SIZE(stack_addr));
-               swap_preempt_enable_no_resched();
                return 1;
        }
 
@@ -925,7 +905,6 @@ int set_kjump_cb(struct pt_regs *regs, jumper_cb_t cb, void *data, size_t size)
        regs->ip = (unsigned long)&kjump_trampoline;
 
        swap_kprobe_running_set(NULL);
-       swap_preempt_enable_no_resched();
 
        return 1;
 }
index 5a1e444..c90757e 100644 (file)
@@ -768,7 +768,6 @@ int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
 
        trampoline_address = (unsigned long)&swap_kretprobe_trampoline;
 
-       preempt_disable();
        kcb = swap_get_kprobe_ctlblk();
 
        spin_lock_irqsave(&kretprobe_lock, flags);
@@ -830,7 +829,6 @@ int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
                swap_kprobe_running_set(NULL);
 
        spin_unlock_irqrestore(&kretprobe_lock, flags);
-       swap_preempt_enable_no_resched();
 
        /*
         * By returning a non-zero value, we are telling
index cde78a8..c69824c 100644 (file)
@@ -297,7 +297,6 @@ void swap_kprobe_running_set(struct kprobe *p);
 void swap_reset_current_kprobe(void);
 struct kprobe_ctlblk *swap_get_kprobe_ctlblk(void);
 
-void prepare_singlestep(struct kprobe *p, struct pt_regs *regs);
 
 #endif /* _SWAP_KPROBES_H */
 
index e555ecb..913e5c2 100644 (file)
 #endif
 
 
-/*
- * TODO: possibly unnided
- *       check and remove swap_preempt_enable_no_resched() call
- */
-#if (defined(MODULE) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)))
-
-#ifdef CONFIG_PREEMPT_COUNT
-#define swap_preempt_enable_no_resched() \
-do { \
-       barrier(); \
-       preempt_count_dec(); \
-} while (0)
-#else /* !CONFIG_PREEMPT_COUNT */
-#define swap_preempt_enable_no_resched() barrier()
-#endif /* CONFIG_PREEMPT_COUNT */
-
-#else /* !(defined(MODULE) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) */
-
-#define swap_preempt_enable_no_resched() preempt_enable_no_resched()
-
-#endif /* !(defined(MODULE) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) */
-
-
 #if LINUX_VERSION_CODE > KERNEL_VERSION(3, 1, 0)
     #define task_job(task) (task->jobctl)
 #else /* LINUX_VERSION_CODE > KERNEL_VERSION(3, 1, 0) */