linux-perf-users.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: tejas05 <tejas05@linux.ibm.com>
To: Athira Rajeev <atrajeev@linux.ibm.com>,
	acme@kernel.org, jolsa@kernel.org, adrian.hunter@intel.com,
	irogers@google.com, namhyung@kernel.org
Cc: linux-perf-users@vger.kernel.org, maddy@linux.ibm.com,
	kjain@linux.ibm.com, hbathini@linux.vnet.ibm.com,
	Aditya.Bodkhe1@ibm.com
Subject: Re: [PATCH] tools/perf/tests: Update perf record testcase to fix usage of affinity for machines with #CPUs > 1K
Date: Tue, 19 Aug 2025 17:26:29 +0530	[thread overview]
Message-ID: <eeaaf0e1-00ea-459f-b4e7-7167e88b8b1e@linux.ibm.com> (raw)
In-Reply-To: <20250814114908.45648-1-atrajeev@linux.ibm.com>

On 8/14/25 17:19, Athira Rajeev wrote:

> The perf record testcase fails on systems with more than 1K CPUs.
>
> Testcase: perf test -vv "PERF_RECORD_* events & perf_sample fields"
>
>    PERF_RECORD_* events & perf_sample fields                       :
>    --- start ---
>    test child forked, pid 272482
>    sched_getaffinity: Invalid argument
>    sched__get_first_possible_cpu: Invalid argument
>    test child finished with -1
>    ---- end ----
>    PERF_RECORD_* events & perf_sample fields: FAILED!
>
> sched__get_first_possible_cpu uses "sched_getaffinity" to get the
> cpumask and this call is returning EINVAL (Invalid argument).
> This happens because the default mask size in glibc is 1024.  To
> overcome this 1024 CPUs mask size limitation of cpu_set_t, change the
> mask size using the CPU_*_S macros ie, use CPU_ALLOC to allocate
> cpumask, CPU_ALLOC_SIZE for size. Same fix needed for mask which is
> used to setaffinity so that mask size is large enough to represent
> number of possible CPU's in the system.
>
> Reported-by: Tejas Manhas <tejas05@linux.ibm.com>
> Signed-off-by: Athira Rajeev <atrajeev@linux.ibm.com>
> ---
>   tools/perf/tests/perf-record.c | 36 ++++++++++++++++++++++++----------
>   1 file changed, 26 insertions(+), 10 deletions(-)
>
> diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c
> index 0b3c37e66871..d895df037707 100644
> --- a/tools/perf/tests/perf-record.c
> +++ b/tools/perf/tests/perf-record.c
> @@ -13,15 +13,19 @@
>   #include "tests.h"
>   #include "util/mmap.h"
>   #include "util/sample.h"
> +#include "util/cpumap.h"
>   
>   static int sched__get_first_possible_cpu(pid_t pid, cpu_set_t *maskp)
>   {
> -	int i, cpu = -1, nrcpus = 1024;
> +	int i, cpu = -1;
> +	int nrcpus = cpu__max_cpu().cpu;
> +	size_t size = CPU_ALLOC_SIZE(nrcpus);
> +
>   realloc:
> -	CPU_ZERO(maskp);
> +	CPU_ZERO_S(size, maskp);
>   
> -	if (sched_getaffinity(pid, sizeof(*maskp), maskp) == -1) {
> -		if (errno == EINVAL && nrcpus < (1024 << 8)) {
> +	if (sched_getaffinity(pid, size, maskp) == -1) {
> +		if (errno == EINVAL && nrcpus < (cpu__max_cpu().cpu << 8)) {
>   			nrcpus = nrcpus << 2;
>   			goto realloc;
>   		}
> @@ -30,11 +34,11 @@ static int sched__get_first_possible_cpu(pid_t pid, cpu_set_t *maskp)
>   	}
>   
>   	for (i = 0; i < nrcpus; i++) {
> -		if (CPU_ISSET(i, maskp)) {
> +		if (CPU_ISSET_S(i, size, maskp)) {
>   			if (cpu == -1)
>   				cpu = i;
>   			else
> -				CPU_CLR(i, maskp);
> +				CPU_CLR_S(i, size, maskp);
>   		}
>   	}
>   
> @@ -50,8 +54,9 @@ static int test__PERF_RECORD(struct test_suite *test __maybe_unused, int subtest
>   		.no_buffering = true,
>   		.mmap_pages   = 256,
>   	};
> -	cpu_set_t cpu_mask;
> -	size_t cpu_mask_size = sizeof(cpu_mask);
> +	int nrcpus = cpu__max_cpu().cpu;
> +	cpu_set_t *cpu_mask;
> +	size_t cpu_mask_size;
>   	struct evlist *evlist = evlist__new_dummy();
>   	struct evsel *evsel;
>   	struct perf_sample sample;
> @@ -69,12 +74,22 @@ static int test__PERF_RECORD(struct test_suite *test __maybe_unused, int subtest
>   	int total_events = 0, nr_events[PERF_RECORD_MAX] = { 0, };
>   	char sbuf[STRERR_BUFSIZE];
>   
> +	cpu_mask = CPU_ALLOC(nrcpus);
> +	if (!cpu_mask) {
> +		pr_debug("failed to create cpumask\n");
> +		goto out;
> +	}
> +
> +	cpu_mask_size = CPU_ALLOC_SIZE(nrcpus);
> +	CPU_ZERO_S(cpu_mask_size, cpu_mask);
> +
>   	perf_sample__init(&sample, /*all=*/false);
>   	if (evlist == NULL) /* Fallback for kernels lacking PERF_COUNT_SW_DUMMY */
>   		evlist = evlist__new_default();
>   
>   	if (evlist == NULL) {
>   		pr_debug("Not enough memory to create evlist\n");
> +		CPU_FREE(cpu_mask);
>   		goto out;
>   	}
>   
> @@ -111,7 +126,7 @@ static int test__PERF_RECORD(struct test_suite *test __maybe_unused, int subtest
>   	evsel__set_sample_bit(evsel, TIME);
>   	evlist__config(evlist, &opts, NULL);
>   
> -	err = sched__get_first_possible_cpu(evlist->workload.pid, &cpu_mask);
> +	err = sched__get_first_possible_cpu(evlist->workload.pid, cpu_mask);
>   	if (err < 0) {
>   		pr_debug("sched__get_first_possible_cpu: %s\n",
>   			 str_error_r(errno, sbuf, sizeof(sbuf)));
> @@ -123,7 +138,7 @@ static int test__PERF_RECORD(struct test_suite *test __maybe_unused, int subtest
>   	/*
>   	 * So that we can check perf_sample.cpu on all the samples.
>   	 */
> -	if (sched_setaffinity(evlist->workload.pid, cpu_mask_size, &cpu_mask) < 0) {
> +	if (sched_setaffinity(evlist->workload.pid, cpu_mask_size, cpu_mask) < 0) {
>   		pr_debug("sched_setaffinity: %s\n",
>   			 str_error_r(errno, sbuf, sizeof(sbuf)));
>   		goto out_delete_evlist;
> @@ -328,6 +343,7 @@ static int test__PERF_RECORD(struct test_suite *test __maybe_unused, int subtest
>   		++errs;
>   	}
>   out_delete_evlist:
> +	CPU_FREE(cpu_mask);
>   	evlist__delete(evlist);
>   out:
>   	perf_sample__exit(&sample);


Hi,

I have tested the patch on the setup where the issue was seen, the patch fixes the issue. Please add the tested-by tag as below.
Tested-by: Tejas Manhas<tejas05@linux.ibm.com>

Thanks & Regards
Tejas



  parent reply	other threads:[~2025-08-19 11:56 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-14 11:49 [PATCH] tools/perf/tests: Update perf record testcase to fix usage of affinity for machines with #CPUs > 1K Athira Rajeev
2025-08-14 12:23 ` Venkat
2025-08-14 20:23 ` Namhyung Kim
2025-08-20 17:20   ` Athira Rajeev
2025-08-19 11:56 ` tejas05 [this message]
2025-08-20 17:22   ` Athira Rajeev

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=eeaaf0e1-00ea-459f-b4e7-7167e88b8b1e@linux.ibm.com \
    --to=tejas05@linux.ibm.com \
    --cc=Aditya.Bodkhe1@ibm.com \
    --cc=acme@kernel.org \
    --cc=adrian.hunter@intel.com \
    --cc=atrajeev@linux.ibm.com \
    --cc=hbathini@linux.vnet.ibm.com \
    --cc=irogers@google.com \
    --cc=jolsa@kernel.org \
    --cc=kjain@linux.ibm.com \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=maddy@linux.ibm.com \
    --cc=namhyung@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).