From mboxrd@z Thu Jan 1 00:00:00 1970 From: guijianfeng@cn.fujitsu.com (Gui Jianfeng) Date: Tue, 10 Mar 2009 14:58:22 +0800 Subject: [ltt-dev] [PATCH] LTTNG: same-name marker handling Message-ID: <49B60F8E.7070003@cn.fujitsu.com> Hi Mathieu, This patch enables same-name marker handling in debugfs. The cached marker pointer is removed, and by looking up for each time instead. If there are two markers with the same channel name, marker name and format pair, for example, channel:fs, name:close, format:"fd %u" in fs_trace and and marker_example respectively. you can get the following message when you read "info" file in debugfs. [root at localhost close]# cat info Location: fs_trace format: "fd %u" state: 0 event_id: 0 call: 0xc0468167 probe single : 0xc0466ed8 Location: marker_example format: "fd %u" state: 0 event_id: 0 call: 0xc0468167 probe single : 0xc0466ed8 Location indicates where this marker locates. and enable them all by issuing the following command: [root at localhost close]# echo 1 > enable Signed-off-by: Gui Jianfeng --- kernel/marker.c | 3 +- ltt/ltt-trace-control.c | 118 ++++++++++++++++++++++++++++++----------------- 2 files changed, 77 insertions(+), 44 deletions(-) diff --git a/kernel/marker.c b/kernel/marker.c index 3820622..bb2b718 100644 --- a/kernel/marker.c +++ b/kernel/marker.c @@ -1321,6 +1321,7 @@ void exit_user_markers(struct task_struct *p) mutex_unlock(&markers_mutex); } } +#endif int is_marker_enabled(const char *channel, const char *name) { @@ -1332,7 +1333,7 @@ int is_marker_enabled(const char *channel, const char *name) return entry && !!entry->refcount; } -#endif +EXPORT_SYMBOL_GPL(is_marker_enabled); int marker_module_notify(struct notifier_block *self, unsigned long val, void *data) diff --git a/ltt/ltt-trace-control.c b/ltt/ltt-trace-control.c index 128db4e..0dc5e93 100644 --- a/ltt/ltt-trace-control.c +++ b/ltt/ltt-trace-control.c @@ -19,6 +19,7 @@ #include #include #include +#include #define LTT_CONTROL_DIR "control" #define MARKERS_CONTROL_DIR "markers" @@ -60,7 +61,6 @@ static struct dentry *dir_lookup(struct dentry *parent, const char *name) return d; } - static ssize_t alloc_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { @@ -697,23 +697,24 @@ static struct file_operations ltt_destroy_trace_operations = { .write = destroy_trace_write, }; -static int marker_enable_open(struct inode *inode, struct file *filp) -{ - filp->private_data = inode->i_private; - return 0; -} - static ssize_t marker_enable_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) { - struct marker *marker; + char *buf; + const char *channel, *marker; int len; - marker = (struct marker *)filp->private_data; + marker = filp->f_dentry->d_parent->d_name.name; + channel = filp->f_dentry->d_parent->d_parent->d_name.name; + + len = 0; buf = kmalloc(1024, GFP_KERNEL); - len = sprintf(buf, "%d\n", _imv_read(marker->state)); + if (is_marker_enabled(channel, marker)) + len = sprintf(buf, "%d\n", 1); + else + len = sprintf(buf, "%d\n", 0); len = simple_read_from_buffer(ubuf, cnt, ppos, buf, len); kfree(buf); @@ -727,9 +728,11 @@ static ssize_t marker_enable_write(struct file *filp, const char __user *ubuf, char buf[NAME_MAX]; int buf_size; int err = 0; - struct marker *marker; + const char *channel, *marker; + + marker = filp->f_dentry->d_parent->d_name.name; + channel = filp->f_dentry->d_parent->d_parent->d_name.name; - marker = (struct marker *)filp->private_data; buf_size = min(cnt, sizeof(buf) - 1); err = copy_from_user(buf, ubuf, buf_size); if (err) @@ -741,16 +744,14 @@ static ssize_t marker_enable_write(struct file *filp, const char __user *ubuf, case 'Y': case 'y': case '1': - err = ltt_marker_connect(marker->channel, marker->name, - "default"); + err = ltt_marker_connect(channel, marker, "default"); if (err) return err; break; case 'N': case 'n': case '0': - err = ltt_marker_disconnect(marker->channel, marker->name, - "default"); + err = ltt_marker_disconnect(channel, marker, "default"); if (err) return err; break; @@ -762,35 +763,46 @@ static ssize_t marker_enable_write(struct file *filp, const char __user *ubuf, } static const struct file_operations enable_fops = { - .open = marker_enable_open, .read = marker_enable_read, .write = marker_enable_write, }; -static int marker_info_open(struct inode *inode, struct file *filp) -{ - filp->private_data = inode->i_private; - return 0; -} - static ssize_t marker_info_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) { - struct marker *marker; char *buf; + const char *channel, *marker; int len; + struct marker_iter iter; + + marker = filp->f_dentry->d_parent->d_name.name; + channel = filp->f_dentry->d_parent->d_parent->d_name.name; - marker = (struct marker *)filp->private_data; + len = 0; buf = kmalloc(1024, GFP_KERNEL); - len = sprintf(buf, "format: \"%s\"\nstate: %d\n" - "event_id: %hu\n" - "call: 0x%p\n" - "probe %s : 0x%p\n", - marker->format, _imv_read(marker->state), - marker->event_id, marker->call, marker->ptype ? - "multi" : "single", marker->ptype ? - (void *)marker->multi : (void *)marker->single.func); + marker_iter_reset(&iter); + marker_iter_start(&iter); + for (; iter.marker != NULL; marker_iter_next(&iter)) { + if (!strcmp(iter.marker->channel, channel) && + !strcmp(iter.marker->name, marker)) + len += sprintf(buf + len, "Location: %s\n" + "format: \"%s\"\nstate: %d\n" + "event_id: %hu\n" + "call: 0x%p\n" + "probe %s : 0x%p\n\n", + iter.module ? iter.module->name : + "Core Kernel", + iter.marker->format, + _imv_read(iter.marker->state), + iter.marker->event_id, + iter.marker->call, + iter.marker->ptype ? + "multi" : "single", iter.marker->ptype ? + (void *)iter.marker->multi : + (void *)iter.marker->single.func); + } + marker_iter_stop(&iter); len = simple_read_from_buffer(ubuf, cnt, ppos, buf, len); kfree(buf); @@ -799,7 +811,6 @@ static ssize_t marker_info_read(struct file *filp, char __user *ubuf, } static const struct file_operations info_fops = { - .open = marker_info_open, .read = marker_info_read, }; @@ -836,7 +847,7 @@ static int build_marker_file(struct marker *marker) enable_d = dir_lookup(marker_d, "enable"); if (!enable_d) { enable_d = debugfs_create_file("enable", 0644, marker_d, - marker, &enable_fops); + NULL, &enable_fops); if (IS_ERR(enable_d) || !enable_d) { printk(KERN_ERR "%s: create file of %s failed\n", @@ -849,7 +860,7 @@ static int build_marker_file(struct marker *marker) info_d = dir_lookup(marker_d, "info"); if (!info_d) { info_d = debugfs_create_file("info", 0444, marker_d, - marker, &info_fops); + NULL, &info_fops); if (IS_ERR(info_d) || !info_d) { printk(KERN_ERR "%s: create file of %s failed\n", @@ -888,26 +899,46 @@ err_build_fail: return err; } -static int remove_marker_control_dir(struct marker *marker) +static int remove_marker_control_dir(struct module *mod, struct marker *marker) { struct dentry *channel_d, *marker_d; + const char *channel, *name; + int count; + struct marker_iter iter; + + count = 0; channel_d = dir_lookup(markers_control_dir, marker->channel); if (!channel_d) return -ENOENT; + channel = channel_d->d_name.name; marker_d = dir_lookup(channel_d, marker->name); if (!marker_d) return -ENOENT; + name = marker_d->d_name.name; + + marker_iter_reset(&iter); + marker_iter_start(&iter); + for (; iter.marker != NULL; marker_iter_next(&iter)) { + if (!strcmp(iter.marker->channel, channel) && + !strcmp(iter.marker->name, name) && mod != iter.module) + count++; + } + + if (count > 0) + goto end; debugfs_remove_recursive(marker_d); if (list_empty(&channel_d->d_subdirs)) debugfs_remove(channel_d); +end: return 0; } -static void cleanup_control_dir(struct marker *begin, struct marker *end) +static void cleanup_control_dir(struct module *mod, struct marker *begin, + struct marker *end) { struct marker *iter; @@ -915,12 +946,13 @@ static void cleanup_control_dir(struct marker *begin, struct marker *end) return; for (iter = begin; iter < end; iter++) - remove_marker_control_dir(iter); + remove_marker_control_dir(mod, iter); return; } -static void build_control_dir(struct marker *begin, struct marker *end) +static void build_control_dir(struct module *mod, struct marker *begin, + struct marker *end) { struct marker *iter; int err; @@ -937,7 +969,7 @@ static void build_control_dir(struct marker *begin, struct marker *end) return; err_build_fail: - cleanup_control_dir(begin, end); + cleanup_control_dir(mod, begin, end); } static int module_notify(struct notifier_block *self, @@ -947,11 +979,11 @@ static int module_notify(struct notifier_block *self, switch (val) { case MODULE_STATE_COMING: - build_control_dir(mod->markers, + build_control_dir(mod, mod->markers, mod->markers + mod->num_markers); break; case MODULE_STATE_GOING: - cleanup_control_dir(mod->markers, + cleanup_control_dir(mod, mod->markers, mod->markers + mod->num_markers); break; } -- 1.5.4.rc3