Commit 8cb7a188 authored by Athira Rajeev's avatar Athira Rajeev Committed by Arnaldo Carvalho de Melo

perf bench: Fix numa testcase to check if CPU used to bind task is online

Perf numa bench test fails with error:

Testcase:

  ./perf bench numa mem -p 2 -t 1 -P 1024 -C 0,8 -M 1,0 -s 20 -zZq --thp  1 --no-data_rand_walk

Failure snippet:

<<>>
  Running 'numa/mem' benchmark:

  # Running main, "perf bench numa numa-mem -p 2 -t 1 -P 1024 -C 0,8 -M 1,0 -s 20 -zZq --thp 1 --no-data_rand_walk"

  perf: bench/numa.c:333: bind_to_cpumask: Assertion `!(ret)' failed.
<<>>

The Testcases uses CPU's 0 and 8. In function "parse_setup_cpu_list",
There is check to see if cpu number is greater than max cpu's possible
in the system ie via "if (bind_cpu_0 >= g->p.nr_cpus || bind_cpu_1 >=
g->p.nr_cpus) {".

But it could happen that system has say 48 CPU's, but only number of
online CPU's is 0-7. Other CPU's are offlined. Since "g->p.nr_cpus" is
48, so function will go ahead and set bit for CPU 8 also in cpumask (
td->bind_cpumask).

bind_to_cpumask function is called to set affinity using
sched_setaffinity and the cpumask. Since the CPU8 is not present, set
affinity will fail here with EINVAL.

Fix this issue by adding a check to make sure that, CPU's provided in
the input argument values are online before proceeding further and skip
the test. For this, include new helper function "is_cpu_online" in
"tools/perf/util/header.c".

Since "BIT(x)" definition will get included from header.h, remove
that from bench/numa.c
Reported-by: default avatarDisha Goel <disgoel@linux.vnet.ibm.com>
Signed-off-by: default avatarAthira Jajeev <atrajeev@linux.vnet.ibm.com>
Tested-by: default avatarDisha Goel <disgoel@linux.vnet.ibm.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kajol Jain <kjain@linux.ibm.com>
Cc: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Nageswara R Sastry <rnsastry@linux.ibm.com>
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Cc: linuxppc-dev@lists.ozlabs.org
Link: https://lore.kernel.org/r/20220412164059.42654-2-atrajeev@linux.vnet.ibm.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 23380e4d
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <linux/numa.h> #include <linux/numa.h>
#include <linux/zalloc.h> #include <linux/zalloc.h>
#include "../util/header.h"
#include <numa.h> #include <numa.h>
#include <numaif.h> #include <numaif.h>
...@@ -585,6 +586,11 @@ static int parse_setup_cpu_list(void) ...@@ -585,6 +586,11 @@ static int parse_setup_cpu_list(void)
return -1; return -1;
} }
if (is_cpu_online(bind_cpu_0) != 1 || is_cpu_online(bind_cpu_1) != 1) {
printf("\nTest not applicable, bind_cpu_0 or bind_cpu_1 is offline\n");
return -1;
}
BUG_ON(bind_cpu_0 < 0 || bind_cpu_1 < 0); BUG_ON(bind_cpu_0 < 0 || bind_cpu_1 < 0);
BUG_ON(bind_cpu_0 > bind_cpu_1); BUG_ON(bind_cpu_0 > bind_cpu_1);
...@@ -752,8 +758,6 @@ static int parse_nodes_opt(const struct option *opt __maybe_unused, ...@@ -752,8 +758,6 @@ static int parse_nodes_opt(const struct option *opt __maybe_unused,
return parse_node_list(arg); return parse_node_list(arg);
} }
#define BIT(x) (1ul << x)
static inline uint32_t lfsr_32(uint32_t lfsr) static inline uint32_t lfsr_32(uint32_t lfsr)
{ {
const uint32_t taps = BIT(1) | BIT(5) | BIT(6) | BIT(31); const uint32_t taps = BIT(1) | BIT(5) | BIT(6) | BIT(31);
......
...@@ -983,6 +983,57 @@ static int write_dir_format(struct feat_fd *ff, ...@@ -983,6 +983,57 @@ static int write_dir_format(struct feat_fd *ff,
return do_write(ff, &data->dir.version, sizeof(data->dir.version)); return do_write(ff, &data->dir.version, sizeof(data->dir.version));
} }
/*
* Check whether a CPU is online
*
* Returns:
* 1 -> if CPU is online
* 0 -> if CPU is offline
* -1 -> error case
*/
int is_cpu_online(unsigned int cpu)
{
char *str;
size_t strlen;
char buf[256];
int status = -1;
struct stat statbuf;
snprintf(buf, sizeof(buf),
"/sys/devices/system/cpu/cpu%d", cpu);
if (stat(buf, &statbuf) != 0)
return 0;
/*
* Check if /sys/devices/system/cpu/cpux/online file
* exists. Some cases cpu0 won't have online file since
* it is not expected to be turned off generally.
* In kernels without CONFIG_HOTPLUG_CPU, this
* file won't exist
*/
snprintf(buf, sizeof(buf),
"/sys/devices/system/cpu/cpu%d/online", cpu);
if (stat(buf, &statbuf) != 0)
return 1;
/*
* Read online file using sysfs__read_str.
* If read or open fails, return -1.
* If read succeeds, return value from file
* which gets stored in "str"
*/
snprintf(buf, sizeof(buf),
"devices/system/cpu/cpu%d/online", cpu);
if (sysfs__read_str(buf, &str, &strlen) < 0)
return status;
status = atoi(str);
free(str);
return status;
}
#ifdef HAVE_LIBBPF_SUPPORT #ifdef HAVE_LIBBPF_SUPPORT
static int write_bpf_prog_info(struct feat_fd *ff, static int write_bpf_prog_info(struct feat_fd *ff,
struct evlist *evlist __maybe_unused) struct evlist *evlist __maybe_unused)
......
...@@ -158,6 +158,7 @@ int do_write(struct feat_fd *fd, const void *buf, size_t size); ...@@ -158,6 +158,7 @@ int do_write(struct feat_fd *fd, const void *buf, size_t size);
int write_padded(struct feat_fd *fd, const void *bf, int write_padded(struct feat_fd *fd, const void *bf,
size_t count, size_t count_aligned); size_t count, size_t count_aligned);
int is_cpu_online(unsigned int cpu);
/* /*
* arch specific callback * arch specific callback
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment