summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Smith <dsmith@redhat.com>2008-06-10 13:12:35 -0500
committerDavid Smith <dsmith@redhat.com>2008-06-10 13:14:01 -0500
commit8253e3b8d11c842773e77d332fb1426d0f1c1427 (patch)
treeec8ce87491946c222ec760d8169607ae1d4d7ec8
parenta3d153e541b1e538a99e8ce68d871860aff1e228 (diff)
downloadsystemtap-steved-8253e3b8d11c842773e77d332fb1426d0f1c1427.tar.gz
systemtap-steved-8253e3b8d11c842773e77d332fb1426d0f1c1427.tar.xz
systemtap-steved-8253e3b8d11c842773e77d332fb1426d0f1c1427.zip
Very early beginnings of memory map notification support.
2008-06-10 David Smith <dsmith@redhat.com> * tapsets.cxx (utrace_derived_probe_group::emit_probe_decl): Initializes .vm_callback. 2008-06-10 David Smith <dsmith@redhat.com> * task_finder.c (struct stap_task_finder_target): Added vm_callback public field. (stap_register_task_finder_target): Sets up .report_quiesce handler. (__stp_utrace_task_finder_target_quiesce): New function.
-rw-r--r--ChangeLog5
-rw-r--r--runtime/ChangeLog8
-rw-r--r--runtime/task_finder.c111
-rw-r--r--tapsets.cxx1
4 files changed, 115 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index 49a4f80f..02d5947c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2008-06-10 David Smith <dsmith@redhat.com>
+
+ * tapsets.cxx (utrace_derived_probe_group::emit_probe_decl):
+ Initializes .vm_callback.
+
2008-06-09 Jim Keniston <jkenisto@us.ibm.com>
PR 6601
diff --git a/runtime/ChangeLog b/runtime/ChangeLog
index 373cbc16..3912a4cf 100644
--- a/runtime/ChangeLog
+++ b/runtime/ChangeLog
@@ -1,3 +1,11 @@
+2008-06-10 David Smith <dsmith@redhat.com>
+
+ * task_finder.c (struct stap_task_finder_target): Added
+ vm_callback public field.
+ (stap_register_task_finder_target): Sets up .report_quiesce
+ handler.
+ (__stp_utrace_task_finder_target_quiesce): New function.
+
2008-06-09 David Smith <dsmith@redhat.com>
* task_finder.c (__stp_utrace_task_finder_report_exec): Handles
diff --git a/runtime/task_finder.c b/runtime/task_finder.c
index 9c8acfa0..8448f29c 100644
--- a/runtime/task_finder.c
+++ b/runtime/task_finder.c
@@ -29,6 +29,12 @@ typedef int (*stap_task_finder_callback)(struct task_struct *tsk,
int process_p,
struct stap_task_finder_target *tgt);
+typedef int (*stap_task_finder_vm_callback)(struct task_struct *tsk,
+ int map_p, char *vm_path,
+ unsigned long vm_start,
+ unsigned long vm_end,
+ unsigned long vm_pgoff);
+
struct stap_task_finder_target {
/* private: */
struct list_head list; /* __stp_task_finder_list linkage */
@@ -42,12 +48,17 @@ struct stap_task_finder_target {
const char *pathname;
pid_t pid;
stap_task_finder_callback callback;
+ stap_task_finder_vm_callback vm_callback;
};
static u32
__stp_utrace_task_finder_target_death(struct utrace_attached_engine *engine,
struct task_struct *tsk);
+static u32
+__stp_utrace_task_finder_target_quiesce(struct utrace_attached_engine *engine,
+ struct task_struct *tsk);
+
static int
stap_register_task_finder_target(struct stap_task_finder_target *new_tgt)
{
@@ -70,6 +81,7 @@ stap_register_task_finder_target(struct stap_task_finder_target *new_tgt)
new_tgt->engine_attached = 0;
memset(&new_tgt->ops, 0, sizeof(new_tgt->ops));
new_tgt->ops.report_death = &__stp_utrace_task_finder_target_death;
+ new_tgt->ops.report_quiesce = &__stp_utrace_task_finder_target_quiesce;
// Search the list for an existing entry for pathname/pid.
list_for_each(node, &__stp_task_finder_list) {
@@ -206,11 +218,15 @@ __stp_get_mm_path(struct mm_struct *mm, char *buf, int buflen)
return rc;
}
-#define __STP_UTRACE_TASK_FINDER_EVENTS (UTRACE_EVENT(CLONE) \
- | UTRACE_EVENT(EXEC) \
- | UTRACE_EVENT(DEATH))
+#define __STP_TASK_FINDER_EVENTS (UTRACE_EVENT(CLONE) \
+ | UTRACE_EVENT(EXEC) \
+ | UTRACE_EVENT(DEATH))
-#define __STP_UTRACE_ATTACHED_TASK_EVENTS (UTRACE_EVENT(DEATH))
+#define __STP_ATTACHED_TASK_BASE_EVENTS (UTRACE_EVENT(DEATH))
+
+#define __STP_ATTACHED_TASK_EVENTS (__STP_ATTACHED_TASK_BASE_EVENTS \
+ | UTRACE_ACTION_QUIESCE \
+ | UTRACE_EVENT(QUIESCE))
static int
stap_utrace_attach(struct task_struct *tsk,
@@ -297,11 +313,11 @@ __stp_utrace_attach_match_filename(struct task_struct *tsk,
}
}
- // Set up thread death notification.
+ // Set up events we need for attached tasks.
if (register_p) {
rc = stap_utrace_attach(tsk, &cb_tgt->ops,
cb_tgt,
- __STP_UTRACE_ATTACHED_TASK_EVENTS);
+ __STP_ATTACHED_TASK_EVENTS);
if (rc != 0 && rc != EPERM)
break;
cb_tgt->engine_attached = 1;
@@ -390,7 +406,7 @@ __stp_utrace_task_finder_report_clone(struct utrace_attached_engine *engine,
// On clone, attach to the child.
rc = stap_utrace_attach(child, engine->ops, 0,
- __STP_UTRACE_TASK_FINDER_EVENTS);
+ __STP_TASK_FINDER_EVENTS);
if (rc != 0 && rc != EPERM)
return UTRACE_ACTION_RESUME;
@@ -482,6 +498,81 @@ __stp_utrace_task_finder_target_death(struct utrace_attached_engine *engine,
return UTRACE_ACTION_DETACH;
}
+static u32
+__stp_utrace_task_finder_target_quiesce(struct utrace_attached_engine *engine,
+ struct task_struct *tsk)
+{
+ struct stap_task_finder_target *tgt = engine->data;
+
+ // Turn off quiesce handling.
+ utrace_set_flags(tsk, engine, __STP_ATTACHED_TASK_BASE_EVENTS);
+
+ if (atomic_read(&__stp_task_finder_state) != __STP_TF_RUNNING) {
+ debug_task_finder_detach();
+ return UTRACE_ACTION_DETACH;
+ }
+
+ if (tgt != NULL && tgt->vm_callback != NULL) {
+ struct mm_struct *mm;
+ char *mmpath_buf;
+ char *mmpath;
+ struct vm_area_struct *vma;
+ int rc;
+
+ /* Call the vm_callback for every vma associated with
+ * a file. */
+ mm = get_task_mm(tsk);
+ if (! mm)
+ goto utftq_out;
+
+ // Allocate space for a path
+ mmpath_buf = _stp_kmalloc(PATH_MAX);
+ if (mmpath_buf == NULL) {
+ mmput(mm);
+ _stp_error("Unable to allocate space for path");
+ goto utftq_out;
+ }
+
+ down_read(&mm->mmap_sem);
+ vma = mm->mmap;
+ while (vma) {
+ if (vma->vm_file) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
+ mmpath = d_path(vma->vm_file->f_dentry,
+ vma->vm_file->f_vfsmnt,
+ mmpath_buf, PATH_MAX);
+#else
+ mmpath = d_path(&(vma->vm_file->f_path),
+ mmpath_buf, PATH_MAX);
+#endif
+ if (mmpath) {
+ // Call the callback
+ rc = tgt->vm_callback(tsk, 1, mmpath,
+ vma->vm_start,
+ vma->vm_end,
+ vma->vm_pgoff);
+ if (rc != 0) {
+ _stp_error("vm callback for %d failed: %d",
+ (int)tsk->pid, rc);
+ }
+
+ }
+ else {
+ _stp_dbug(__FUNCTION__, __LINE__,
+ "no mmpath?\n");
+ }
+ }
+ vma = vma->vm_next;
+ }
+ up_read(&mm->mmap_sem);
+ mmput(mm); /* We're done with mm */
+ _stp_kfree(mmpath_buf);
+ }
+
+utftq_out:
+ return (UTRACE_ACTION_NEWSTATE | UTRACE_ACTION_RESUME);
+}
+
struct utrace_engine_ops __stp_utrace_task_finder_ops = {
.report_clone = __stp_utrace_task_finder_report_clone,
.report_exec = __stp_utrace_task_finder_report_exec,
@@ -511,7 +602,7 @@ stap_start_task_finder(void)
struct list_head *tgt_node;
rc = stap_utrace_attach(tsk, &__stp_utrace_task_finder_ops, 0,
- __STP_UTRACE_TASK_FINDER_EVENTS);
+ __STP_TASK_FINDER_EVENTS);
if (rc == EPERM) {
/* Ignore EPERM errors, which mean this wasn't
* a thread we can attach to. */
@@ -578,10 +669,10 @@ stap_start_task_finder(void)
goto stf_err;
}
- // Set up thread death notification.
+ // Set up events we need for attached tasks.
rc = stap_utrace_attach(tsk, &cb_tgt->ops,
cb_tgt,
- __STP_UTRACE_ATTACHED_TASK_EVENTS);
+ __STP_ATTACHED_TASK_EVENTS);
if (rc != 0 && rc != EPERM)
goto stf_err;
cb_tgt->engine_attached = 1;
diff --git a/tapsets.cxx b/tapsets.cxx
index 8496e80a..3de2123c 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -5434,6 +5434,7 @@ utrace_derived_probe_group::emit_probe_decl (systemtap_session& s,
}
s.op->line() << " .callback=&_stp_utrace_probe_cb,";
+ s.op->line() << " .vm_callback=NULL,";
s.op->line() << " },";
s.op->line() << " .pp=" << lex_cast_qstring (*p->sole_location()) << ",";
s.op->line() << " .ph=&" << p->name << ",";