public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Ingo Molnar <mingo@elte.hu>
To: Jason Baron <jbaron@redhat.com>
Cc: linux-kernel@vger.kernel.org, paulus@samba.org,
	a.p.zijlstra@chello.nl, rostedt@goodmis.org, fweisbec@gmail.com
Subject: Re: [PATCH 2/2] perf_counter: add support to the 'perf' tool for tracepoints
Date: Mon, 13 Jul 2009 09:15:31 +0200	[thread overview]
Message-ID: <20090713071531.GA19230@elte.hu> (raw)
In-Reply-To: <0d7326e18b9860fbf8fb2739f90a23eb9262e24b.1246912068.git.jbaron@redhat.com>


* Jason Baron <jbaron@redhat.com> wrote:

> +static char *tracepoint_id_to_name(u64 config)
> +{
> +	static char tracepoint_name[2 * MAX_EVENT_LENGTH];
> +	DIR *sys_dir, *evt_dir;
> +	struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
> +	struct stat st;
> +	char id_buf[4];
> +	int fd;
> +	long long id;

could this become u64?

> +	char evt_path[MAX_PATH_LENGTH];
> +
> +	if (valid_debugfs_mount())
> +		return "unkown";
> +
> +	sys_dir = opendir(default_debugfs_path);
> +	if (!sys_dir)
> +		goto cleanup;
> +	for_each_subsystem(sys_dir, sys_dirent, sys_next, evt_path, st) {
> +		evt_dir = opendir(evt_path);
> +		if (!evt_dir)
> +			goto cleanup;
> +		for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next,
> +								evt_path, st) {
> +			sprintf(evt_path, "%s/%s/%s/id", default_debugfs_path,
> +				sys_dirent.d_name, evt_dirent.d_name);
> +			fd = open(evt_path, O_RDONLY);
> +			if (fd < 0)
> +				continue;
> +			if (read(fd, id_buf, sizeof(id_buf)) < 0) {
> +				close(fd);
> +				continue;
> +			}
> +			close(fd);
> +			id = atoll(id_buf);
> +			if ((u64)id == config) {

... and thus the cast here could be dropped?

> +				closedir(evt_dir);
> +				closedir(sys_dir);
> +				snprintf(tracepoint_name, 2 * MAX_EVENT_LENGTH,
> +					"%s:%s", sys_dirent.d_name,
> +					evt_dirent.d_name);
> +				return tracepoint_name;
> +			}
> +		}
> +		closedir(evt_dir);
> +	}
> +cleanup:
> +	closedir(sys_dir);
> +	return "unkown";
> +}
> +
>  static int is_cache_op_valid(u8 cache_type, u8 cache_op)
>  {
>  	if (hw_cache_stat[cache_type] & COP(cache_op))
> @@ -177,6 +259,9 @@ char *event_name(int counter)
>  			return sw_event_names[config];
>  		return "unknown-software";
>  
> +	case PERF_TYPE_TRACEPOINT:
> +		return tracepoint_id_to_name(config);
> +
>  	default:
>  		break;
>  	}
> @@ -265,6 +350,78 @@ parse_generic_hw_event(const char **str, struct perf_counter_attr *attr)
>  	return 1;
>  }
>  
> +static int parse_tracepoint_event(const char **strp,
> +				    struct perf_counter_attr *attr)
> +{
> +	const char *evt_name;
> +	char sys_name[MAX_EVENT_LENGTH];
> +	DIR *sys_dir, *evt_dir;
> +	struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
> +	struct stat st;
> +	char id_buf[4];
> +	int fd;
> +	unsigned int sys_length, evt_length;
> +	u64 id;
> +	char evt_path[MAX_PATH_LENGTH];
> +
> +	if (valid_debugfs_mount())
> +		return 0;
> +
> +	evt_name = strchr(*strp, ':');
> +	if (evt_name) {
> +		sys_length = evt_name - *strp;
> +		if (sys_length >= MAX_EVENT_LENGTH)
> +			return 0;
> +		strncpy(sys_name, *strp, sys_length);
> +		sys_name[sys_length] = '\0';
> +		evt_name = evt_name + 1;
> +		evt_length = strlen(evt_name);
> +		if (evt_length >= MAX_EVENT_LENGTH)
> +			return 0;
> +	} else
> +		return 0;
> +
> +	sys_dir = opendir(default_debugfs_path);
> +	if (!sys_dir)
> +		goto cleanup;
> +	for_each_subsystem(sys_dir, sys_dirent, sys_next, evt_path, st) {

a minor request. Just like you added a newline after the return 0 
above, please add a newline after separate blocks of code as well - 
i.e after the 'goto cleanup' above. It makes the loop which begins 
stand out on its own, and makes the sys_dir initialization look 
self-sufficient as well. (which it is)

> +		if (strcmp(sys_dirent.d_name, sys_name) == 0) {
> +			evt_dir = opendir(evt_path);
> +			if (!evt_dir)
> +				goto cleanup;
> +			for_each_event(sys_dirent, evt_dir, evt_dirent,
> +						       evt_next, evt_path, st) {
> +				if (strcmp(evt_dirent.d_name, evt_name) == 0) {
> +					sprintf(evt_path, "%s/%s/%s/id",
> +						default_debugfs_path,
> +						sys_dirent.d_name,
> +						evt_dirent.d_name);
> +					fd = open(evt_path, O_RDONLY);
> +					if (fd < 0)
> +						continue;
> +					if (read(fd, id_buf,
> +						 sizeof(id_buf)) < 0) {
> +						close(fd);
> +						continue;
> +					}
> +					close(fd);
> +					id = atoll(id_buf);
> +					attr->config = id;
> +					attr->type = PERF_TYPE_TRACEPOINT;
> +					closedir(evt_dir);
> +					closedir(sys_dir);
> +					*strp = evt_name + evt_length;
> +					return 1;
> +				}
> +			}
> +			closedir(evt_dir);
> +		}
> +	}
> +cleanup:
> +	closedir(sys_dir);
> +	return 0;
> +}

Ok, this whole feature looks nice. A few minor details need fixing: 
the two functions above tracepoint_id_to_name() and 
parse_tracepoint_event() are a bit large and look very crowded.

one trick to win an indentation level would be to turn this:

> +		if (strcmp(sys_dirent.d_name, sys_name) == 0) {
> +			evt_dir = opendir(evt_path);

into:

		if (strcmp(sys_dirent.d_name, sys_name))
			continue;

		evt_dir = opendir(evt_path);

(Also, for logic operations please write '!x' instead of 'x == 0' - 
it's easy to see only the beginning of the line and miss the 
effective negation.)

The other thing to do would be to move the inner core of the loop 
out into a helper inline function.

plus, this:

> +	if (evt_name) {
> +		sys_length = evt_name - *strp;
> +		if (sys_length >= MAX_EVENT_LENGTH)
> +			return 0;
> +		strncpy(sys_name, *strp, sys_length);
> +		sys_name[sys_length] = '\0';
> +		evt_name = evt_name + 1;
> +		evt_length = strlen(evt_name);
> +		if (evt_length >= MAX_EVENT_LENGTH)
> +			return 0;
> +	} else
> +		return 0;

should be written as:

	if (!evt_name)
		return 0;

	sys_length = evt_name - *strp;
	...

i.e. we should try to compress the visual complexity of 
code as much as possible.

Also ... all code flows return 0, regardless of error or not error. 
Is this intentional?

	Ingo

  parent reply	other threads:[~2009-07-13  7:15 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-07-06 21:11 [PATCH 0/2] perf_counter: add tracepoint support Jason Baron
2009-07-06 21:11 ` [PATCH 1/2] perf_counter: cleanup kernel perf counter support for tracepoints Jason Baron
2009-07-06 21:12 ` [PATCH 2/2] perf_counter: add support to the 'perf' tool " Jason Baron
2009-07-07  8:29   ` Peter Zijlstra
2009-07-08 20:17     ` [PATCH 3/2] perf_counters: add debugfs dir option Jason Baron
2009-07-09  0:47       ` Frederic Weisbecker
2009-07-09 14:45         ` Jason Baron
2009-07-10  4:17           ` Ingo Molnar
2009-07-13  7:15   ` Ingo Molnar [this message]
2009-07-09  3:10 ` [PATCH 0/2] perf_counter: add tracepoint support Frederic Weisbecker
2009-07-09  7:58   ` Peter Zijlstra
2009-07-10  3:53     ` Ingo Molnar

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=20090713071531.GA19230@elte.hu \
    --to=mingo@elte.hu \
    --cc=a.p.zijlstra@chello.nl \
    --cc=fweisbec@gmail.com \
    --cc=jbaron@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=paulus@samba.org \
    --cc=rostedt@goodmis.org \
    /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