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: Michael Petlan <mpetlan@redhat.com>
Acked-by: Jiri Olsa <jolsa@redhat.com>
LPU-Reference: 20191208162056.20772-1-mpetlan@redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Michael Petlan 2019-12-08 17:20:56 +01:00 committed by Arnaldo Carvalho de Melo
parent eb573e746b
commit 2870782687

View File

@ -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;