This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
[Patch 4/5][Djprobe]Djprobe Coexist with Kprobes
- From: Masami Hiramatsu <hiramatu at sdl dot hitachi dot co dot jp>
- To: systemtap at sources dot redhat dot com
- Cc: Satoshi Oshima <soshima at redhat dot com>,Hideo Aoki <haoki at redhat dot com>, sugita at sdl dot hitachi dot co dot jp
- Date: Thu, 29 Sep 2005 22:00:07 +0900
- Subject: [Patch 4/5][Djprobe]Djprobe Coexist with Kprobes
Hi,
This patch enables djprobe to insert several probes
in the same address.
In other words, multi-djprobes support.
--
Masami HIRAMATSU
2nd Research Dept.
Hitachi, Ltd., Systems Development Laboratory
E-mail: hiramatu@sdl.hitachi.co.jp
arch/i386/kernel/kprobes.c | 8 +++++---
include/linux/kprobes.h | 13 ++++++++-----
kernel/kprobes.c | 11 +++++++----
3 files changed, 20 insertions(+), 12 deletions(-)
diff -Narup linux-2.6.13-mm1.djp.3/arch/i386/kernel/kprobes.c linux-2.6.13-mm1.djp.4/arch/i386/kernel/kprobes.c
--- linux-2.6.13-mm1.djp.3/arch/i386/kernel/kprobes.c 2005-09-12 20:08:48.000000000 +0900
+++ linux-2.6.13-mm1.djp.4/arch/i386/kernel/kprobes.c 2005-09-28 20:06:23.000000000 +0900
@@ -614,9 +614,11 @@ static inline void __set_breakpoint_op(v
static void asmlinkage djprobe_callback(struct djprobe_instance * djpi,
struct pt_regs *regs)
{
- /*TODO: use list*/
- if (djpi->djp && djpi->djp->handler)
- djpi->djp->handler(djpi->djp, regs);
+ struct djprobe * djp;
+ list_for_each_entry_rcu(djp, &djpi->plist, plist) {
+ if (djp->handler)
+ djp->handler(djp, regs);
+ }
}
/*
diff -Narup linux-2.6.13-mm1.djp.3/include/linux/kprobes.h linux-2.6.13-mm1.djp.4/include/linux/kprobes.h
--- linux-2.6.13-mm1.djp.3/include/linux/kprobes.h 2005-09-12 14:05:36.000000000 +0900
+++ linux-2.6.13-mm1.djp.4/include/linux/kprobes.h 2005-09-28 20:06:23.000000000 +0900
@@ -145,7 +145,7 @@ struct kretprobe_instance {
/* djprobe's instance (internal use)*/
struct djprobe_instance {
- struct djprobe *djp;
+ struct list_head plist; /* list of djprobes for multiprobe support */
#ifdef ARCH_SUPPORTS_DJPROBES
struct arch_djprobe_stub stub;
#endif /* ARCH_SUPPORTS_DJPROBES */
@@ -153,7 +153,7 @@ struct djprobe_instance {
struct list_head list; /* list of djprobe_instances */
cpumask_t checked_cpus;
};
-#define DJPI_EMPTY(djpi) (djpi->djp==NULL)
+#define DJPI_EMPTY(djpi) (list_empty(&djpi->plist))
#define DJPI_CHECKED(djpi) (cpus_equal(djpi->checked_cpus, cpu_online_map))
struct djprobe;
@@ -165,15 +165,18 @@ struct djprobe {
#ifndef ARCH_SUPPORTS_DJPROBES
struct kprobe kp;
#endif /* ARCH_SUPPORTS_DJPROBES */
+ /* list of djprobes */
+ struct list_head plist;
+
+ /* probing handler (pre-executed) */
+ djprobe_handler_t handler;
+
/* location of the probe point */
void * addr;
/* sum of length of the replacing codes */
int size;
- /* probing handler (pre-executed) */
- djprobe_handler_t handler;
-
/* pointer for instance */
struct djprobe_instance * inst;
};
diff -Narup linux-2.6.13-mm1.djp.3/kernel/kprobes.c linux-2.6.13-mm1.djp.4/kernel/kprobes.c
--- linux-2.6.13-mm1.djp.3/kernel/kprobes.c 2005-09-27 18:10:28.000000000 +0900
+++ linux-2.6.13-mm1.djp.4/kernel/kprobes.c 2005-09-28 20:06:23.000000000 +0900
@@ -751,12 +751,13 @@ int __kprobes register_djprobe(struct dj
return ret;
spin_lock(&djprobe_lock);
+ INIT_LIST_HEAD(&djp->plist);
/* check confliction with other djprobes */
djpi = __get_djprobe_instance(djp->addr, djp->size);
if (djpi) {
- if (djpi->kp.addr == djp->addr && DJPI_EMPTY(djpi)) {
+ if (djpi->kp.addr == djp->addr) {
djp->inst = djpi;
- djpi->djp = djp; /*TODO: use list*/
+ list_add_rcu(&djp->plist, &djpi->plist);
goto out;
} else {
ret = -EEXIST; /* a djprobe were inserted */
@@ -779,8 +780,9 @@ int __kprobes register_djprobe(struct dj
}
memset(djpi, 0, sizeof(struct djprobe_instance)); /* for kprobe */
/* attach */
+ INIT_LIST_HEAD(&djpi->plist);
djp->inst = djpi;
- djpi->djp = djp; /*TODO: use list*/
+ list_add_rcu(&djp->plist, &djpi->plist);
djpi->kp.addr = djp->addr;
INIT_LIST_HEAD(&djpi->list);
list_add(&djpi->list, &djprobe_list);
@@ -798,6 +800,7 @@ int __kprobes register_djprobe(struct dj
ret = install_djprobe_instance(djpi);
if (ret < 0) { /* failed to install */
djp->inst = NULL;
+ list_del_rcu(&djp->plist);
djpi->kp.addr = NULL;
__free_djprobe_instance(djpi);
}
@@ -815,7 +818,7 @@ void __kprobes unregister_djprobe(struct
djpi = djp->inst;
spin_lock(&djprobe_lock);
djp->inst = NULL;
- djpi->djp = NULL; /*TODO: use list*/
+ list_del_rcu(&djp->plist);
if (DJPI_EMPTY(djpi)) {
uninstall_djprobe_instance(djpi);
}