Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a72594ca authored by Ingo Molnar's avatar Ingo Molnar
Browse files

Merge tag 'perf-core-for-mingo-4.16-20180117' of...

Merge tag 'perf-core-for-mingo-4.16-20180117' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux

 into perf/core

Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:

- Fix various per event 'max-stack' and 'call-graph=dwarf' issues,
  mostly in 'perf trace', allowing to use 'perf trace --call-graph' with
  'dwarf' and 'fp' to setup the callgraph details for the syscall events
  and make that apply to other events, whilhe allowing to override that on
  a per-event basis, using '-e sched:*switch/call-graph=dwarf/' for
  instance (Arnaldo Carvalho de Melo)

- Improve the --time percent support in record/report/script (Jin Yao)

- Fix copyfile_offset update of output offset (Jiri Olsa)

- Add python script to profile and resolve physical mem type (Kan Liang)

- Add ARM Statistical Profiling Extensions (SPE) support (Kim Phillips)

- Remove trailing semicolon in the evlist code (Luis de Bethencourt)

- Fix incorrect handling of type _TERM_DRV_CFG (Mathieu Poirier)

- Use asprintf when possible in libtraceevent (Federico Vaga)

- Fix bad force_token escape sequence in libtraceevent (Michael Sartain)

- Add UL suffix to MISSING_EVENTS in libtraceevent (Michael Sartain)

- value of unknown symbolic fields in libtraceevent (Jan Kiszka)

- libtraceevent updates: (Steven Rostedt)
  o Show value of flags that have not been parsed
  o Simplify pointer print logic and fix %pF
  o Handle new pointer processing of bprint strings
  o Show contents (in hex) of data of unrecognized type records
  o Fix get_field_str() for dynamic strings

- Add missing break in FALSE case of pevent_filter_clear_trivial() (Taeung Song)

- Fix failed memory allocation for get_cpuid_str (Thomas Richter)

Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents 7a7368a5 81fccd6c
Loading
Loading
Loading
Loading
+51 −11
Original line number Diff line number Diff line
@@ -1094,7 +1094,7 @@ static enum event_type __read_token(char **tok)
		if (strcmp(*tok, "LOCAL_PR_FMT") == 0) {
			free(*tok);
			*tok = NULL;
			return force_token("\"\%s\" ", tok);
			return force_token("\"%s\" ", tok);
		} else if (strcmp(*tok, "STA_PR_FMT") == 0) {
			free(*tok);
			*tok = NULL;
@@ -3970,6 +3970,11 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
				val &= ~fval;
			}
		}
		if (val) {
			if (print && arg->flags.delim)
				trace_seq_puts(s, arg->flags.delim);
			trace_seq_printf(s, "0x%llx", val);
		}
		break;
	case PRINT_SYMBOL:
		val = eval_num_arg(data, size, event, arg->symbol.field);
@@ -3980,6 +3985,8 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
				break;
			}
		}
		if (!flag)
			trace_seq_printf(s, "0x%llx", val);
		break;
	case PRINT_HEX:
	case PRINT_HEX_STR:
@@ -4293,6 +4300,26 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
				goto process_again;
			case 'p':
				ls = 1;
				if (isalnum(ptr[1])) {
					ptr++;
					/* Check for special pointers */
					switch (*ptr) {
					case 's':
					case 'S':
					case 'f':
					case 'F':
						break;
					default:
						/*
						 * Older kernels do not process
						 * dereferenced pointers.
						 * Only process if the pointer
						 * value is a printable.
						 */
						if (isprint(*(char *)bptr))
							goto process_string;
					}
				}
				/* fall through */
			case 'd':
			case 'u':
@@ -4345,6 +4372,7 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc

				break;
			case 's':
 process_string:
				arg = alloc_arg();
				if (!arg) {
					do_warning_event(event, "%s(%d): not enough memory!",
@@ -4949,21 +4977,27 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
				else
					ls = 2;

				if (*(ptr+1) == 'F' || *(ptr+1) == 'f' ||
				    *(ptr+1) == 'S' || *(ptr+1) == 's') {
				if (isalnum(ptr[1]))
					ptr++;

				if (arg->type == PRINT_BSTRING) {
					trace_seq_puts(s, arg->string.string);
					break;
				}

				if (*ptr == 'F' || *ptr == 'f' ||
				    *ptr == 'S' || *ptr == 's') {
					show_func = *ptr;
				} else if (*(ptr+1) == 'M' || *(ptr+1) == 'm') {
					print_mac_arg(s, *(ptr+1), data, size, event, arg);
					ptr++;
				} else if (*ptr == 'M' || *ptr == 'm') {
					print_mac_arg(s, *ptr, data, size, event, arg);
					arg = arg->next;
					break;
				} else if (*(ptr+1) == 'I' || *(ptr+1) == 'i') {
				} else if (*ptr == 'I' || *ptr == 'i') {
					int n;

					n = print_ip_arg(s, ptr+1, data, size, event, arg);
					n = print_ip_arg(s, ptr, data, size, event, arg);
					if (n > 0) {
						ptr += n;
						ptr += n - 1;
						arg = arg->next;
						break;
					}
@@ -5532,8 +5566,14 @@ void pevent_print_event(struct pevent *pevent, struct trace_seq *s,

	event = pevent_find_event_by_record(pevent, record);
	if (!event) {
		do_warning("ug! no event found for type %d",
			   trace_parse_common_type(pevent, record->data));
		int i;
		int type = trace_parse_common_type(pevent, record->data);

		do_warning("ug! no event found for type %d", type);
		trace_seq_printf(s, "[UNKNOWN TYPE %d]", type);
		for (i = 0; i < record->size; i++)
			trace_seq_printf(s, " %02x",
					 ((unsigned char *)record->data)[i]);
		return;
	}

+9 −15
Original line number Diff line number Diff line
@@ -120,12 +120,12 @@ char **traceevent_plugin_list_options(void)
		for (op = reg->options; op->name; op++) {
			char *alias = op->plugin_alias ? op->plugin_alias : op->file;
			char **temp = list;
			int ret;

			name = malloc(strlen(op->name) + strlen(alias) + 2);
			if (!name)
			ret = asprintf(&name, "%s:%s", alias, op->name);
			if (ret < 0)
				goto err;

			sprintf(name, "%s:%s", alias, op->name);
			list = realloc(list, count + 2);
			if (!list) {
				list = temp;
@@ -290,17 +290,14 @@ load_plugin(struct pevent *pevent, const char *path,
	const char *alias;
	char *plugin;
	void *handle;
	int ret;

	plugin = malloc(strlen(path) + strlen(file) + 2);
	if (!plugin) {
	ret = asprintf(&plugin, "%s/%s", path, file);
	if (ret < 0) {
		warning("could not allocate plugin memory\n");
		return;
	}

	strcpy(plugin, path);
	strcat(plugin, "/");
	strcat(plugin, file);

	handle = dlopen(plugin, RTLD_NOW | RTLD_GLOBAL);
	if (!handle) {
		warning("could not load plugin '%s'\n%s\n",
@@ -391,6 +388,7 @@ load_plugins(struct pevent *pevent, const char *suffix,
	char *home;
	char *path;
	char *envdir;
	int ret;

	if (pevent->flags & PEVENT_DISABLE_PLUGINS)
		return;
@@ -421,16 +419,12 @@ load_plugins(struct pevent *pevent, const char *suffix,
	if (!home)
		return;

	path = malloc(strlen(home) + strlen(LOCAL_PLUGIN_DIR) + 2);
	if (!path) {
	ret = asprintf(&path, "%s/%s", home, LOCAL_PLUGIN_DIR);
	if (ret < 0) {
		warning("could not allocate plugin memory\n");
		return;
	}

	strcpy(path, home);
	strcat(path, "/");
	strcat(path, LOCAL_PLUGIN_DIR);

	load_plugins_dir(pevent, suffix, path, load_plugin, data);

	free(path);
+2 −2
Original line number Diff line number Diff line
@@ -24,8 +24,8 @@

#include "kbuffer.h"

#define MISSING_EVENTS (1 << 31)
#define MISSING_STORED (1 << 30)
#define MISSING_EVENTS (1UL << 31)
#define MISSING_STORED (1UL << 30)

#define COMMIT_MASK ((1 << 27) - 1)

+14 −8
Original line number Diff line number Diff line
@@ -287,12 +287,10 @@ find_event(struct pevent *pevent, struct event_list **events,
		sys_name = NULL;
	}

	reg = malloc(strlen(event_name) + 3);
	if (reg == NULL)
	ret = asprintf(&reg, "^%s$", event_name);
	if (ret < 0)
		return PEVENT_ERRNO__MEM_ALLOC_FAILED;

	sprintf(reg, "^%s$", event_name);

	ret = regcomp(&ereg, reg, REG_ICASE|REG_NOSUB);
	free(reg);

@@ -300,13 +298,12 @@ find_event(struct pevent *pevent, struct event_list **events,
		return PEVENT_ERRNO__INVALID_EVENT_NAME;

	if (sys_name) {
		reg = malloc(strlen(sys_name) + 3);
		if (reg == NULL) {
		ret = asprintf(&reg, "^%s$", sys_name);
		if (ret < 0) {
			regfree(&ereg);
			return PEVENT_ERRNO__MEM_ALLOC_FAILED;
		}

		sprintf(reg, "^%s$", sys_name);
		ret = regcomp(&sreg, reg, REG_ICASE|REG_NOSUB);
		free(reg);
		if (ret) {
@@ -1634,6 +1631,7 @@ int pevent_filter_clear_trivial(struct event_filter *filter,
		case FILTER_TRIVIAL_FALSE:
			if (filter_type->filter->boolean.value)
				continue;
			break;
		case FILTER_TRIVIAL_TRUE:
			if (!filter_type->filter->boolean.value)
				continue;
@@ -1879,17 +1877,25 @@ static const char *get_field_str(struct filter_arg *arg, struct pevent_record *r
	struct pevent *pevent;
	unsigned long long addr;
	const char *val = NULL;
	unsigned int size;
	char hex[64];

	/* If the field is not a string convert it */
	if (arg->str.field->flags & FIELD_IS_STRING) {
		val = record->data + arg->str.field->offset;
		size = arg->str.field->size;

		if (arg->str.field->flags & FIELD_IS_DYNAMIC) {
			addr = *(unsigned int *)val;
			val = record->data + (addr & 0xffff);
			size = addr >> 16;
		}

		/*
		 * We need to copy the data since we can't be sure the field
		 * is null terminated.
		 */
		if (*(val + arg->str.field->size - 1)) {
		if (*(val + size - 1)) {
			/* copy it */
			memcpy(arg->str.buffer, val, arg->str.field->size);
			/* the buffer is already NULL terminated */
+1 −1
Original line number Diff line number Diff line
@@ -403,7 +403,7 @@ OPTIONS
	to end of file.

	Also support time percent with multiple time range. Time string is
	'a%/n,b%/m,...' or 'a%-b%,c%-%d,...'. The maximum number of slices is 10.
	'a%/n,b%/m,...' or 'a%-b%,c%-%d,...'.

	For example:
	Select the second 10% time slice:
Loading