tools/perf/builtin-ftrace.c

Source file repositories/reference/linux-study-clean/tools/perf/builtin-ftrace.c

File Facts

System
Linux kernel
Corpus path
tools/perf/builtin-ftrace.c
Extension
.c
Size
48681 bytes
Lines
2026
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct ftrace_profile_data {
	struct stats st;
};

static int add_func_duration(struct perf_ftrace *ftrace, char *func, double time_ns)
{
	struct ftrace_profile_data *prof = NULL;

	if (!hashmap__find(ftrace->profile_hash, func, &prof)) {
		char *key = strdup(func);

		if (key == NULL)
			return -ENOMEM;

		prof = zalloc(sizeof(*prof));
		if (prof == NULL) {
			free(key);
			return -ENOMEM;
		}

		init_stats(&prof->st);
		hashmap__add(ftrace->profile_hash, key, prof);
	}

	update_stats(&prof->st, time_ns);
	return 0;
}

/*
 * The ftrace function_graph text output normally looks like below:
 *
 * CPU   DURATION       FUNCTION
 *
 *  0)               |  syscall_trace_enter.isra.0() {
 *  0)               |    __audit_syscall_entry() {
 *  0)               |      auditd_test_task() {
 *  0)   0.271 us    |        __rcu_read_lock();
 *  0)   0.275 us    |        __rcu_read_unlock();
 *  0)   1.254 us    |      } /\* auditd_test_task *\/
 *  0)   0.279 us    |      ktime_get_coarse_real_ts64();
 *  0)   2.227 us    |    } /\* __audit_syscall_entry *\/
 *  0)   2.713 us    |  } /\* syscall_trace_enter.isra.0 *\/
 *
 *  Parse the line and get the duration and function name.
 */
static int parse_func_duration(struct perf_ftrace *ftrace, char *line, size_t len)
{
	char *p;
	char *func;
	double duration;

	/* skip CPU */
	p = strchr(line, ')');
	if (p == NULL)
		return 0;

	/* get duration */
	p = skip_spaces(p + 1);

	/* no duration? */
	if (p == NULL || *p == '|')
		return 0;

	/* skip markers like '*' or '!' for longer than ms */
	if (!isdigit(*p))
		p++;

	duration = strtod(p, &p);

	if (strncmp(p, " us", 3)) {
		pr_debug("non-usec time found.. ignoring\n");
		return 0;
	}

	/*
	 * profile stat keeps the max and min values as integer,
	 * convert to nsec time so that we can have accurate max.
	 */
	duration *= 1000;

	/* skip to the pipe */
	while (p < line + len && *p != '|')
		p++;

	if (*p++ != '|')
		return -EINVAL;

	/* get function name */
	func = skip_spaces(p);

Annotation

Implementation Notes