Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f709b122 authored by Keshavamurthy Anil S's avatar Keshavamurthy Anil S Committed by Linus Torvalds
Browse files

[PATCH] kprobes-changed-from-using-spinlock-to-mutex fix



Based on some feedback from Oleg Nesterov, I have made few changes to
previously posted patch.

Signed-off-by: default avatarAnil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 49a2a1b8
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -35,7 +35,6 @@
#include <asm/kdebug.h>
#include <asm/sstep.h>

static DECLARE_MUTEX(kprobe_mutex);
DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);

@@ -54,9 +53,7 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)

	/* insn must be on a special executable page on ppc64 */
	if (!ret) {
		down(&kprobe_mutex);
		p->ainsn.insn = get_insn_slot();
		up(&kprobe_mutex);
		if (!p->ainsn.insn)
			ret = -ENOMEM;
	}
+2 −2
Original line number Diff line number Diff line
@@ -43,7 +43,7 @@
#include <asm/kdebug.h>

void jprobe_return_end(void);
void __kprobes arch_copy_kprobe(struct kprobe *p);
static void __kprobes arch_copy_kprobe(struct kprobe *p);

DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
@@ -180,7 +180,7 @@ static inline s32 *is_riprel(u8 *insn)
	return NULL;
}

void __kprobes arch_copy_kprobe(struct kprobe *p)
static void __kprobes arch_copy_kprobe(struct kprobe *p)
{
	s32 *ripdisp;
	memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE);
+18 −14
Original line number Diff line number Diff line
@@ -431,7 +431,7 @@ static int __kprobes register_aggr_kprobe(struct kprobe *old_p,
		copy_kprobe(old_p, p);
		ret = add_new_kprobe(old_p, p);
	} else {
		ap = kcalloc(1, sizeof(struct kprobe), GFP_ATOMIC);
		ap = kcalloc(1, sizeof(struct kprobe), GFP_KERNEL);
		if (!ap)
			return -ENOMEM;
		add_aggr_kprobe(ap, old_p);
@@ -491,7 +491,8 @@ out:
void __kprobes unregister_kprobe(struct kprobe *p)
{
	struct module *mod;
	struct kprobe *old_p, *cleanup_p;
	struct kprobe *old_p, *list_p;
	int cleanup_p;

	down(&kprobe_mutex);
	old_p = get_kprobe(p->addr);
@@ -499,22 +500,25 @@ void __kprobes unregister_kprobe(struct kprobe *p)
		up(&kprobe_mutex);
		return;
	}

	if ((old_p->pre_handler == aggr_pre_handler) &&
	if (p != old_p) {
		list_for_each_entry_rcu(list_p, &old_p->list, list)
			if (list_p == p)
			/* kprobe p is a valid probe */
				goto valid_p;
		up(&kprobe_mutex);
		return;
	}
valid_p:
	if ((old_p == p) || ((old_p->pre_handler == aggr_pre_handler) &&
		(p->list.next == &old_p->list) &&
		(p->list.prev == &old_p->list)) {
		/* Only one element in the aggregate list */
		(p->list.prev == &old_p->list))) {
		/* Only probe on the hash list */
		arch_disarm_kprobe(p);
		hlist_del_rcu(&old_p->hlist);
		cleanup_p = old_p;
	} else if (old_p == p) {
		/* Only one kprobe element in the hash list */
		arch_disarm_kprobe(p);
		hlist_del_rcu(&p->hlist);
		cleanup_p = p;
		cleanup_p = 1;
	} else {
		list_del_rcu(&p->list);
		cleanup_p = NULL;
		cleanup_p = 0;
	}

	up(&kprobe_mutex);
@@ -524,7 +528,7 @@ void __kprobes unregister_kprobe(struct kprobe *p)
		module_put(mod);

	if (cleanup_p) {
		if (cleanup_p->pre_handler == aggr_pre_handler) {
		if (p != old_p) {
			list_del_rcu(&p->list);
			kfree(old_p);
		}