From nobody Thu Dec 26 21:13:29 2024 Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A96624596E for ; Mon, 12 Feb 2024 18:59:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707764352; cv=none; b=NOx5yXPbZmEmVEIAz20dffNTgxiDMM23PkEDi6C2WNnRw6CezSBWMnQ2xfCzuOiFOxX8ZTMDCwLM04X7iy+tY/mpaJ41GxPdL1kCL2VEBgPOeGoRSJn7saBEgDQIZMy1WiXsSZYMKfeydGPdv3WfNy29qkfcpEihI7HU1E1czp8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707764352; c=relaxed/simple; bh=9GvaQ8U/ciyGf0POxeefEusSW20t+DHMSsugj/N6ETY=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=p9Xyycqz5OAzMP5x6AH9UXmDPib0it4ITP/p7IFBYBsdCSJo0wjWIu81r1avH+G3omxzL0ia4/VxTDZkEut3ZUsKuIB/oj2AGX650A6bbtKDmXTnTWqaJ0fid943lVfwbMkjC4oDP0TaQurvQ7Hm9o0rnVYgIcyUn3MZga/X5UM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=pma60R5z; arc=none smtp.client-ip=209.85.219.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="pma60R5z" Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-dc74645bfa8so126788276.1 for ; Mon, 12 Feb 2024 10:59:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1707764349; x=1708369149; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=F6UUwQ6uU0gh1AgBT5LAdlyWuLVQW/eRWP9wNVATd0w=; b=pma60R5zHeE04LRBeGIwCBhS8j+w+e2dINMD07Tw+sO5K5oDGkV3vTBu/jkDZmkF99 qwEVMpLxFthmRUMx5AxSQ8NEQ37PW5Irh1yLy8fLO2a2FKJKwL21V9PbXDDjLR/ieVfG JvxHiZHuxiWB8pXKIXI3cGDaorGndfGbxoODxJC4t2fMgrdw37Es6Yb8qRxf9Wp1Ob12 V5u0JG34Vf0PD5T73GviB9uZJLoFPmHh0nrkatnb7YrH6bysD6XKOxKAaCprEwDUS1Eq cTxkjM3E5s980bQ2KqFN5FXhuetSNbnh7EArJVqfsSEgQBRFwRwwYrIw2K1ebfZlMV53 DRzA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1707764349; x=1708369149; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=F6UUwQ6uU0gh1AgBT5LAdlyWuLVQW/eRWP9wNVATd0w=; b=ci7Abvej/wqf8tAeISXzj7mLKp5jVFGb5Pm8hT/tVp3wS/aU+eRN8ZFkJp8eqUv3/E kBk36CtRQYUcqa/3Ews3zUfb10+cR/5Iv5R/VnqbtyuhYqx7MdAWO9OWVI1D059xm17u jcvBDR4FbTHAUDgUzzeL0M38zM1TRMMaYopvJzAMJ5su418OdhoDneLAe8EA6XqnoxbC 7zawCsEI7tm9tUCTwxKAu9ILLLxUtSBzLo7Ts9dA6xIjvCeEk/LYaJk8mauqL1lM3nTY d9pz3VVyelmSwVoxv2sDo8dcbpuUa28q9W3ZnD+JWl691fNqBePSZ+snHC5jz58vPLtk slwg== X-Forwarded-Encrypted: i=1; AJvYcCUU8d8BZZc1glFfNspCYJVnRmkRxSlxPZhWP0j8uvqQxFoJtsWwjuCHsz3U6jxjdVFc7v6qcsGu7+oSZUPLXmqK7t81+Q207CJ7YNT4 X-Gm-Message-State: AOJu0YyXvicO59MrU6AZsSS1U43C9frMWSXEFrl0Ss7cnhGrYu2abi8h tyYCp5amLoFjuEKv1HkEV1AuQB1sQ2b2Cd7EAVEN3LjJFEKqDQLsONv3vvxdIyG5tCDWf/+5F19 2LSPySQ== X-Google-Smtp-Source: AGHT+IHSN4ECweWB1sjgp7X1buxa09RypuopSmFNaefe0SEaS78M3SDkr3wLQ4m5gAc4tVA7kyQuIFcZ7NsM X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:125c:bcda:4fe2:b6e6]) (user=irogers job=sendgmr) by 2002:a25:aa2a:0:b0:dcc:41ad:fb3b with SMTP id s39-20020a25aa2a000000b00dcc41adfb3bmr6327ybi.10.1707764349685; Mon, 12 Feb 2024 10:59:09 -0800 (PST) Date: Mon, 12 Feb 2024 10:58:51 -0800 In-Reply-To: <20240212185858.68189-1-irogers@google.com> Message-Id: <20240212185858.68189-2-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240212185858.68189-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.687.g38aa6559b0-goog Subject: [PATCH v3 1/8] perf thread_map: Skip exited threads when scanning /proc From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt , James Clark , Athira Jajeev , Kan Liang , Yang Jihong , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, llvm@lists.linux.dev Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Scanning /proc is inherently racy. Scanning /proc/pid/task within that is also racy as the pid can terminate. Rather than failing in __thread_map__new_all_cpus, skip pids for such failures. Signed-off-by: Ian Rogers --- tools/perf/util/thread_map.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c index ea3b431b9783..b5f12390c355 100644 --- a/tools/perf/util/thread_map.c +++ b/tools/perf/util/thread_map.c @@ -109,9 +109,10 @@ static struct perf_thread_map *__thread_map__new_all_c= pus(uid_t uid) =20 snprintf(path, sizeof(path), "/proc/%d/task", pid); items =3D scandir(path, &namelist, filter, NULL); - if (items <=3D 0) - goto out_free_closedir; - + if (items <=3D 0) { + pr_debug("scandir for %d returned empty, skipping\n", pid); + continue; + } while (threads->nr + items >=3D max_threads) { max_threads *=3D 2; grow =3D true; @@ -152,8 +153,6 @@ static struct perf_thread_map *__thread_map__new_all_cp= us(uid_t uid) for (i =3D 0; i < items; i++) zfree(&namelist[i]); free(namelist); - -out_free_closedir: zfree(&threads); goto out_closedir; } --=20 2.43.0.687.g38aa6559b0-goog From nobody Thu Dec 26 21:13:29 2024 Received: from mail-yw1-f201.google.com (mail-yw1-f201.google.com [209.85.128.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D2EDE4642B for ; Mon, 12 Feb 2024 18:59:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707764354; cv=none; b=rH1iE2AJTF+IRPQtjRPHenBwlGC6bu12TSc8UqQfGrkd2wvaAvFtn3lM0Qcm78xbYf8j+qbekmfcWYqg3UJU9WMZRKP4ACwTugvYHsy3GAw5NF3JCMSvYYkATrfNDwzJApqKmuHjJJ6wneH6hK8D/BmjMAYImgI8BhBAGVvMGes= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707764354; c=relaxed/simple; bh=n2O402eXl0NfPZxZpyKpmaH2tTNJfdr2mDOm+fQw/Cc=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=gOl9oMZXrRrb+9DAb407Wrq+/jUHRrSMfng5JAb0OFd9Hzdgre+RT3LJr1uCER8a0FMN/RMilbejiK31p1Pp7ypSq3GXzzkyYI2JqoQOO0veKZKRfXOxln8cJ4R0ZLeYpUTEzl5cjpcMNFY/TMK7nuTb/QZ/vZH45Ea+6XgYXE0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=Z/0YUCyk; arc=none smtp.client-ip=209.85.128.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="Z/0YUCyk" Received: by mail-yw1-f201.google.com with SMTP id 00721157ae682-60665b5fabcso2278977b3.1 for ; Mon, 12 Feb 2024 10:59:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1707764352; x=1708369152; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=OIfZNhk3eeeHKa2Xi7smZJqgcOWfMoStAIdRAdrChFA=; b=Z/0YUCykgJfwMNAuJWZAhKye2bUj0YwVfdISaZBnDa7acXWcFuPB+xOK+Ywh7bdCT7 VwZaRPHSxsUQmQTGmY1N112s0CT1499Yq6yLNWoP+/KCQtmgIwM2nWl8dU71faR1mt/g CZnbNJ9nuucb6+y72lvlZiF3hXUkB6tlx/XCRgIacXVG+E/AmBlehDXmvROWCfJEvp/3 Vo31kejJaAci/LsQPNeZNPwo7bQatJf1/EjUCEmpbkfe6IlQNgNaUtVwcMikvSvZw6Cl goNU92ZBh0F2rNoGZHCmJbk0ieauMWjNYCp09qrfGGGPbMMn01Rpi1aimFrLrJ+8CzJb IlpQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1707764352; x=1708369152; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=OIfZNhk3eeeHKa2Xi7smZJqgcOWfMoStAIdRAdrChFA=; b=j8CLaWLz03BogF82rqiK7ew3JFuhmFrgRdpebMd6ni88U86EFILPNQAmzMzWNe6RY/ z34Pp9CZmCBsHJftK6yKELUzqUkodE+UcVRYAxpcD8sxPTVfQ7dwaoL+yzBq5cZWaGxq 1XEW70bmIRQjbZ4J2yb/+ajxaJrXELC4ESaGFsNSsoxtwKnnooUXiCqUyQ29LS9iojO4 GOwBI1EdKugnIwTV4aeEm87YPSLFn0NXft0g5rXQAKLQl6G7SrAEMBaFH7Wc9y9F5T1T mgBaS0UXTypfVbyOeZiqJ6RVnFjlSVERzwMWm7+FzUNSpWLfInzb9R/DDrQKQWDpTNPb KbgQ== X-Gm-Message-State: AOJu0YwYiDT7179NzH/GHztob7QkYelPa1YIhM+VDNAEnJsApSIgC/U2 NbVqOFQuRgLqpYE9hMuQ/nf0Rsbe7Pv532FRYZhA8NCMW4197+zBVgXVKaKH4x42Kfc4VKRQiR3 NrC8UyA== X-Google-Smtp-Source: AGHT+IEy+Jg0Tj/ybPHU3HIvQArQsZS1I7w8worYnB6VQTB+CTcX6kNyH0cRnpkyL81Q6ve0Mct9ZogKPFED X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:125c:bcda:4fe2:b6e6]) (user=irogers job=sendgmr) by 2002:a05:690c:884:b0:604:d53e:4616 with SMTP id cd4-20020a05690c088400b00604d53e4616mr1320135ywb.6.1707764351840; Mon, 12 Feb 2024 10:59:11 -0800 (PST) Date: Mon, 12 Feb 2024 10:58:52 -0800 In-Reply-To: <20240212185858.68189-1-irogers@google.com> Message-Id: <20240212185858.68189-3-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240212185858.68189-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.687.g38aa6559b0-goog Subject: [PATCH v3 2/8] perf list: Add scandirat compatibility function From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt , James Clark , Athira Jajeev , Kan Liang , Yang Jihong , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, llvm@lists.linux.dev Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" scandirat is used during the printing of tracepoint events but may be missing from certain libcs. Add a compatibility implementation that uses the symlink of an fd in /proc as a path for the reliably present scandir. Signed-off-by: Ian Rogers --- tools/perf/util/print-events.c | 12 +++--------- tools/perf/util/util.c | 19 +++++++++++++++++++ tools/perf/util/util.h | 8 ++++++++ 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c index b0fc48be623f..15ec55b07bfd 100644 --- a/tools/perf/util/print-events.c +++ b/tools/perf/util/print-events.c @@ -63,6 +63,8 @@ void print_tracepoint_events(const struct print_callbacks= *print_cb __maybe_unus { char *events_path =3D get_tracing_file("events"); int events_fd =3D open(events_path, O_PATH); + struct dirent **sys_namelist =3D NULL; + int sys_items; =20 put_tracing_file(events_path); if (events_fd < 0) { @@ -70,10 +72,7 @@ void print_tracepoint_events(const struct print_callback= s *print_cb __maybe_unus return; } =20 -#ifdef HAVE_SCANDIRAT_SUPPORT -{ - struct dirent **sys_namelist =3D NULL; - int sys_items =3D tracing_events__scandir_alphasort(&sys_namelist); + sys_items =3D tracing_events__scandir_alphasort(&sys_namelist); =20 for (int i =3D 0; i < sys_items; i++) { struct dirent *sys_dirent =3D sys_namelist[i]; @@ -130,11 +129,6 @@ void print_tracepoint_events(const struct print_callba= cks *print_cb __maybe_unus } =20 free(sys_namelist); -} -#else - printf("\nWARNING: Your libc doesn't have the scandirat function, please = ask its maintainers to implement it.\n" - " As a rough fallback, please do 'ls %s' to see the availa= ble tracepoint events.\n", events_path); -#endif close(events_fd); } =20 diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index c1fd9ba6d697..4f561e5e4162 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -552,3 +552,22 @@ int sched_getcpu(void) return -1; } #endif + +#ifndef HAVE_SCANDIRAT_SUPPORT +int scandirat(int dirfd, const char *dirp, + struct dirent ***namelist, + int (*filter)(const struct dirent *), + int (*compar)(const struct dirent **, const struct dirent **)) +{ + char path[PATH_MAX]; + int err, fd =3D openat(dirfd, dirp, O_PATH); + + if (fd < 0) + return fd; + + snprintf(path, sizeof(path), "/proc/%d/fd/%d", getpid(), fd); + err =3D scandir(path, namelist, filter, compar); + close(fd); + return err; +} +#endif diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 7c8915d92dca..9966c21aaf04 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -6,6 +6,7 @@ /* glibc 2.20 deprecates _BSD_SOURCE in favour of _DEFAULT_SOURCE */ #define _DEFAULT_SOURCE 1 =20 +#include #include #include #include @@ -56,6 +57,13 @@ int perf_tip(char **strp, const char *dirpath); int sched_getcpu(void); #endif =20 +#ifndef HAVE_SCANDIRAT_SUPPORT +int scandirat(int dirfd, const char *dirp, + struct dirent ***namelist, + int (*filter)(const struct dirent *), + int (*compar)(const struct dirent **, const struct dirent **)); +#endif + extern bool perf_singlethreaded; =20 void perf_set_singlethreaded(void); --=20 2.43.0.687.g38aa6559b0-goog From nobody Thu Dec 26 21:13:29 2024 Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 28D3547A48 for ; Mon, 12 Feb 2024 18:59:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707764356; cv=none; b=YyjB8ggGzLqVYGUZpgby1KXJg2h8OiBfbD4vZnoCBHsLuzzbdQJuqu21B5Neua9QIOnua4J5rXBqidryROjrVG3816VeBLkGNWD7zWmEAt7JZBsZTDEa0N3XCB0UG0EaJBeWRsBsAWV7bRFU8tLrFIGJe1WXDpzS43NiYK57Rro= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707764356; c=relaxed/simple; bh=cEoquvI2Ge+v6/Ow4yXCwb905NVQF3PwLLtFQnXzKG0=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=R09PvgKxLF+kDuck2E42pgvpz6CpTfRMXn5ZJUt5ljkPjFa7fo6F9yfAqpdYp1ZmaQ7y/MBPZ/zVMdEb14LC4/JLGEdclJcCDaKLGdYMpALo9JymO3WoQblKzelum6MRw6zsYX6SISzVuBZKyS0zCH7WUJVI9l5P863z2okoHy0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=b3qyvL7h; arc=none smtp.client-ip=209.85.219.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="b3qyvL7h" Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-dc6dbdcfd39so7316678276.2 for ; Mon, 12 Feb 2024 10:59:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1707764354; x=1708369154; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=WQsEsQdYL+F7rq54Mfa+75HgoPY/TwxmW9rhD6V78kU=; b=b3qyvL7hKvSiShvVNQaxcvEvKsCZdzosqakFJkI3oZze12klYVVyv1VSYZdXvbJX5I 1dudKCo/MwdMVTFpmL5z/f491Q2zeNtfWT9NMVTCPbXyzOMRc88lAVsq818iVh/hxC35 weS46+ZmJKtiHwJ3w+y9jkHGDSMSaQB7prK1g3zumZ3N/eGTh+qHaZsjRKjX3SXFU4dh nJL2r3ZK2+U+qKeHKrIqBXYA9oq0Z7M5Toow35y6fOvPMMa48vek2D48ATwjVbnUd4JX yu6P0FUgHcvFmVM3WiMI/MSwz/tE8+bmecubIhOekMLWmj08gYf7pLigFLrwO9rt7uKD CZ2g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1707764354; x=1708369154; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=WQsEsQdYL+F7rq54Mfa+75HgoPY/TwxmW9rhD6V78kU=; b=owHHbjHevh6paNbsNBJ6GzTxXJMXQ/amWr//JPzHalXr5NCSWnRzj+4uGoSMRtU++x C06lA+uH4NEKv1z+RWHapp+IxIZH4nqDPCGDWDdwQ+QUnHxdPzFwN5UGKs8u6p4LTfyc RNxdSk4Ee3dJAx/l4f9ZNtlUJTQiqf2aCULbiC/aSaRL4tyqvx7h6njMaZhMwBcjZ9Xl P5MWIfQp5t8QV0PnQdCG8OqsjpPUmVXbGsWcvRFmVQkbwrtzSAttN1boh55bXxMqMR8A EB3+ABfLtnFKTuLFWcT/SiCJDjm+a1KFp+OUeFqgHH97IM3+APd1dst1p++1WbNyfzYu XLaQ== X-Gm-Message-State: AOJu0YxiQ9RNEIKiQL2lacNdc3Kw0OeWbvX6j5vMQM2qH1hE5g6s025D gM4SYptgcEdE3qi1TWn83SEkDbbqufkHh3iJJdygWCeY3WOMaA/dgSmG+kPIcVdrgXlxb0xq6SI eE846aw== X-Google-Smtp-Source: AGHT+IHiKcmNRG+oK564DasQqJu4KLrzYsGTIqh58ndlp5tR6/bM86Cw+35Q8wd8t+rVtSAhwGVk7oS7/43U X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:125c:bcda:4fe2:b6e6]) (user=irogers job=sendgmr) by 2002:a05:6902:10c2:b0:dc6:d2c8:6e50 with SMTP id w2-20020a05690210c200b00dc6d2c86e50mr1160978ybu.7.1707764353986; Mon, 12 Feb 2024 10:59:13 -0800 (PST) Date: Mon, 12 Feb 2024 10:58:53 -0800 In-Reply-To: <20240212185858.68189-1-irogers@google.com> Message-Id: <20240212185858.68189-4-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240212185858.68189-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.687.g38aa6559b0-goog Subject: [PATCH v3 3/8] perf tests: Avoid fork in perf_has_symbol test From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt , James Clark , Athira Jajeev , Kan Liang , Yang Jihong , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, llvm@lists.linux.dev Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" perf test -vv Symbols is used to indentify symbols within the perf binary. Add the -F flag so that the test command doesn't fork the test before running. This removes a little overhead. Signed-off-by: Ian Rogers Acked-by: Adrian Hunter --- tools/perf/tests/shell/lib/perf_has_symbol.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/tests/shell/lib/perf_has_symbol.sh b/tools/perf/tes= ts/shell/lib/perf_has_symbol.sh index 5d59c32ae3e7..561c93b75d77 100644 --- a/tools/perf/tests/shell/lib/perf_has_symbol.sh +++ b/tools/perf/tests/shell/lib/perf_has_symbol.sh @@ -3,7 +3,7 @@ =20 perf_has_symbol() { - if perf test -vv "Symbols" 2>&1 | grep "[[:space:]]$1$"; then + if perf test -vv -F "Symbols" 2>&1 | grep "[[:space:]]$1$"; then echo "perf does have symbol '$1'" return 0 fi --=20 2.43.0.687.g38aa6559b0-goog From nobody Thu Dec 26 21:13:29 2024 Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2379D47F6C for ; Mon, 12 Feb 2024 18:59:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707764359; cv=none; b=drwzasdiLwS6DcHCzlQMP8FU6N9XIHT9OldJqYiS0o8TchfmMveGVV4NSRYxPeXfhkfTPS0xQpXqs9bvEtb8YYpYUcgsKv8rdcbIEiw4froMI9RbNcc+8XvjupwIsGzE0nqguPBaQW+HQ6jx8UkoDULyS+sj14S9N7vuV23vlZc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707764359; c=relaxed/simple; bh=LBou+XLQ8QDVF7i9zNrb0c+TC2HDLKGD9kRdzvqDd8M=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=D7ggRGq35O5TkQPn/MYXibxMAKB21+uofn8+FVOs223XUC/uyR/DqlKbovZoXqUW5lLzHuhKJlFgR4JoNss0ed4VFAivclmu19Qavo6jKe1N2XwT7cOkUapaQUT+l3/L/kw2qBJ3b6majYKte1dOrpGU7471Cm7bqEdtLmtAxYI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=HGs80CWM; arc=none smtp.client-ip=209.85.219.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="HGs80CWM" Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-dcbc447ddfeso725685276.1 for ; Mon, 12 Feb 2024 10:59:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1707764356; x=1708369156; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=FAs57lgcOMUxLgf079L8itwe0kfFXp2CsT7fDYu4PDI=; b=HGs80CWMzD8pcAUY1jRbxc/aYbownwLRYBYA83vBUAtJYVtFpKvup9XaGpO0muRX6S dtKmOKiTT2Mon+xo0DqCzxqKnyBx0luCM/Xuig3+tVnlA2laEzAfIJNyOar7iTrQ/vcV Bdc06BggdZddTwXW6xjZSVlXdU1VRLoSb8jOY541/2W8c3GV0SdOthe3si8zT1IvkxLw k4u5C8CcsVG/3oS62NCzBMXW1pizYRfKPV6nTk4PmjyOauAthQ7oaUfiCDrZPKR9Y0tk FAXHVuUaOz8ik1VrvH5YENVMP5MHwLqoBMz7HhbN/uk1YF+qLZ5fExsY6bEs0ERXPK8k FWpA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1707764356; x=1708369156; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=FAs57lgcOMUxLgf079L8itwe0kfFXp2CsT7fDYu4PDI=; b=IZn0wMEfiimvtrZhW1oPQvcLpLKIbSjLd5rcviMeCcCQhCfw20a52srx0NoA8uv/Jp IGxptU9BymOgzOCiBMg7sd64FOoTf4K9bzxCeXoQaaW4fIHxtBj4VCldidll021MbL2x daQ9tv45ZlSnzA6G/I+hwZVBQrp4EeJdz5NCtpN529D+UBf5Rox0defhMfIUmACIxS4P DouXOwXDlyRtzhCZbit6JrvbE5pGQnBsVXv1cPDNgxcbtCui2DiANQcI5UWk87y6i4RW UUN9rb+IZX9Z0AieWoV9STatdqqPKd0Rtl8VFz3EQtjdubLqGiLC7svn1ml4AsliOuEE vBvQ== X-Forwarded-Encrypted: i=1; AJvYcCWp4Zp4qMMR6HS9Oy012d6TZCxZpZhAHwOe4f+bh2dGIRiziIHcquq2Nrq82/cTsYrZTiiQKc8iNnq9rxiKJQX73O+e7rjqDXs1Fxw0 X-Gm-Message-State: AOJu0YwH+ep+VRjoWrAD0l/oC9j666BSjsPQodXAuGbI+Q00MaDM3mnT 7ZBEAoKalNSDxXASRwKDOKB7C7X7D0/gvOcmfw5rDhIuCUr7RRc/6NPMzBlkjNeAaDBW5gkNs8v J4fYi9g== X-Google-Smtp-Source: AGHT+IFKUUMT3n7DkY6OIeWV+e7Wky9FtU2Gzr+NBHztBUsnln24BvN1I4nBHu3pAe9rRC8RqMKIOJHyh6k+ X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:125c:bcda:4fe2:b6e6]) (user=irogers job=sendgmr) by 2002:a05:6902:1007:b0:dc6:e20f:80cb with SMTP id w7-20020a056902100700b00dc6e20f80cbmr348338ybt.3.1707764356106; Mon, 12 Feb 2024 10:59:16 -0800 (PST) Date: Mon, 12 Feb 2024 10:58:54 -0800 In-Reply-To: <20240212185858.68189-1-irogers@google.com> Message-Id: <20240212185858.68189-5-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240212185858.68189-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.687.g38aa6559b0-goog Subject: [PATCH v3 4/8] tools subcmd: Add a no exec function call option From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt , James Clark , Athira Jajeev , Kan Liang , Yang Jihong , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, llvm@lists.linux.dev Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Tools like perf fork tests in case they crash, but they don't want to exec a full binary. Add an option to call a function rather than do an exec. The child process exits with the result of the function call and is passed the struct of the run_command, things like container_of can then allow the child process function to determine additional arguments. Signed-off-by: Ian Rogers --- tools/lib/subcmd/run-command.c | 2 ++ tools/lib/subcmd/run-command.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tools/lib/subcmd/run-command.c b/tools/lib/subcmd/run-command.c index 5cdac2162532..d435eb42354b 100644 --- a/tools/lib/subcmd/run-command.c +++ b/tools/lib/subcmd/run-command.c @@ -122,6 +122,8 @@ int start_command(struct child_process *cmd) } if (cmd->preexec_cb) cmd->preexec_cb(); + if (cmd->no_exec_cmd) + exit(cmd->no_exec_cmd(cmd)); if (cmd->exec_cmd) { execv_cmd(cmd->argv); } else { diff --git a/tools/lib/subcmd/run-command.h b/tools/lib/subcmd/run-command.h index 17d969c6add3..d794138a797f 100644 --- a/tools/lib/subcmd/run-command.h +++ b/tools/lib/subcmd/run-command.h @@ -47,6 +47,8 @@ struct child_process { unsigned exec_cmd:1; /* if this is to be external sub-command */ unsigned stdout_to_stderr:1; void (*preexec_cb)(void); + /* If set, call function in child rather than doing an exec. */ + int (*no_exec_cmd)(struct child_process *process); }; =20 int start_command(struct child_process *); --=20 2.43.0.687.g38aa6559b0-goog From nobody Thu Dec 26 21:13:29 2024 Received: from mail-yb1-f201.google.com (mail-yb1-f201.google.com [209.85.219.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 95508481C2 for ; Mon, 12 Feb 2024 18:59:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707764361; cv=none; b=LNdFU3/OR+xpdsVuup+wWKZqZSVW6elGNJXI0J94rGtPzuuNcLXQXh3sTQDbEdPZYXfwsOUEpQbwoOqWx71H1Hgu0r+Gfoz3El4tW+zQBI6jOX8POcvp9w+9QnAqGhn4KGXsPOGuy8LAfIfqozrC3sNbpFvk4YVTkcdYQidR1X4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707764361; c=relaxed/simple; bh=d/hQVr7HLwaHgpbOrtRFt5ktwlU8Fbwq9EyeSqxfkuQ=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=PHnJV7qXkBQ5Vn1PsQHOIloLiZKIYMrYvbuYVnfdUiw3FKQBF22oC0WDDBi7VzRTaoI2liUWXSnd7q+IrC1MWZa9Ivz0faSIhiSlx+M4T1JYSQp7ceJz3sMTsAMSVkViTrQBeiNai3WSPVCeKj2Bqp1PSOAqwB9iiUuQVKk1XFQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=nfm8stO0; arc=none smtp.client-ip=209.85.219.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="nfm8stO0" Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-dcc4563611cso91259276.3 for ; Mon, 12 Feb 2024 10:59:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1707764358; x=1708369158; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=ORLaSbqJ7XxCjGmPCGfASaJCafSHFkQjULJrCBkVFqo=; b=nfm8stO0KYzzkP4P+Tp2w0E4WtZJyzqmz/HJXxxURLoqyfbAh4TizitH0krHm4FBJ1 3/8Bls53sKDsGG9VhF4IEjM8NgdYV0QtHmjqyE+yah5mFw5ahYfi9nt4Knu+Xkvoq4+z wYLClti3uaX37SZjZRluHoM0UNS8i9rde3LhQA/4dvQYZUih3VctBUGWh9coP+3EUgoZ VppjjN2c8PWmJ9lcy1QILsfJ4Pc9AXAP4ah45JKjPwpOXDlg9Hw495ReiZ/qgx1wGYJj ofQz76wHT+4stLCUoAsN5bD7Qa49f24YernNIHZwihw87N2d3S7FNzwXqDP7Wx5bbCWd 91zQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1707764358; x=1708369158; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=ORLaSbqJ7XxCjGmPCGfASaJCafSHFkQjULJrCBkVFqo=; b=YPDDPwMUIq7WhvHENlBqG01gIDPczNL4hkuMTuAgmXq32zOIHR3PcXy2O7Mjgm44lY 2SsqVe5V0/7zFNDxmNDxBAw/RY806bvEdt475kJJeGUE7cxiugwXMeqjEVPUgmkkic0S o0Qvqgst7nciJpJvgyhXqChhNZN95Ok9Kct6/9v7kzpxIlTyUi4/r9PeNA2GNB0J2HWB IeJj7cB4yBwHF1mT9Os1g6/fsxoGMjGnaD1heMpw1lO6Ii1EPxttZgzmxh13PbZabqeR djCfRny823aqI0TawCX6HxsbRR13qpzBuG1RflG3yYbWvfBsKFjkCAmE7n0h4h3o0df8 Zf0g== X-Forwarded-Encrypted: i=1; AJvYcCVCFHNNtJePZ9g6R33og+cMisenrn4c2PCAH9oSvJ2EloGf05gS6aaydNHvVMu4mbt0XsChf7Ltbt0ixYRdWMZp6XVpXhE84DFVc+6d X-Gm-Message-State: AOJu0YwMpJEhu7+hwtOaU0iSF5QIs/rimMFEm/Sa3w8DuR67HSmar/uH kHb9mV1/rqrbwRArXaPlN5v83CIlP6u//3L1g5PYbm0aHZMaeJBObAKk+wO7p1DOdk4dl5+6ThG ddQ7XSQ== X-Google-Smtp-Source: AGHT+IEgg5F6/JDC9O18WbAqy6Jn09Lk9KedltE8Flre9vl6bkzkS2WkyxJZcH+1HD8YPk9Has0tt+LZbMMt X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:125c:bcda:4fe2:b6e6]) (user=irogers job=sendgmr) by 2002:a05:6902:1027:b0:dc2:550b:a4f4 with SMTP id x7-20020a056902102700b00dc2550ba4f4mr1970106ybt.1.1707764358452; Mon, 12 Feb 2024 10:59:18 -0800 (PST) Date: Mon, 12 Feb 2024 10:58:55 -0800 In-Reply-To: <20240212185858.68189-1-irogers@google.com> Message-Id: <20240212185858.68189-6-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240212185858.68189-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.687.g38aa6559b0-goog Subject: [PATCH v3 5/8] perf test: Rename builtin-test-list and add missed header guard From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt , James Clark , Athira Jajeev , Kan Liang , Yang Jihong , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, llvm@lists.linux.dev Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" builtin-test-list is primarily concerned with shell script tests. Rename the file to better reflect this and add a missed header guard. Signed-off-by: Ian Rogers --- tools/perf/tests/Build | 2 +- tools/perf/tests/builtin-test.c | 2 +- tools/perf/tests/{builtin-test-list.c =3D> tests-scripts.c} | 2 +- tools/perf/tests/{builtin-test-list.h =3D> tests-scripts.h} | 4 ++++ 4 files changed, 7 insertions(+), 3 deletions(-) rename tools/perf/tests/{builtin-test-list.c =3D> tests-scripts.c} (99%) rename tools/perf/tests/{builtin-test-list.h =3D> tests-scripts.h} (79%) diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build index 53ba9c3e20e0..c7f9d9676095 100644 --- a/tools/perf/tests/Build +++ b/tools/perf/tests/Build @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 =20 perf-y +=3D builtin-test.o -perf-y +=3D builtin-test-list.o +perf-y +=3D tests-scripts.o perf-y +=3D parse-events.o perf-y +=3D dso-data.o perf-y +=3D attr.o diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-tes= t.c index 4a5973f9bb9b..eff3c62e9b47 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -29,7 +29,7 @@ #include #include =20 -#include "builtin-test-list.h" +#include "tests-scripts.h" =20 static bool dont_fork; const char *dso_to_test; diff --git a/tools/perf/tests/builtin-test-list.c b/tools/perf/tests/tests-= scripts.c similarity index 99% rename from tools/perf/tests/builtin-test-list.c rename to tools/perf/tests/tests-scripts.c index a65b9e547d82..4ebd841da05b 100644 --- a/tools/perf/tests/builtin-test-list.c +++ b/tools/perf/tests/tests-scripts.c @@ -15,7 +15,7 @@ #include #include #include "builtin.h" -#include "builtin-test-list.h" +#include "tests-scripts.h" #include "color.h" #include "debug.h" #include "hist.h" diff --git a/tools/perf/tests/builtin-test-list.h b/tools/perf/tests/tests-= scripts.h similarity index 79% rename from tools/perf/tests/builtin-test-list.h rename to tools/perf/tests/tests-scripts.h index eb81f3aa6683..3a3ec6191848 100644 --- a/tools/perf/tests/builtin-test-list.h +++ b/tools/perf/tests/tests-scripts.h @@ -1,4 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ +#ifndef TESTS_SCRIPTS_H +#define TESTS_SCRIPTS_H =20 struct script_file { char *dir; @@ -10,3 +12,5 @@ struct script_file { const struct script_file *list_script_files(void); /* Get maximum width of description string */ int list_script_max_width(void); + +#endif /* TESTS_SCRIPTS_H */ --=20 2.43.0.687.g38aa6559b0-goog From nobody Thu Dec 26 21:13:29 2024 Received: from mail-yb1-f201.google.com (mail-yb1-f201.google.com [209.85.219.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B379645C14 for ; Mon, 12 Feb 2024 18:59:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707764363; cv=none; b=O8LveCVco4WECY+Gn0/f/GDQBHB6Y7lH4l6qmn7ZBoUV5uDNB/lY66e16lat7/gi8C1ZxHC8xF4I4A96iy56wxf6PgWP2pLyr7fJPiDAkMq8yIWK4mOc4dBHv/QsGxSKxKQMtHLbVW08R+BoVZayxul55Yxe9J/qUZJgFAz2edM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707764363; c=relaxed/simple; bh=pokSEbOrag3uWdO1RhTKTOPvPSFp8ZMJI6bQo7DbnNA=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=uMHXqw0eEuHizsqctw5M8nudd3E4BNoUhVR8n6eGdFfxYepdHWB/b4yEQndgNRhERZTlwqpT9T2g9/1TvEoMpVL/B8QbsrYa29TCfsaigTxvvHRQ2k5z0W261y3yXN8+k9JoHDZrIfjfUS966BvsdkFj5JGl9CCWe3KVrJ3fwmY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=VJyBcTrZ; arc=none smtp.client-ip=209.85.219.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="VJyBcTrZ" Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-dc6b269b172so5768206276.1 for ; Mon, 12 Feb 2024 10:59:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1707764361; x=1708369161; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=mEeFv0uon5WQC9cFYvgD6Kwx90gDUxQUuXbCDfN9dJU=; b=VJyBcTrZUBi5oZMBg6/NziPWTE5l63C+eegMy4hvn2u1fzJdXhxZXJynWerDIdnnsm hGqsnsBA+/P5Tvs5P4HBWph2ELiMM6DwNz3tz7JeYbwylImdmlvmKWzNC9El0oVUQwKP kFyWDi3mF0ZQpk9AtKrwePZQ6+fFRH7v50t7KX6eQzIpWqRJpwfMs+uN7bHcKcSd6B3F d5qowv4SL1d2wE3qnsaUY0EzzmrnDklS7nXsRiVaLNOpL11MzDOYJcXODklmGWQPq6OA jeZLHMkINn6/iMHZC+t1zNSs0zWP3f0IKOpyZ0NPQRwBZH4oN6kYZMIuve336JSLb0ui eNWQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1707764361; x=1708369161; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=mEeFv0uon5WQC9cFYvgD6Kwx90gDUxQUuXbCDfN9dJU=; b=qY57+J+spqBP/V9f51rwVDwbXKZYF9ggOq/PZMmf99WKgSYz3hRXTArCO0WU64h2HJ mIn43h5U3MlWK1Oqv4TZxkQyQCGEus8dKIJ7ffp5zf8OVpyD1h8u4xcFVnlpFNA7Zibn lz85f+tG/9L5shrVkI5idZLCIhTlFgC7aF769tEDAt9t1o7NsGNoW9KsxkNEGtMQWlr7 jjpB/k7BKPQE5hbKOAIAVKOoah1UQwdrPGNwifm/JI3MPcO0odJicyuOOm69mX25GU4T FoV23MEIXAEhRuruPPj8ReZqItIEP2anbOq59FhvMA/1RkTL1RCRmciruQsXBdKCtIh+ /XMg== X-Forwarded-Encrypted: i=1; AJvYcCVvsFibKk7WDCbXDLGJS8AwqL1B+nlQh6e0g2AzExLVp1KYwKN1KZtbuuIlfuQd9PVD9/YKRcVX0h6B/xdW33S3L8P4DawaMsSqT9Pc X-Gm-Message-State: AOJu0Yzh6NQIpYxBpBlqUEWb94qdKFJw20Pm+nB+4nFrUQSb+7SxVudg IaEPaC0KmhtjAQ1na+kDYbey4Mx3PnIOBkNUU1fO7KH1RbFH7JCsPFtzr6x/GvAPdWUVRzA+q6w eX4JlBw== X-Google-Smtp-Source: AGHT+IEO1PiMz3c0RZTIoYJezmJDkE3dGRBEbQ9aT7WtE501MYAM1moyGkhzIzhdVkLI5mUBKa4Uy1qhvLLj X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:125c:bcda:4fe2:b6e6]) (user=irogers job=sendgmr) by 2002:a05:6902:1209:b0:dc7:7655:46ce with SMTP id s9-20020a056902120900b00dc7765546cemr64080ybu.2.1707764360768; Mon, 12 Feb 2024 10:59:20 -0800 (PST) Date: Mon, 12 Feb 2024 10:58:56 -0800 In-Reply-To: <20240212185858.68189-1-irogers@google.com> Message-Id: <20240212185858.68189-7-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240212185858.68189-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.687.g38aa6559b0-goog Subject: [PATCH v3 6/8] perf tests: Use scandirat for shell script finding From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt , James Clark , Athira Jajeev , Kan Liang , Yang Jihong , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, llvm@lists.linux.dev Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Avoid filename appending buffers by using openat, faccessat and scandirat more widely. Turn the script's path back to a file name using readlink from /proc//fd/. Read the script's description using api/io.h to avoid fdopen conversions. Whilst reading perform additional sanity checks on the script's contents. Signed-off-by: Ian Rogers --- tools/perf/tests/builtin-test.c | 21 ++--- tools/perf/tests/tests-scripts.c | 144 ++++++++++++++++++------------- tools/perf/tests/tests-scripts.h | 1 - 3 files changed, 95 insertions(+), 71 deletions(-) diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-tes= t.c index eff3c62e9b47..6d5001daaf63 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -300,22 +300,20 @@ static int test_and_print(struct test_suite *t, int s= ubtest) } =20 struct shell_test { - const char *dir; const char *file; }; =20 static int shell_test__run(struct test_suite *test, int subdir __maybe_unu= sed) { int err; - char script[PATH_MAX]; struct shell_test *st =3D test->priv; + char *cmd; =20 - path__join(script, sizeof(script) - 3, st->dir, st->file); - - if (verbose > 0) - strncat(script, " -v", sizeof(script) - strlen(script) - 1); - - err =3D system(script); + asprintf(&cmd, "%s%s", st->file, verbose ? " -v" : ""); + if (!cmd) + return TEST_FAIL; + err =3D system(cmd); + free(cmd); if (!err) return TEST_OK; =20 @@ -331,7 +329,7 @@ static int run_shell_tests(int argc, const char *argv[]= , int i, int width, files =3D list_script_files(); if (!files) return 0; - for (file =3D files; file->dir; file++) { + for (file =3D files; file->file; file++) { int curr =3D i++; struct test_case test_cases[] =3D { { @@ -345,13 +343,12 @@ static int run_shell_tests(int argc, const char *argv= [], int i, int width, .test_cases =3D test_cases, .priv =3D &st, }; - st.dir =3D file->dir; + st.file =3D file->file; =20 if (test_suite.desc =3D=3D NULL || !perf_test__matches(test_suite.desc, curr, argc, argv)) continue; =20 - st.file =3D file->file; pr_info("%3d: %-*s:", i, width, test_suite.desc); =20 if (intlist__find(skiplist, i)) { @@ -455,7 +452,7 @@ static int perf_test__list_shell(int argc, const char *= *argv, int i) files =3D list_script_files(); if (!files) return 0; - for (file =3D files; file->dir; file++) { + for (file =3D files; file->file; file++) { int curr =3D i++; struct test_suite t =3D { .desc =3D file->desc diff --git a/tools/perf/tests/tests-scripts.c b/tools/perf/tests/tests-scri= pts.c index 4ebd841da05b..9b3b66dd5508 100644 --- a/tools/perf/tests/tests-scripts.c +++ b/tools/perf/tests/tests-scripts.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "builtin.h" #include "tests-scripts.h" #include "color.h" @@ -35,55 +36,69 @@ static size_t files_num =3D 0; static struct script_file *files =3D NULL; static int files_max_width =3D 0; =20 -static const char *shell_tests__dir(char *path, size_t size) +static int shell_tests__dir_fd(void) { - const char *devel_dirs[] =3D { "./tools/perf/tests", "./tests", }; - char *exec_path; - unsigned int i; + char path[PATH_MAX], *exec_path; + static const char * const devel_dirs[] =3D { "./tools/perf/tests/shell", = "./tests/shell", }; =20 - for (i =3D 0; i < ARRAY_SIZE(devel_dirs); ++i) { - struct stat st; + for (size_t i =3D 0; i < ARRAY_SIZE(devel_dirs); ++i) { + int fd =3D open(devel_dirs[i], O_PATH); =20 - if (!lstat(devel_dirs[i], &st)) { - scnprintf(path, size, "%s/shell", devel_dirs[i]); - if (!lstat(devel_dirs[i], &st)) - return path; - } + if (fd >=3D 0) + return fd; } =20 /* Then installed path. */ exec_path =3D get_argv_exec_path(); - scnprintf(path, size, "%s/tests/shell", exec_path); + scnprintf(path, sizeof(path), "%s/tests/shell", exec_path); free(exec_path); - return path; + return open(path, O_PATH); } =20 -static const char *shell_test__description(char *description, size_t size, - const char *path, const char *n= ame) +static char *shell_test__description(int dir_fd, const char *name) { - FILE *fp; - char filename[PATH_MAX]; - int ch; + struct io io; + char buf[128], desc[256]; + int ch, pos =3D 0; =20 - path__join(filename, sizeof(filename), path, name); - fp =3D fopen(filename, "r"); - if (!fp) + io__init(&io, openat(dir_fd, name, O_RDONLY), buf, sizeof(buf)); + if (io.fd < 0) return NULL; =20 /* Skip first line - should be #!/bin/sh Shebang */ + if (io__get_char(&io) !=3D '#') + goto err_out; + if (io__get_char(&io) !=3D '!') + goto err_out; do { - ch =3D fgetc(fp); - } while (ch !=3D EOF && ch !=3D '\n'); - - description =3D fgets(description, size, fp); - fclose(fp); + ch =3D io__get_char(&io); + if (ch < 0) + goto err_out; + } while (ch !=3D '\n'); =20 - /* Assume first char on line is omment everything after that desc */ - return description ? strim(description + 1) : NULL; + do { + ch =3D io__get_char(&io); + if (ch < 0) + goto err_out; + } while (ch =3D=3D '#' || isspace(ch)); + while (ch > 0 && ch !=3D '\n') { + desc[pos++] =3D ch; + if (pos >=3D (int)sizeof(desc) - 1) + break; + ch =3D io__get_char(&io); + } + while (pos > 0 && isspace(desc[--pos])) + ; + desc[++pos] =3D '\0'; + close(io.fd); + return strdup(desc); +err_out: + close(io.fd); + return NULL; } =20 /* Is this full file path a shell script */ -static bool is_shell_script(const char *path) +static bool is_shell_script(int dir_fd, const char *path) { const char *ext; =20 @@ -91,20 +106,16 @@ static bool is_shell_script(const char *path) if (!ext) return false; if (!strcmp(ext, ".sh")) { /* Has .sh extension */ - if (access(path, R_OK | X_OK) =3D=3D 0) /* Is executable */ + if (faccessat(dir_fd, path, R_OK | X_OK, 0) =3D=3D 0) /* Is executable */ return true; } return false; } =20 /* Is this file in this dir a shell script (for test purposes) */ -static bool is_test_script(const char *path, const char *name) +static bool is_test_script(int dir_fd, const char *name) { - char filename[PATH_MAX]; - - path__join(filename, sizeof(filename), path, name); - if (!is_shell_script(filename)) return false; - return true; + return is_shell_script(dir_fd, name); } =20 /* Duplicate a string and fall over and die if we run out of memory */ @@ -120,12 +131,21 @@ static char *strdup_check(const char *str) return newstr; } =20 -static void append_script(const char *dir, const char *file, const char *d= esc) +static void append_script(int dir_fd, const char *name, char *desc) { + char filename[PATH_MAX], link[128]; struct script_file *files_tmp; - size_t files_num_tmp; + size_t files_num_tmp, len; int width; =20 + snprintf(link, sizeof(link), "/proc/%d/fd/%d", getpid(), dir_fd); + len =3D readlink(link, filename, sizeof(filename)); + if (len < 0) { + pr_err("Failed to readlink %s", link); + return; + } + filename[len++] =3D '/'; + strcpy(&filename[len], name); files_num_tmp =3D files_num + 1; if (files_num_tmp >=3D SIZE_MAX) { pr_err("Too many script files\n"); @@ -142,10 +162,8 @@ static void append_script(const char *dir, const char = *file, const char *desc) /* Add file to end and NULL terminate the struct array */ files =3D files_tmp; files_num =3D files_num_tmp; - files[files_num - 1].dir =3D strdup_check(dir); - files[files_num - 1].file =3D strdup_check(file); - files[files_num - 1].desc =3D strdup_check(desc); - files[files_num].dir =3D NULL; + files[files_num - 1].file =3D strdup_check(filename); + files[files_num - 1].desc =3D desc; files[files_num].file =3D NULL; files[files_num].desc =3D NULL; =20 @@ -154,32 +172,39 @@ static void append_script(const char *dir, const char= *file, const char *desc) files_max_width =3D width; } =20 -static void append_scripts_in_dir(const char *path) +static void append_scripts_in_dir(int dir_fd) { struct dirent **entlist; struct dirent *ent; int n_dirs, i; - char filename[PATH_MAX]; =20 /* List files, sorted by alpha */ - n_dirs =3D scandir(path, &entlist, NULL, alphasort); + n_dirs =3D scandirat(dir_fd, ".", &entlist, NULL, alphasort); if (n_dirs =3D=3D -1) return; for (i =3D 0; i < n_dirs && (ent =3D entlist[i]); i++) { + int fd; + if (ent->d_name[0] =3D=3D '.') continue; /* Skip hidden files */ - if (is_test_script(path, ent->d_name)) { /* It's a test */ - char bf[256]; - const char *desc =3D shell_test__description - (bf, sizeof(bf), path, ent->d_name); + if (is_test_script(dir_fd, ent->d_name)) { /* It's a test */ + char *desc =3D shell_test__description(dir_fd, ent->d_name); =20 if (desc) /* It has a desc line - valid script */ - append_script(path, ent->d_name, desc); - } else if (is_directory(path, ent)) { /* Scan the subdir */ - path__join(filename, sizeof(filename), - path, ent->d_name); - append_scripts_in_dir(filename); + append_script(dir_fd, ent->d_name, desc); + continue; + } + if (ent->d_type !=3D DT_DIR) { + struct stat st; + + if (ent->d_type !=3D DT_UNKNOWN) + continue; + fstatat(dir_fd, ent->d_name, &st, 0); + if (!S_ISDIR(st.st_mode)) + continue; } + fd =3D openat(dir_fd, ent->d_name, O_PATH); + append_scripts_in_dir(fd); } for (i =3D 0; i < n_dirs; i++) /* Clean up */ zfree(&entlist[i]); @@ -188,14 +213,17 @@ static void append_scripts_in_dir(const char *path) =20 const struct script_file *list_script_files(void) { - char path_dir[PATH_MAX]; - const char *path; + int dir_fd; =20 if (files) return files; /* Singleton - we already know our list */ =20 - path =3D shell_tests__dir(path_dir, sizeof(path_dir)); /* Walk dir */ - append_scripts_in_dir(path); + dir_fd =3D shell_tests__dir_fd(); /* Walk dir */ + if (dir_fd < 0) + return NULL; + + append_scripts_in_dir(dir_fd); + close(dir_fd); =20 return files; } diff --git a/tools/perf/tests/tests-scripts.h b/tools/perf/tests/tests-scri= pts.h index 3a3ec6191848..3508a293aaf9 100644 --- a/tools/perf/tests/tests-scripts.h +++ b/tools/perf/tests/tests-scripts.h @@ -3,7 +3,6 @@ #define TESTS_SCRIPTS_H =20 struct script_file { - char *dir; char *file; char *desc; }; --=20 2.43.0.687.g38aa6559b0-goog From nobody Thu Dec 26 21:13:29 2024 Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4E2304C619 for ; Mon, 12 Feb 2024 18:59:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707764367; cv=none; b=XEG6HLgkx5r67ki7Tn/pgkezOWhByBDbRLQQvH4jTu4BpQD17RiPG+cVx3+uhTnPLdUOIb4vbFeFA4NMnV/GlAU0A070sQYWKyigqLq/MDDy/26oh9lGWLs649GvZjYd3kxg/w+DhOkOktPI4Ea17ZtjIy4kjr2Pe6oofIHCeSY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707764367; c=relaxed/simple; bh=e3Zo3j0Y+lDByuniGWZetsyjr0YP2URaOB3bhuKdkPg=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=l68pb11i03BhlyxbsyZxx+lCfAeAaJQlWKLS9/jqMaabKRVz1+8Q5Y1FzIWLhBZ0mCxhRWi5M9FcKwOC54OrjIPfyX61nC4KqyCN2qC8lw6ZfhMEtrnFT5bZA9l2wFXwcXAztpUJEiVmYsmAVBT52Zsrx6pioeScn/rDCxRCy4k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=ylR/MUEQ; arc=none smtp.client-ip=209.85.219.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="ylR/MUEQ" Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-dcc4563611cso91399276.3 for ; Mon, 12 Feb 2024 10:59:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1707764364; x=1708369164; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=pKUjhtJivPO8JCDFJHJoi47s/FDcERs+KA6j2+NQ9Pw=; b=ylR/MUEQRNmZgmOMFzBEmUWxXFXgr8EGMDjGS4KxyOYH6OrU1BWo1NNqz+tALsYPvc cSGN7wk+G2B1nnGKufpp3NXCHIcxjyc+4Zfb1+rmXQya6N2L9/8xX9F4NpNlBKMnbb1W sH0SD50PWxGdLkgU25wfbvbymsTw8qTgg6zZcJJE8R0zWz1JmlAChFQVgGjBrSQ4x863 SFTnEH1cDOSSP0sVFi3BHNiH0DA/3jMvF8qB6tuLy+ElIOAXJ84ohfOwUFl6oGm23KUX qgV2OuQFdJKALpwBW89KrROimcb3vF8JOT7XD56CqkHxA9zdDsZ2Vw/RVbnswnvkIjBD IVAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1707764364; x=1708369164; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=pKUjhtJivPO8JCDFJHJoi47s/FDcERs+KA6j2+NQ9Pw=; b=DriOBD2fEqeizq+o5N5iWIIPeroJ7N9hvhN8OIvkG09zAcinrpXecU4GCPWQm3gD4P 7FmdlwlGz3tHRuOdmDuX4w/XzbLVlviqcCdpv2VSjv0MW6RqSJhlnY8MgLYVoRPSNCLn P9C/MsNYTxFNs83GxVFo8yaAxjSrpjObmaA+3pxzFZrmJjoJq0A8b9wo+mES0afogk2j +48oaQZOzGX7k6j7caX+KMlK/sQLdG58nCQawegfLfiJTAqFbTavH/twjrK+M5wY0OGv lBDHd/vL+MtFbyvdVyloreMzUPx3W8STyFypHY9dLgn0UBQXcRAUva0jCLAgYsuSZGT6 YOig== X-Forwarded-Encrypted: i=1; AJvYcCUdIfjvZWul/L+dL/bcXL7Hn2W+ovjRsUN/HwK32ZW1EJIY+3ZFfCV7gRpnEaD9p2I9GM+cFQYEa9TkDJKFK+ebwwNX5Zdc+sfgyuyc X-Gm-Message-State: AOJu0Yzt1D1B0RBZpvA9GjhaPGj1TTNpF7PmEVtJ4kg8afFcGOAfvLat V0tNSwnehkm2XFIvJ0d3ELF+VTiTGZL86AVwiss0teRsiHtCuCdIeDOBPwx/Nvmppn9ayt5FM/b Enm3PIA== X-Google-Smtp-Source: AGHT+IGp0Tsh7Pkj0Vy343kMXSz7NO54KJv8lgbh53tJQw9m113ZOWAhaXvei7ITu3tfs9FrEXppNbX4CDUw X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:125c:bcda:4fe2:b6e6]) (user=irogers job=sendgmr) by 2002:a25:6910:0:b0:dc2:398d:a671 with SMTP id e16-20020a256910000000b00dc2398da671mr1960328ybc.10.1707764364421; Mon, 12 Feb 2024 10:59:24 -0800 (PST) Date: Mon, 12 Feb 2024 10:58:57 -0800 In-Reply-To: <20240212185858.68189-1-irogers@google.com> Message-Id: <20240212185858.68189-8-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240212185858.68189-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.687.g38aa6559b0-goog Subject: [PATCH v3 7/8] perf tests: Run time generate shell test suites From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt , James Clark , Athira Jajeev , Kan Liang , Yang Jihong , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, llvm@lists.linux.dev Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Rather than special shell test logic, do a single pass to create an array of test suites. Hold the shell test file name in the test suite priv field. This makes the special shell test logic in builtin-test.c redundant so remove it. Signed-off-by: Ian Rogers --- tools/perf/tests/builtin-test.c | 91 +--------------------- tools/perf/tests/tests-scripts.c | 130 ++++++++++++++++++------------- tools/perf/tests/tests-scripts.h | 10 +-- 3 files changed, 81 insertions(+), 150 deletions(-) diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-tes= t.c index 6d5001daaf63..c42cb40fc242 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -130,6 +130,7 @@ static struct test_suite *generic_tests[] =3D { static struct test_suite **tests[] =3D { generic_tests, arch_tests, + NULL, /* shell tests created at runtime. */ }; =20 static struct test_workload *workloads[] =3D { @@ -299,74 +300,12 @@ static int test_and_print(struct test_suite *t, int s= ubtest) return err; } =20 -struct shell_test { - const char *file; -}; - -static int shell_test__run(struct test_suite *test, int subdir __maybe_unu= sed) -{ - int err; - struct shell_test *st =3D test->priv; - char *cmd; - - asprintf(&cmd, "%s%s", st->file, verbose ? " -v" : ""); - if (!cmd) - return TEST_FAIL; - err =3D system(cmd); - free(cmd); - if (!err) - return TEST_OK; - - return WEXITSTATUS(err) =3D=3D 2 ? TEST_SKIP : TEST_FAIL; -} - -static int run_shell_tests(int argc, const char *argv[], int i, int width, - struct intlist *skiplist) -{ - struct shell_test st; - const struct script_file *files, *file; - - files =3D list_script_files(); - if (!files) - return 0; - for (file =3D files; file->file; file++) { - int curr =3D i++; - struct test_case test_cases[] =3D { - { - .desc =3D file->desc, - .run_case =3D shell_test__run, - }, - { .name =3D NULL, } - }; - struct test_suite test_suite =3D { - .desc =3D test_cases[0].desc, - .test_cases =3D test_cases, - .priv =3D &st, - }; - st.file =3D file->file; - - if (test_suite.desc =3D=3D NULL || - !perf_test__matches(test_suite.desc, curr, argc, argv)) - continue; - - pr_info("%3d: %-*s:", i, width, test_suite.desc); - - if (intlist__find(skiplist, i)) { - color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (user override)\n"); - continue; - } - - test_and_print(&test_suite, 0); - } - return 0; -} - static int __cmd_test(int argc, const char *argv[], struct intlist *skipli= st) { struct test_suite *t; unsigned int j, k; int i =3D 0; - int width =3D list_script_max_width(); + int width =3D 0; =20 for_each_test(j, k, t) { int len =3D strlen(test_description(t, -1)); @@ -441,28 +380,6 @@ static int __cmd_test(int argc, const char *argv[], st= ruct intlist *skiplist) } } } - - return run_shell_tests(argc, argv, i, width, skiplist); -} - -static int perf_test__list_shell(int argc, const char **argv, int i) -{ - const struct script_file *files, *file; - - files =3D list_script_files(); - if (!files) - return 0; - for (file =3D files; file->file; file++) { - int curr =3D i++; - struct test_suite t =3D { - .desc =3D file->desc - }; - - if (!perf_test__matches(t.desc, curr, argc, argv)) - continue; - - pr_info("%3d: %s\n", i, t.desc); - } return 0; } =20 @@ -489,9 +406,6 @@ static int perf_test__list(int argc, const char **argv) test_description(t, subi)); } } - - perf_test__list_shell(argc, argv, i); - return 0; } =20 @@ -551,6 +465,7 @@ int cmd_test(int argc, const char **argv) /* Unbuffered output */ setvbuf(stdout, NULL, _IONBF, 0); =20 + tests[2] =3D create_script_test_suites(); argc =3D parse_options_subcommand(argc, argv, test_options, test_subcomma= nds, test_usage, 0); if (argc >=3D 1 && !strcmp(argv[0], "list")) return perf_test__list(argc - 1, argv + 1); diff --git a/tools/perf/tests/tests-scripts.c b/tools/perf/tests/tests-scri= pts.c index 9b3b66dd5508..e60867b1e5ce 100644 --- a/tools/perf/tests/tests-scripts.c +++ b/tools/perf/tests/tests-scripts.c @@ -26,16 +26,6 @@ #include "tests.h" #include "util/rlimit.h" =20 - -/* - * As this is a singleton built once for the run of the process, there is - * no value in trying to free it and just let it stay around until process - * exits when it's cleaned up. - */ -static size_t files_num =3D 0; -static struct script_file *files =3D NULL; -static int files_max_width =3D 0; - static int shell_tests__dir_fd(void) { char path[PATH_MAX], *exec_path; @@ -131,12 +121,31 @@ static char *strdup_check(const char *str) return newstr; } =20 -static void append_script(int dir_fd, const char *name, char *desc) +static int shell_test__run(struct test_suite *test, int subtest __maybe_un= used) +{ + const char *file =3D test->priv; + int err; + char *cmd; + + asprintf(&cmd, "%s%s", file, verbose ? " -v" : ""); + if (!cmd) + return TEST_FAIL; + err =3D system(cmd); + free(cmd); + if (!err) + return TEST_OK; + + return WEXITSTATUS(err) =3D=3D 2 ? TEST_SKIP : TEST_FAIL; +} + +static void append_script(int dir_fd, const char *name, char *desc, + struct test_suite ***result, + size_t *result_sz) { char filename[PATH_MAX], link[128]; - struct script_file *files_tmp; - size_t files_num_tmp, len; - int width; + struct test_suite *test_suite, **result_tmp; + struct test_case *tests; + size_t len; =20 snprintf(link, sizeof(link), "/proc/%d/fd/%d", getpid(), dir_fd); len =3D readlink(link, filename, sizeof(filename)); @@ -146,33 +155,43 @@ static void append_script(int dir_fd, const char *nam= e, char *desc) } filename[len++] =3D '/'; strcpy(&filename[len], name); - files_num_tmp =3D files_num + 1; - if (files_num_tmp >=3D SIZE_MAX) { - pr_err("Too many script files\n"); - abort(); + + tests =3D calloc(2, sizeof(*tests)); + if (!tests) { + pr_err("Out of memory while building script test suite list\n"); + return; } + tests[0].name =3D strdup_check(name); + tests[0].desc =3D strdup_check(desc); + tests[0].run_case =3D shell_test__run; + + test_suite =3D zalloc(sizeof(*test_suite)); + if (!test_suite) { + pr_err("Out of memory while building script test suite list\n"); + free(tests); + return; + } + test_suite->desc =3D desc; + test_suite->test_cases =3D tests; + test_suite->priv =3D strdup_check(filename); /* Realloc is good enough, though we could realloc by chunks, not that * anyone will ever measure performance here */ - files_tmp =3D realloc(files, - (files_num_tmp + 1) * sizeof(struct script_file)); - if (files_tmp =3D=3D NULL) { - pr_err("Out of memory while building test list\n"); - abort(); + result_tmp =3D realloc(*result, (*result_sz + 1) * sizeof(*result_tmp)); + if (result_tmp =3D=3D NULL) { + pr_err("Out of memory while building script test suite list\n"); + free(tests); + free(test_suite); + return; } /* Add file to end and NULL terminate the struct array */ - files =3D files_tmp; - files_num =3D files_num_tmp; - files[files_num - 1].file =3D strdup_check(filename); - files[files_num - 1].desc =3D desc; - files[files_num].file =3D NULL; - files[files_num].desc =3D NULL; - - width =3D strlen(desc); /* Track max width of desc */ - if (width > files_max_width) - files_max_width =3D width; + *result =3D result_tmp; + (*result)[*result_sz] =3D test_suite; + (*result_sz)++; } =20 -static void append_scripts_in_dir(int dir_fd) +static void append_scripts_in_dir(int dir_fd, + struct test_suite ***result, + size_t *result_sz) { struct dirent **entlist; struct dirent *ent; @@ -191,7 +210,7 @@ static void append_scripts_in_dir(int dir_fd) char *desc =3D shell_test__description(dir_fd, ent->d_name); =20 if (desc) /* It has a desc line - valid script */ - append_script(dir_fd, ent->d_name, desc); + append_script(dir_fd, ent->d_name, desc, result, result_sz); continue; } if (ent->d_type !=3D DT_DIR) { @@ -204,32 +223,35 @@ static void append_scripts_in_dir(int dir_fd) continue; } fd =3D openat(dir_fd, ent->d_name, O_PATH); - append_scripts_in_dir(fd); + append_scripts_in_dir(fd, result, result_sz); } for (i =3D 0; i < n_dirs; i++) /* Clean up */ zfree(&entlist[i]); free(entlist); } =20 -const struct script_file *list_script_files(void) +struct test_suite **create_script_test_suites(void) { - int dir_fd; - - if (files) - return files; /* Singleton - we already know our list */ - - dir_fd =3D shell_tests__dir_fd(); /* Walk dir */ - if (dir_fd < 0) - return NULL; + struct test_suite **result =3D NULL, **result_tmp; + size_t result_sz =3D 0; + int dir_fd =3D shell_tests__dir_fd(); /* Walk dir */ =20 - append_scripts_in_dir(dir_fd); - close(dir_fd); + /* + * Append scripts if fd is good, otherwise return a NULL terminated zero + * length array. + */ + if (dir_fd >=3D 0) + append_scripts_in_dir(dir_fd, &result, &result_sz); =20 - return files; -} - -int list_script_max_width(void) -{ - list_script_files(); /* Ensure we have scanned all scripts */ - return files_max_width; + result_tmp =3D realloc(result, (result_sz + 1) * sizeof(*result_tmp)); + if (result_tmp =3D=3D NULL) { + pr_err("Out of memory while building script test suite list\n"); + abort(); + } + /* NULL terminate the test suite array. */ + result =3D result_tmp; + result[result_sz] =3D NULL; + if (dir_fd >=3D 0) + close(dir_fd); + return result; } diff --git a/tools/perf/tests/tests-scripts.h b/tools/perf/tests/tests-scri= pts.h index 3508a293aaf9..b553ad26ea17 100644 --- a/tools/perf/tests/tests-scripts.h +++ b/tools/perf/tests/tests-scripts.h @@ -2,14 +2,8 @@ #ifndef TESTS_SCRIPTS_H #define TESTS_SCRIPTS_H =20 -struct script_file { - char *file; - char *desc; -}; +#include "tests.h" =20 -/* List available script tests to run - singleton - never freed */ -const struct script_file *list_script_files(void); -/* Get maximum width of description string */ -int list_script_max_width(void); +struct test_suite **create_script_test_suites(void); =20 #endif /* TESTS_SCRIPTS_H */ --=20 2.43.0.687.g38aa6559b0-goog From nobody Thu Dec 26 21:13:29 2024 Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CCBEE4CB46 for ; Mon, 12 Feb 2024 18:59:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707764369; cv=none; b=r5Al95eV2ahiwgcZpjxQl5FLrPYBqNNTIjN0YSseec1BrMQ2nFHltLJc6MFjlUvLvuvWq76zBv2eDV2p5QDjpAHAj/F1mQVUSTB3l72SlsXpNnHARmZ20FzEcg3lSJHEQREf6OYskIDA2yYFCPJbyB3rRiDn3wr2EmWIS5JHdBM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707764369; c=relaxed/simple; bh=KfhEEpMCpHHqvGdrilXEBwK902jKxXX9KSQmwky6Gvk=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=b86adNCK3sVDhKKQmmzIuh9W2EjB5n266Ngv1iv765c9BFqSGx3fAuFHQxSGfMAUmsO3OCVU0FaaqVDeiR//spD8ud9Wo6ym5Ew8On3zaE+uohl0XCY5gHxMdJtyYmlScbJS9td4/QCcVvLCKpNhVcQmWxsf0MtAFpDmhBjURfw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=pJhrHak2; arc=none smtp.client-ip=209.85.219.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="pJhrHak2" Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-dc74ebfd282so6120720276.3 for ; Mon, 12 Feb 2024 10:59:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1707764367; x=1708369167; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=6B/9ZrYGS/GvVU4GCl+WETb7MhjnAD4f86As1bzZZ1w=; b=pJhrHak2y57vA6OoI0mm/XzrgkVOszPiR2R1gjHKxwB+JXkklNrNwprDmelIfEHEN2 dv5qWYLm5y+5ESaR1Kmx7TTczqrD7BVJfEmbu4PGukb7ZDOKJnONYh+My10g5lKWHcam 5GuX9uYGZcvP5PLpRniiWGLb2nssCEzepRpftUqTE3mqmOILMeFY9Vsc53OgSZGvLWp7 +YYPtikYn2eaaWqrARdR7WgrlxnU0Pr0ntIlDS6B/zi9L7YqIPi4jo1JxKRXvkUACrzC kwRatrRhqq5jtHAeidV40SZdYjvk1p7Xa2NABKBAvA8lp/dPaTiUY2C3hfxzH+cE7fMT DICA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1707764367; x=1708369167; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=6B/9ZrYGS/GvVU4GCl+WETb7MhjnAD4f86As1bzZZ1w=; b=vk5RUnbi5u31d+5Mbch0STAsTvRUqsv964qM/uhS00eyQYRlG6cQkySWzQn4X3H6PE Q3iu1L5k0u9kmYhtCzec8m1acZZLKn7UXh8dCfTnPK5XfdZe/ddIo/JbbF5bq7XmEaFi blUvmEYPR1ySTKnKIoAzhUAnmKUUc4tjEgbPgd5XCf4npiM5APgMN3EKIWq78RK3+sco nZLBaL1CpE8jUoXMsWK4r7ewwPd8wPYj6fU5m9OxAsPD98qD8jGgAmvch+3NLFPZ26RJ +WmCRSyhjhWZ7dgubIjw1QFxb9z2ZrjLrfAhe+vS5xqIZRHMni7IZMnWO36epU4kebMu xegQ== X-Gm-Message-State: AOJu0YzZ4HdAePaTqnVkLN7GxJPMcTvIbg0e5QPWFa4hVv6goPstlbZj OtADMam3HkAGXBhaGPehDcz6XdLF0YDeCQ5uMhKclWpij46Cbmoyfk45V75rZDlxh6zTyX8y7nq 0rnQBcw== X-Google-Smtp-Source: AGHT+IHeJtr+J+UM1A953ZSh67WoMqrpAZorBHS86+PuKa3y82YBkZsQ3Sy+ahaObrCz9S/jk8xrV/sdLep/ X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:125c:bcda:4fe2:b6e6]) (user=irogers job=sendgmr) by 2002:a25:aa6e:0:b0:dc6:e8a7:fdba with SMTP id s101-20020a25aa6e000000b00dc6e8a7fdbamr2005453ybi.4.1707764366829; Mon, 12 Feb 2024 10:59:26 -0800 (PST) Date: Mon, 12 Feb 2024 10:58:58 -0800 In-Reply-To: <20240212185858.68189-1-irogers@google.com> Message-Id: <20240212185858.68189-9-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240212185858.68189-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.687.g38aa6559b0-goog Subject: [PATCH v3 8/8] perf tests: Add option to run tests in parallel From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt , James Clark , Athira Jajeev , Kan Liang , Yang Jihong , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, llvm@lists.linux.dev Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" By default tests are forked, add an option (-p or --parallel) so that the forked tests are all started in parallel and then their output gathered serially. This is opt-in as running in parallel can cause test flakes. Rather than fork within the code, the start_command/finish_command from libsubcmd are used. This changes how stderr and stdout are handled. The child stderr and stdout are always read to avoid the child blocking. If verbose is 1 (-v) then if the test fails the child stdout and stderr are displayed. If the verbose is >1 (e.g. -vv) then the stdout and stderr from the child are immediately displayed. An unscientific test on my laptop shows the wall clock time for perf test without parallel being 5 minutes 21 seconds and with parallel (-p) being 1 minute 50 seconds. Signed-off-by: Ian Rogers --- v1 of this code had a bug where stdout/stderr weren't read fully. This and additional issues/improvements are dealt with in v2. --- tools/perf/tests/builtin-test.c | 305 ++++++++++++++++++++++---------- 1 file changed, 213 insertions(+), 92 deletions(-) diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-tes= t.c index c42cb40fc242..b815db8ebf79 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -6,6 +6,7 @@ */ #include #include +#include #include #include #include @@ -21,9 +22,11 @@ #include "debug.h" #include "color.h" #include +#include #include "string2.h" #include "symbol.h" #include "util/rlimit.h" +#include "util/strbuf.h" #include #include #include @@ -31,7 +34,13 @@ =20 #include "tests-scripts.h" =20 +/* + * Command line option to not fork the test running in the same process and + * making them easier to debug. + */ static bool dont_fork; +/* Fork the tests in parallel and then wait for their completion. */ +static bool parallel; const char *dso_to_test; const char *test_objdump_path =3D "objdump"; =20 @@ -209,76 +218,36 @@ static bool perf_test__matches(const char *desc, int = curr, int argc, const char return false; } =20 -static int run_test(struct test_suite *test, int subtest) -{ - int status, err =3D -1, child =3D dont_fork ? 0 : fork(); - char sbuf[STRERR_BUFSIZE]; - - if (child < 0) { - pr_err("failed to fork test: %s\n", - str_error_r(errno, sbuf, sizeof(sbuf))); - return -1; - } - - if (!child) { - if (!dont_fork) { - pr_debug("test child forked, pid %d\n", getpid()); - - if (verbose <=3D 0) { - int nullfd =3D open("/dev/null", O_WRONLY); - - if (nullfd >=3D 0) { - close(STDERR_FILENO); - close(STDOUT_FILENO); - - dup2(nullfd, STDOUT_FILENO); - dup2(STDOUT_FILENO, STDERR_FILENO); - close(nullfd); - } - } else { - signal(SIGSEGV, sighandler_dump_stack); - signal(SIGFPE, sighandler_dump_stack); - } - } - - err =3D test_function(test, subtest)(test, subtest); - if (!dont_fork) - exit(err); - } - - if (!dont_fork) { - wait(&status); +struct child_test { + struct child_process process; + struct test_suite *test; + int test_num; + int subtest; +}; =20 - if (WIFEXITED(status)) { - err =3D (signed char)WEXITSTATUS(status); - pr_debug("test child finished with %d\n", err); - } else if (WIFSIGNALED(status)) { - err =3D -1; - pr_debug("test child interrupted\n"); - } - } +static int run_test_child(struct child_process *process) +{ + struct child_test *child =3D container_of(process, struct child_test, pro= cess); + int err; =20 - return err; + pr_debug("--- start ---\n"); + pr_debug("test child forked, pid %d\n", getpid()); + err =3D test_function(child->test, child->subtest)(child->test, child->su= btest); + pr_debug("---- end(%d) ----\n", err); + fflush(NULL); + return -err; } =20 -#define for_each_test(j, k, t) \ - for (j =3D 0, k =3D 0; j < ARRAY_SIZE(tests); j++, k =3D 0) \ - while ((t =3D tests[j][k++]) !=3D NULL) - -static int test_and_print(struct test_suite *t, int subtest) +static int print_test_result(struct test_suite *t, int i, int subtest, int= result, int width) { - int err; - - pr_debug("\n--- start ---\n"); - err =3D run_test(t, subtest); - pr_debug("---- end ----\n"); + if (has_subtests(t)) { + int subw =3D width > 2 ? width - 2 : width; =20 - if (!has_subtests(t)) - pr_debug("%s:", t->desc); - else - pr_debug("%s subtest %d:", t->desc, subtest + 1); + pr_info("%3d.%1d: %-*s:", i + 1, subtest + 1, subw, test_description(t, = subtest)); + } else + pr_info("%3d: %-*s:", i + 1, width, test_description(t, subtest)); =20 - switch (err) { + switch (result) { case TEST_OK: pr_info(" Ok\n"); break; @@ -297,22 +266,177 @@ static int test_and_print(struct test_suite *t, int = subtest) break; } =20 - return err; + return 0; +} + +static int finish_test(struct child_test *child_test, int width) +{ + struct test_suite *t =3D child_test->test; + int i =3D child_test->test_num; + int subi =3D child_test->subtest; + int out =3D child_test->process.out; + int err =3D child_test->process.err; + bool out_done =3D out <=3D 0; + bool err_done =3D err <=3D 0; + struct strbuf out_output =3D STRBUF_INIT; + struct strbuf err_output =3D STRBUF_INIT; + int ret; + + /* + * For test suites with subtests, display the suite name ahead of the + * sub test names. + */ + if (has_subtests(t) && subi =3D=3D 0) + pr_info("%3d: %-*s:\n", i + 1, width, test_description(t, -1)); + + /* + * Busy loop reading from the child's stdout and stderr that are set to + * be non-blocking until EOF. + */ + if (!out_done) + fcntl(out, F_SETFL, O_NONBLOCK); + if (!err_done) + fcntl(err, F_SETFL, O_NONBLOCK); + if (verbose > 1) { + if (has_subtests(t)) + pr_info("%3d.%1d: %s:\n", i + 1, subi + 1, test_description(t, subi)); + else + pr_info("%3d: %s:\n", i + 1, test_description(t, -1)); + } + while (!out_done || !err_done) { + struct pollfd pfds[2] =3D { + { .fd =3D out, + .events =3D POLLIN | POLLERR | POLLHUP | POLLNVAL, + }, + { .fd =3D err, + .events =3D POLLIN | POLLERR | POLLHUP | POLLNVAL, + }, + }; + char buf[512]; + ssize_t len; + + /* Poll to avoid excessive spinning, timeout set for 1000ms. */ + poll(pfds, ARRAY_SIZE(pfds), /*timeout=3D*/1000); + if (!out_done && pfds[0].revents) { + errno =3D 0; + len =3D read(out, buf, sizeof(buf) - 1); + + if (len <=3D 0) { + out_done =3D errno !=3D EAGAIN; + } else { + buf[len] =3D '\0'; + if (verbose > 1) + fprintf(stdout, "%s", buf); + else + strbuf_addstr(&out_output, buf); + } + } + if (!err_done && pfds[1].revents) { + errno =3D 0; + len =3D read(err, buf, sizeof(buf) - 1); + + if (len <=3D 0) { + err_done =3D errno !=3D EAGAIN; + } else { + buf[len] =3D '\0'; + if (verbose > 1) + fprintf(stdout, "%s", buf); + else + strbuf_addstr(&err_output, buf); + } + } + } + /* Clean up child process. */ + ret =3D finish_command(&child_test->process); + if (verbose =3D=3D 1 && ret =3D=3D TEST_FAIL) { + /* Add header for test that was skipped above. */ + if (has_subtests(t)) + pr_info("%3d.%1d: %s:\n", i + 1, subi + 1, test_description(t, subi)); + else + pr_info("%3d: %s:\n", i + 1, test_description(t, -1)); + fprintf(stdout, "%s", out_output.buf); + fprintf(stderr, "%s", err_output.buf); + } + strbuf_release(&out_output); + strbuf_release(&err_output); + print_test_result(t, i, subi, ret, width); + if (out > 0) + close(out); + if (err > 0) + close(err); + return 0; +} + +static int start_test(struct test_suite *test, int i, int subi, struct chi= ld_test **child, + int width) +{ + int err; + + *child =3D NULL; + if (dont_fork) { + pr_debug("--- start ---\n"); + err =3D test_function(test, subi)(test, subi); + pr_debug("---- end ----\n"); + print_test_result(test, i, subi, err, width); + return 0; + } + + *child =3D zalloc(sizeof(**child)); + if (!*child) + return -ENOMEM; + + (*child)->test =3D test; + (*child)->test_num =3D i; + (*child)->subtest =3D subi; + (*child)->process.pid =3D -1; + (*child)->process.no_stdin =3D 1; + if (verbose <=3D 0) { + (*child)->process.no_stdout =3D 1; + (*child)->process.no_stderr =3D 1; + } else { + (*child)->process.out =3D -1; + (*child)->process.err =3D -1; + } + (*child)->process.no_exec_cmd =3D run_test_child; + err =3D start_command(&(*child)->process); + if (err || parallel) + return err; + return finish_test(*child, width); } =20 +#define for_each_test(j, k, t) \ + for (j =3D 0, k =3D 0; j < ARRAY_SIZE(tests); j++, k =3D 0) \ + while ((t =3D tests[j][k++]) !=3D NULL) + static int __cmd_test(int argc, const char *argv[], struct intlist *skipli= st) { struct test_suite *t; unsigned int j, k; int i =3D 0; int width =3D 0; + size_t num_tests =3D 0; + struct child_test **child_tests; + int child_test_num =3D 0; =20 for_each_test(j, k, t) { int len =3D strlen(test_description(t, -1)); =20 if (width < len) width =3D len; + + if (has_subtests(t)) { + for (int l =3D 0, subn =3D num_subtests(t); l < subn; l++) { + len =3D strlen(test_description(t, -1)); + if (width < len) + width =3D len; + num_tests++; + } + } else + num_tests++; } + child_tests =3D calloc(num_tests, sizeof(*child_tests)); + if (!child_tests) + return -ENOMEM; =20 for_each_test(j, k, t) { int curr =3D i++; @@ -334,52 +458,47 @@ static int __cmd_test(int argc, const char *argv[], s= truct intlist *skiplist) continue; } =20 - pr_info("%3d: %-*s:", i, width, test_description(t, -1)); - if (intlist__find(skiplist, i)) { + pr_info("%3d: %-*s:", curr + 1, width, test_description(t, -1)); color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (user override)\n"); continue; } =20 if (!has_subtests(t)) { - test_and_print(t, -1); + int err =3D start_test(t, curr, -1, &child_tests[child_test_num++], wid= th); + + if (err) { + /* TODO: if parallel waitpid the already forked children. */ + free(child_tests); + return err; + } } else { int subn =3D num_subtests(t); - /* - * minus 2 to align with normal testcases. - * For subtest we print additional '.x' in number. - * for example: - * - * 35: Test LLVM searching and compiling : - * 35.1: Basic BPF llvm compiling test : Ok - */ - int subw =3D width > 2 ? width - 2 : width; - - if (subn <=3D 0) { - color_fprintf(stderr, PERF_COLOR_YELLOW, - " Skip (not compiled in)\n"); - continue; - } - pr_info("\n"); =20 for (subi =3D 0; subi < subn; subi++) { - int len =3D strlen(test_description(t, subi)); + int err; =20 - if (subw < len) - subw =3D len; - } - - for (subi =3D 0; subi < subn; subi++) { if (!perf_test__matches(test_description(t, subi), curr, argc, argv)) continue; =20 - pr_info("%3d.%1d: %-*s:", i, subi + 1, subw, - test_description(t, subi)); - test_and_print(t, subi); + err =3D start_test(t, curr, subi, &child_tests[child_test_num++], + width); + if (err) + return err; } } } + for (i =3D 0; i < child_test_num; i++) { + if (parallel) { + int ret =3D finish_test(child_tests[i], width); + + if (ret) + return ret; + } + free(child_tests[i]); + } + free(child_tests); return 0; } =20 @@ -447,6 +566,8 @@ int cmd_test(int argc, const char **argv) "be more verbose (show symbol address, etc)"), OPT_BOOLEAN('F', "dont-fork", &dont_fork, "Do not fork for testcase"), + OPT_BOOLEAN('p', "parallel", ¶llel, + "Run the tests altogether in parallel"), OPT_STRING('w', "workload", &workload, "work", "workload to run for testi= ng"), OPT_STRING(0, "dso", &dso_to_test, "dso", "dso to test"), OPT_STRING(0, "objdump", &test_objdump_path, "path", --=20 2.43.0.687.g38aa6559b0-goog