Commit 28707826 authored by Michael Petlan's avatar Michael Petlan Committed by Arnaldo Carvalho de Melo
Browse files

perf header: Fix false warning when there are no duplicate cache entries



Before this patch, perf expected that there might be NPROC*4 unique
cache entries at max, however, it also expected that some of them would
be shared and/or of the same size, thus the final number of entries
would be reduced to be lower than NPROC*4. In case the number of entries
hadn't been reduced (was NPROC*4), the warning was printed.

However, some systems might have unusual cache topology, such as the
following two-processor KVM guest:

	cpu  level  shared_cpu_list  size
	  0     1         0           32K
	  0     1         0           64K
	  0     2         0           512K
	  0     3         0           8192K
	  1     1         1           32K
	  1     1         1           64K
	  1     2         1           512K
	  1     3         1           8192K

This KVM guest has 8 (NPROC*4) unique cache entries, which used to make
perf printing the message, although there actually aren't "way too many
cpu caches".

v2: Removing unused argument.

v3: Unifying the way we obtain number of cpus.

v4: Removed '& UINT_MAX' construct which is redundant.

Signed-off-by: default avatarMichael Petlan <mpetlan@redhat.com>
Acked-by: default avatarJiri Olsa <jolsa@redhat.com>
LPU-Reference: 20191208162056.20772-1-mpetlan@redhat.com
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent eb573e74
Loading
Loading
Loading
Loading
+6 −15
Original line number Diff line number Diff line
@@ -1089,21 +1089,18 @@ static void cpu_cache_level__fprintf(FILE *out, struct cpu_cache_level *c)
	fprintf(out, "L%d %-15s %8s [%s]\n", c->level, c->type, c->size, c->map);
}

static int build_caches(struct cpu_cache_level caches[], u32 size, u32 *cntp)
#define MAX_CACHE_LVL 4

static int build_caches(struct cpu_cache_level caches[], u32 *cntp)
{
	u32 i, cnt = 0;
	long ncpus;
	u32 nr, cpu;
	u16 level;

	ncpus = sysconf(_SC_NPROCESSORS_CONF);
	if (ncpus < 0)
		return -1;

	nr = (u32)(ncpus & UINT_MAX);
	nr = cpu__max_cpu();

	for (cpu = 0; cpu < nr; cpu++) {
		for (level = 0; level < 10; level++) {
		for (level = 0; level < MAX_CACHE_LVL; level++) {
			struct cpu_cache_level c;
			int err;

@@ -1123,18 +1120,12 @@ static int build_caches(struct cpu_cache_level caches[], u32 size, u32 *cntp)
				caches[cnt++] = c;
			else
				cpu_cache_level__free(&c);

			if (WARN_ONCE(cnt == size, "way too many cpu caches.."))
				goto out;
		}
	}
 out:
	*cntp = cnt;
	return 0;
}

#define MAX_CACHE_LVL 4

static int write_cache(struct feat_fd *ff,
		       struct evlist *evlist __maybe_unused)
{
@@ -1143,7 +1134,7 @@ static int write_cache(struct feat_fd *ff,
	u32 cnt = 0, i, version = 1;
	int ret;

	ret = build_caches(caches, max_caches, &cnt);
	ret = build_caches(caches, &cnt);
	if (ret)
		goto out;