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

Commit 26bdace7 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull perf tooling fixes from Thomas Gleixner:

 - fix 'perf test Session topology' segfault on s390 (Thomas Richter)

 - fix NULL return handling in bpf__prepare_load() (YueHaibing)

 - fix indexing on Coresight ETM packet queue decoder (Mathieu Poirier)

 - fix perf.data format description of NRCPUS header (Arnaldo Carvalho
   de Melo)

 - update perf.data documentation section on cpu topology

 - handle uncore event aliases in small groups properly (Kan Liang)

 - add missing perf_sample.addr into python sample dictionary (Leo Yan)

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  perf tools: Fix perf.data format description of NRCPUS header
  perf script python: Add addr into perf sample dict
  perf data: Update documentation section on cpu topology
  perf cs-etm: Fix indexing for decoder packet queue
  perf bpf: Fix NULL return handling in bpf__prepare_load()
  perf test: "Session topology" dumps core on s390
  perf parse-events: Handle uncore event aliases in small groups properly
parents 918fe1b3 6497bbc3
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -111,8 +111,8 @@ A perf_header_string with the CPU architecture (uname -m)
A structure defining the number of CPUs.

struct nr_cpus {
       uint32_t nr_cpus_online;
       uint32_t nr_cpus_available; /* CPUs not yet onlined */
       uint32_t nr_cpus_online;
};

	HEADER_CPUDESC = 8,
@@ -153,10 +153,18 @@ struct {
	HEADER_CPU_TOPOLOGY = 13,

String lists defining the core and CPU threads topology.
The string lists are followed by a variable length array
which contains core_id and socket_id of each cpu.
The number of entries can be determined by the size of the
section minus the sizes of both string lists.

struct {
       struct perf_header_string_list cores; /* Variable length */
       struct perf_header_string_list threads; /* Variable length */
       struct {
	      uint32_t core_id;
	      uint32_t socket_id;
       } cpus[nr]; /* Variable length records */
};

Example:
+24 −6
Original line number Diff line number Diff line
@@ -70,6 +70,27 @@ static int check_cpu_topology(char *path, struct cpu_map *map)
	session = perf_session__new(&data, false, NULL);
	TEST_ASSERT_VAL("can't get session", session);

	/* On platforms with large numbers of CPUs process_cpu_topology()
	 * might issue an error while reading the perf.data file section
	 * HEADER_CPU_TOPOLOGY and the cpu_topology_map pointed to by member
	 * cpu is a NULL pointer.
	 * Example: On s390
	 *   CPU 0 is on core_id 0 and physical_package_id 6
	 *   CPU 1 is on core_id 1 and physical_package_id 3
	 *
	 *   Core_id and physical_package_id are platform and architecture
	 *   dependend and might have higher numbers than the CPU id.
	 *   This actually depends on the configuration.
	 *
	 *  In this case process_cpu_topology() prints error message:
	 *  "socket_id number is too big. You may need to upgrade the
	 *  perf tool."
	 *
	 *  This is the reason why this test might be skipped.
	 */
	if (!session->header.env.cpu)
		return TEST_SKIP;

	for (i = 0; i < session->header.env.nr_cpus_avail; i++) {
		if (!cpu_map__has(map, i))
			continue;
@@ -95,7 +116,7 @@ int test__session_topology(struct test *test __maybe_unused, int subtest __maybe
{
	char path[PATH_MAX];
	struct cpu_map *map;
	int ret = -1;
	int ret = TEST_FAIL;

	TEST_ASSERT_VAL("can't get templ file", !get_temp(path));

@@ -110,12 +131,9 @@ int test__session_topology(struct test *test __maybe_unused, int subtest __maybe
		goto free_path;
	}

	if (check_cpu_topology(path, map))
		goto free_map;
	ret = 0;

free_map:
	ret = check_cpu_topology(path, map);
	cpu_map__put(map);

free_path:
	unlink(path);
	return ret;
+3 −3
Original line number Diff line number Diff line
@@ -66,7 +66,7 @@ bpf__prepare_load_buffer(void *obj_buf, size_t obj_buf_sz, const char *name)
	}

	obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, name);
	if (IS_ERR(obj)) {
	if (IS_ERR_OR_NULL(obj)) {
		pr_debug("bpf: failed to load buffer\n");
		return ERR_PTR(-EINVAL);
	}
@@ -102,14 +102,14 @@ struct bpf_object *bpf__prepare_load(const char *filename, bool source)
			pr_debug("bpf: successfull builtin compilation\n");
		obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, filename);

		if (!IS_ERR(obj) && llvm_param.dump_obj)
		if (!IS_ERR_OR_NULL(obj) && llvm_param.dump_obj)
			llvm__dump_obj(filename, obj_buf, obj_buf_sz);

		free(obj_buf);
	} else
		obj = bpf_object__open(filename);

	if (IS_ERR(obj)) {
	if (IS_ERR_OR_NULL(obj)) {
		pr_debug("bpf: failed to load %s\n", filename);
		return obj;
	}
+10 −2
Original line number Diff line number Diff line
@@ -96,11 +96,19 @@ int cs_etm_decoder__get_packet(struct cs_etm_decoder *decoder,
	/* Nothing to do, might as well just return */
	if (decoder->packet_count == 0)
		return 0;
	/*
	 * The queueing process in function cs_etm_decoder__buffer_packet()
	 * increments the tail *before* using it.  This is somewhat counter
	 * intuitive but it has the advantage of centralizing tail management
	 * at a single location.  Because of that we need to follow the same
	 * heuristic with the head, i.e we increment it before using its
	 * value.  Otherwise the first element of the packet queue is not
	 * used.
	 */
	decoder->head = (decoder->head + 1) & (MAX_BUFFER - 1);

	*packet = decoder->packet_buffer[decoder->head];

	decoder->head = (decoder->head + 1) & (MAX_BUFFER - 1);

	decoder->packet_count--;

	return 1;
+1 −0
Original line number Diff line number Diff line
@@ -127,6 +127,7 @@ struct perf_evsel {
	bool			precise_max;
	bool			ignore_missing_thread;
	bool			forced_leader;
	bool			use_uncore_alias;
	/* parse modifier helper */
	int			exclude_GH;
	int			nr_members;
Loading