Mirror of the lttng-dev mailing list
 help / color / mirror / Atom feed
From: guijianfeng@cn.fujitsu.com (Gui Jianfeng)
Subject: [ltt-dev] [PATCH] LTTng: Make mark-control work in debugfs
Date: Fri, 13 Feb 2009 14:24:17 +0800	[thread overview]
Message-ID: <49951211.1040006@cn.fujitsu.com> (raw)
In-Reply-To: <20090211165648.GB26549@Krystal>

Mathieu Desnoyers wrote:
> * Gui Jianfeng (guijianfeng at cn.fujitsu.com) wrote:
>> Mathieu Desnoyers wrote:
>>> I think I have an idea we could implement to support arming markers
>>> which are not loaded in the kernel yet. The use-case is :
>>>
>>> We have a marker in a given module, which is not loaded. We are
>>> interested in tracing events in this module happening soon after module
>>> load. Therefore, we cannot use the /mnt/debugfs/ltt/markers/**/* files,
>>> because the marker is not present yet.
>>>
>>> We could implement mkdir operations to support this. This is out of
>>> ltt-armall scope, and people would have to use it manually and *know*
>>> what channel and marker names they want to enable, but I think it's ok.
>>>
>>> So basically, we would have :
>>>
>>> cd /mnt/debugfs/ltt
>>> mkdir channel_name
>>> cd channel_name
>>> mkdir marker_name
>>>
>>> The marker_name subdirectory would be populated with standard
>>> information and enable files.
>>   Do you mean if we do "mkdir channel_name" and "mkdir marker_name"
>>   kernel will automatically insert the probe module, but in debugfs, 
>>   it doesn't show all of the markers this module have, but just the 
>>   requested one?
>>
> 
> No. I mean that doing :
> mkdir channel_name
> mkdir channel_name/marker_name
> echo 1 > channel_name/marker_name
> 
> Should be the same as the 
> echo "connect channel_name marker_name" > /proc/ltt
> 
> This worked even if the channel/marker pair were not listed in
> /proc/ltt.
> 
> This would create the directories locally even if they do not exist in
> the marker table, and call ltt_marker_connect() when echo 1 >
> channel_name/marker_name is done.

  Well, I got your point now.
  /proc/ltt shows the markers which are located in a specific ELF section "__markers".
  echo "connect channel_name marker_name" > /proc/ltt just creates a marker_entry. Since
  a marker with "channel_name marker_name" doesn't exist in any where. IOW, it can never
  be triggered. Hence, does this feature really make sense?

> 
> Mathieu
> 
>>> Do you think it could be added easily to ltt-trace-control ?
>>>
>>> Mathieu
>>>
>>>
>>>> Thanks,
>>>>
>>>> Mathieu
>>>>
>>>>>> I'm providing the patch modified to fit with checkpatch below.
>>>>>>
>>>>>> Thanks,
>>>>>>
>>>>>> Mathieu
>>>>>>
>>>>>>
>>>>>> lttng-make-mark-control-work-in-debugfs
>>>>>>
>>>>>> This patch makes mark-control work in debugfs
>>>>>> Control files are organized as following.
>>>>>> ltt/
>>>>>> |-- markers
>>>>>> |   |-- fs
>>>>>> |   |   |-- buffer_wait_end
>>>>>> |   |   |   |-- enable
>>>>>> |   |   |   `-- info
>>>>>> |   |   |-- buffer_wait_start
>>>>>> |   |   |   |-- enable
>>>>>> |   |   |   `-- info
>>>>>> |   |   |-- close
>>>>>> |   |   |   |-- enable
>>>>>> |   |   |   `-- info
>>>>>> |   |   |-- exec
>>>>>> |   |   |   |-- enable
>>>>>> |   |   |   `-- info
>>>>>> ...
>>>>>>
>>>>>> One can enable or disable a marker by using the following command
>>>>>> # echo 1 > ltt/markers/fs/close/enable
>>>>>> # echo 0 > ltt/markers/fs/close/enable
>>>>>>
>>>>>> Show the marker information as following 
>>>>>> # cat ltt/markers/fs/close/info
>>>>>> format: "fd %u"
>>>>>> state: 1
>>>>>> event_id: 2
>>>>>> call: 0xc0459118
>>>>>> probe single : 0xc04f7b08
>>>>>>
>>>>>> Mathieu :
>>>>>>
>>>>>> enabled -> enable to follow the semantic of the rest of the debugfs API.
>>>>>> checkpatch.pl cleanup.
>>>>>>
>>>>>> Signed-off-by: Gui Jianfeng <guijianfeng at cn.fujitsu.com>
>>>>>> Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at polymtl.ca>
>>>>>> ---
>>>>>>  ltt/ltt-trace-control.c |  298 +++++++++++++++++++++++++++++++++++++++++++++++-
>>>>>>  1 file changed, 294 insertions(+), 4 deletions(-)
>>>>>>
>>>>>> Index: linux-2.6-lttng/ltt/ltt-trace-control.c
>>>>>> ===================================================================
>>>>>> --- linux-2.6-lttng.orig/ltt/ltt-trace-control.c	2009-02-04 00:56:05.000000000 -0500
>>>>>> +++ linux-2.6-lttng/ltt/ltt-trace-control.c	2009-02-04 01:01:46.000000000 -0500
>>>>>> @@ -1,8 +1,10 @@
>>>>>>  /*
>>>>>>   * LTT trace control module over debugfs.
>>>>>>   *
>>>>>> - * Copyright 2008 -
>>>>>> - *	Zhaolei <zhaolei at cn.fujitsu.com>
>>>>>> + * Copyright 2008 - Zhaolei <zhaolei at cn.fujitsu.com>
>>>>>> + *
>>>>>> + * Copyright 2009 - Gui Jianfeng <guijianfeng at cn.fujitsu.com>
>>>>>> + *                  Make mark-control work in debugfs
>>>>>>   */
>>>>>>  
>>>>>>  /*
>>>>>> @@ -16,14 +18,17 @@
>>>>>>  #include <linux/uaccess.h>
>>>>>>  #include <linux/debugfs.h>
>>>>>>  #include <linux/ltt-tracer.h>
>>>>>> +#include <linux/notifier.h>
>>>>>>  
>>>>>>  #define LTT_CONTROL_DIR "control"
>>>>>> +#define MARKERS_CONTROL_DIR "markers"
>>>>>>  #define LTT_SETUP_TRACE_FILE "setup_trace"
>>>>>>  #define LTT_DESTROY_TRACE_FILE "destroy_trace"
>>>>>>  
>>>>>>  #define LTT_WRITE_MAXLEN	(128)
>>>>>>  
>>>>>> -struct dentry *ltt_control_dir, *ltt_setup_trace_file, *ltt_destroy_trace_file;
>>>>>> +struct dentry *ltt_control_dir, *ltt_setup_trace_file, *ltt_destroy_trace_file,
>>>>>> +	*markers_control_dir;
>>>>>>  
>>>>>>  /*
>>>>>>   * the traces_lock nests inside control_lock.
>>>>>> @@ -692,6 +697,270 @@ static struct file_operations ltt_destro
>>>>>>  	.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;
>>>>>> +	int len;
>>>>>> +
>>>>>> +	marker = (struct marker *)filp->private_data;
>>>>>> +	buf = kmalloc(1024, GFP_KERNEL);
>>>>>> +
>>>>>> +	len = sprintf(buf, "%d\n", _imv_read(marker->state));
>>>>>> +
>>>>>> +	len = simple_read_from_buffer(ubuf, cnt, ppos, buf, len);
>>>>>> +	kfree(buf);
>>>>>> +
>>>>>> +	return len;
>>>>>> +}
>>>>>> +
>>>>>> +static ssize_t marker_enable_write(struct file *filp, const char __user *ubuf,
>>>>>> +				size_t cnt, loff_t *ppos)
>>>>>> +{
>>>>>> +	char buf[NAME_MAX];
>>>>>> +	int buf_size;
>>>>>> +	int err = 0;
>>>>>> +	struct marker *marker;
>>>>>> +
>>>>>> +	marker = (struct marker *)filp->private_data;
>>>>>> +	buf_size = min(cnt, sizeof(buf) - 1);
>>>>>> +	err = copy_from_user(buf, ubuf, buf_size);
>>>>>> +	if (err)
>>>>>> +		return err;
>>>>>> +
>>>>>> +	buf[buf_size] = 0;
>>>>>> +
>>>>>> +	switch (buf[0]) {
>>>>>> +	case 'Y':
>>>>>> +	case 'y':
>>>>>> +	case '1':
>>>>>> +		err = ltt_marker_connect(marker->channel, marker->name,
>>>>>> +					 "default");
>>>>>> +		if (err)
>>>>>> +			return err;
>>>>>> +		break;
>>>>>> +	case 'N':
>>>>>> +	case 'n':
>>>>>> +	case '0':
>>>>>> +		err = ltt_marker_disconnect(marker->channel, marker->name,
>>>>>> +					    "default");
>>>>>> +		if (err)
>>>>>> +			return err;
>>>>>> +		break;
>>>>>> +	default:
>>>>>> +		return -EPERM;
>>>>>> +	}
>>>>>> +
>>>>>> +	return cnt;
>>>>>> +}
>>>>>> +
>>>>>> +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;
>>>>>> +	int len;
>>>>>> +
>>>>>> +	marker = (struct marker *)filp->private_data;
>>>>>> +	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);
>>>>>> +
>>>>>> +	len = simple_read_from_buffer(ubuf, cnt, ppos, buf, len);
>>>>>> +	kfree(buf);
>>>>>> +
>>>>>> +	return len;
>>>>>> +}
>>>>>> +
>>>>>> +static const struct file_operations info_fops = {
>>>>>> +	.open = marker_info_open,
>>>>>> +	.read = marker_info_read,
>>>>>> +};
>>>>>> +
>>>>>> +static int build_marker_file(struct marker *marker)
>>>>>> +{
>>>>>> +	struct dentry *channel_d, *marker_d, *enable_d, *info_d;
>>>>>> +	int err;
>>>>>> +
>>>>>> +	channel_d = dir_lookup(markers_control_dir, marker->channel);
>>>>>> +	if (!channel_d) {
>>>>>> +		channel_d = debugfs_create_dir(marker->channel,
>>>>>> +					       markers_control_dir);
>>>>>> +		if (IS_ERR(channel_d) || !channel_d) {
>>>>>> +			printk(KERN_ERR
>>>>>> +			       "%s: build channel dir of %s failed\n",
>>>>>> +			       __func__, marker->channel);
>>>>>> +			err = -ENOMEM;
>>>>>> +			goto err_build_fail;
>>>>>> +		}
>>>>>> +	}
>>>>>> +
>>>>>> +	marker_d  = dir_lookup(channel_d, marker->name);
>>>>>> +	if (!marker_d) {
>>>>>> +		marker_d = debugfs_create_dir(marker->name, channel_d);
>>>>>> +		if (IS_ERR(marker_d) || !marker_d) {
>>>>>> +			printk(KERN_ERR
>>>>>> +			       "%s: marker dir of %s failed\n",
>>>>>> +			       __func__, marker->name);
>>>>>> +			err = -ENOMEM;
>>>>>> +			goto err_build_fail;
>>>>>> +		}
>>>>>> +	}
>>>>>> +
>>>>>> +	enable_d = dir_lookup(marker_d, "enable");
>>>>>> +	if (!enable_d) {
>>>>>> +		enable_d = debugfs_create_file("enable", 0644, marker_d,
>>>>>> +						marker, &enable_fops);
>>>>>> +		if (IS_ERR(enable_d) || !enable_d) {
>>>>>> +			printk(KERN_ERR
>>>>>> +			       "%s: create file of %s failed\n",
>>>>>> +			       __func__, "enable");
>>>>>> +			err = -ENOMEM;
>>>>>> +			goto err_build_fail;
>>>>>> +		}
>>>>>> +	}
>>>>>> +
>>>>>> +	info_d = dir_lookup(marker_d, "info");
>>>>>> +	if (!info_d) {
>>>>>> +		info_d = debugfs_create_file("info", 0444, marker_d,
>>>>>> +						marker, &info_fops);
>>>>>> +		if (IS_ERR(info_d) || !info_d) {
>>>>>> +			printk(KERN_ERR
>>>>>> +			       "%s: create file of %s failed\n",
>>>>>> +			       __func__, "enable");
>>>>>> +			err = -ENOMEM;
>>>>>> +			goto err_build_fail;
>>>>>> +		}
>>>>>> +	}
>>>>>> +
>>>>>> +	return 0;
>>>>>> +
>>>>>> +err_build_fail:
>>>>>> +	return err;
>>>>>> +}
>>>>>> +
>>>>>> +static int build_marker_control_files(void)
>>>>>> +{
>>>>>> +	struct marker_iter iter;
>>>>>> +	int err;
>>>>>> +
>>>>>> +	err = 0;
>>>>>> +	if (!markers_control_dir)
>>>>>> +		return -EEXIST;
>>>>>> +
>>>>>> +	marker_iter_reset(&iter);
>>>>>> +	marker_iter_start(&iter);
>>>>>> +	for (; iter.marker != NULL; marker_iter_next(&iter)) {
>>>>>> +		err = build_marker_file(iter.marker);
>>>>>> +		if (err)
>>>>>> +			goto err_build_fail;
>>>>>> +	}
>>>>>> +	marker_iter_stop(&iter);
>>>>>> +	return 0;
>>>>>> +
>>>>>> +err_build_fail:
>>>>>> +	return err;
>>>>>> +}
>>>>>> +
>>>>>> +static int remove_marker_control_dir(struct marker *marker)
>>>>>> +{
>>>>>> +	struct dentry *channel_d, *marker_d;
>>>>>> +
>>>>>> +	channel_d = dir_lookup(markers_control_dir, marker->channel);
>>>>>> +	if (!channel_d)
>>>>>> +		return -ENOENT;
>>>>>> +
>>>>>> +	marker_d = dir_lookup(channel_d, marker->name);
>>>>>> +	if (!marker_d)
>>>>>> +		return -ENOENT;
>>>>>> +
>>>>>> +	debugfs_remove_recursive(marker_d);
>>>>>> +	if (list_empty(&channel_d->d_subdirs))
>>>>>> +		debugfs_remove(channel_d);
>>>>>> +
>>>>>> +	return 0;
>>>>>> +}
>>>>>> +
>>>>>> +static void cleanup_control_dir(struct marker *begin, struct marker *end)
>>>>>> +{
>>>>>> +	struct marker *iter;
>>>>>> +
>>>>>> +	if (!markers_control_dir)
>>>>>> +		return;
>>>>>> +
>>>>>> +	for (iter = begin; iter < end; iter++)
>>>>>> +		remove_marker_control_dir(iter);
>>>>>> +
>>>>>> +	return;
>>>>>> +}
>>>>>> +
>>>>>> +static void build_control_dir(struct marker *begin, struct marker *end)
>>>>>> +{
>>>>>> +	struct marker *iter;
>>>>>> +	int err;
>>>>>> +
>>>>>> +	err = 0;
>>>>>> +	if (!markers_control_dir)
>>>>>> +		return;
>>>>>> +
>>>>>> +	for (iter = begin; iter < end; iter++) {
>>>>>> +		err = build_marker_file(iter);
>>>>>> +		if (err)
>>>>>> +			goto err_build_fail;
>>>>>> +	}
>>>>>> +
>>>>>> +	return;
>>>>>> +err_build_fail:
>>>>>> +	cleanup_control_dir(begin, end);
>>>>>> +}
>>>>>> +
>>>>>> +static int module_notify(struct notifier_block *self,
>>>>>> +		  unsigned long val, void *data)
>>>>>> +{
>>>>>> +	struct module *mod = data;
>>>>>> +
>>>>>> +	switch (val) {
>>>>>> +	case MODULE_STATE_COMING:
>>>>>> +		build_control_dir(mod->markers,
>>>>>> +				  mod->markers + mod->num_markers);
>>>>>> +		break;
>>>>>> +	case MODULE_STATE_GOING:
>>>>>> +		cleanup_control_dir(mod->markers,
>>>>>> +				    mod->markers + mod->num_markers);
>>>>>> +		break;
>>>>>> +	}
>>>>>> +	return NOTIFY_DONE;
>>>>>> +}
>>>>>> +
>>>>>> +static struct notifier_block module_nb = {
>>>>>> +	.notifier_call = module_notify,
>>>>>> +};
>>>>>>  
>>>>>>  static int __init ltt_trace_control_init(void)
>>>>>>  {
>>>>>> @@ -733,8 +1002,27 @@ static int __init ltt_trace_control_init
>>>>>>  		goto err_create_destroy_trace_file;
>>>>>>  	}
>>>>>>  
>>>>>> -	return 0;
>>>>>> +	markers_control_dir = debugfs_create_dir(MARKERS_CONTROL_DIR,
>>>>>> +						 ltt_root_dentry);
>>>>>> +	if (IS_ERR(markers_control_dir) || !markers_control_dir) {
>>>>>> +		printk(KERN_ERR
>>>>>> +			"ltt_channel_control_init: create dir of %s failed\n",
>>>>>> +			MARKERS_CONTROL_DIR);
>>>>>> +		err = -ENOMEM;
>>>>>> +		goto err_create_marker_control_dir;
>>>>>> +	}
>>>>>>  
>>>>>> +	if (build_marker_control_files())
>>>>>> +		goto err_build_fail;
>>>>>> +
>>>>>> +	if (!register_module_notifier(&module_nb))
>>>>>> +		return 0;
>>>>>> +
>>>>>> +err_build_fail:
>>>>>> +	debugfs_remove_recursive(markers_control_dir);
>>>>>> +	markers_control_dir = NULL;
>>>>>> +err_create_marker_control_dir:
>>>>>> +	debugfs_remove(ltt_destroy_trace_file);
>>>>>>  err_create_destroy_trace_file:
>>>>>>  	debugfs_remove(ltt_setup_trace_file);
>>>>>>  err_create_setup_trace_file:
>>>>>> @@ -759,6 +1047,8 @@ static void __exit ltt_trace_control_exi
>>>>>>  	debugfs_remove(ltt_setup_trace_file);
>>>>>>  	debugfs_remove(ltt_destroy_trace_file);
>>>>>>  	debugfs_remove_recursive(ltt_control_dir);
>>>>>> +	debugfs_remove_recursive(markers_control_dir);
>>>>>> +	unregister_module_notifier(&module_nb);
>>>>>>  }
>>>>>>  
>>>>>>  module_init(ltt_trace_control_init);
>>>>>>
>>>>>>
>>>>> -- 
>>>>> Regards
>>>>> Gui Jianfeng
>>>>>
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> ltt-dev mailing list
>>>>> ltt-dev at lists.casi.polymtl.ca
>>>>> http://lists.casi.polymtl.ca/cgi-bin/mailman/listinfo/ltt-dev
>>>>>
>>>> -- 
>>>> Mathieu Desnoyers
>>>> OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68
>> -- 
>> Regards
>> Gui Jianfeng
>>
>> _______________________________________________
>> ltt-dev mailing list
>> ltt-dev at lists.casi.polymtl.ca
>> http://lists.casi.polymtl.ca/cgi-bin/mailman/listinfo/ltt-dev
>>
> 

-- 
Regards
Gui Jianfeng




  reply	other threads:[~2009-02-13  6:24 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-02-04  1:46 Gui Jianfeng
2009-02-04  6:20 ` Mathieu Desnoyers
2009-02-04  6:30   ` Mathieu Desnoyers
2009-02-04  6:44   ` Gui Jianfeng
2009-02-04  7:12     ` Mathieu Desnoyers
2009-02-05  1:20       ` Gui Jianfeng
2009-02-11  5:32         ` Mathieu Desnoyers
2009-02-11  8:43           ` Mathieu Desnoyers
2009-02-11  9:27             ` Gui Jianfeng
2009-02-11 16:56               ` Mathieu Desnoyers
2009-02-13  6:24                 ` Gui Jianfeng [this message]
2009-02-13  6:54                   ` Mathieu Desnoyers
2009-02-16  2:43                     ` Gui Jianfeng
2009-02-16  3:16                       ` KOSAKI Motohiro
2009-02-16  3:48                         ` Gui Jianfeng
2009-02-16  4:37                           ` Mathieu Desnoyers
2009-02-16  5:16                             ` Gui Jianfeng

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=49951211.1040006@cn.fujitsu.com \
    --to=guijianfeng@cn.fujitsu.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox