From nobody Wed Apr 8 04:31:28 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 792E1C3F6B0 for ; Wed, 24 Aug 2022 07:28:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234938AbiHXH2s (ORCPT ); Wed, 24 Aug 2022 03:28:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45134 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232752AbiHXH2m (ORCPT ); Wed, 24 Aug 2022 03:28:42 -0400 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6098269F4D for ; Wed, 24 Aug 2022 00:28:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1661326121; x=1692862121; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Q3tbz1NaUEC/rY8ldWb5Y5evI0RmSTZjOIOG8xF0v8Q=; b=FDvsw6EJCWPW7GGSwb10QwsB8/N5ooyKN8mAmlEsCyZuwliHf2uaT4wP QU51SYnJGne/jxWBsnXuJwdbhyCDR7Q57xXshtUudF23rxfMI7uXxS3bk HRa738CCiOVReGcka9TAZOi535Bd0km26kqQlBpE0FsL//2BT08hCraVj X2E+8lAeNgQCt6yIJ3ey0N6xQM4aclnptHgxNTMSnrYTf7AZVaAdyU/ae y5L0weq/HBAvsrb7b9qa2BGlbX3QwmX8rLpBnjSVc05KiTAoAs4lRrAFd jLr6FTNRTpAgGPsNyxc7z9HxRYHmOssfzWutUWAecgAUFzxDtZNFp75BQ A==; X-IronPort-AV: E=McAfee;i="6500,9779,10448"; a="295173945" X-IronPort-AV: E=Sophos;i="5.93,260,1654585200"; d="scan'208";a="295173945" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Aug 2022 00:28:41 -0700 X-IronPort-AV: E=Sophos;i="5.93,260,1654585200"; d="scan'208";a="605939141" Received: from ahunter6-mobl1.ger.corp.intel.com (HELO ahunter-VirtualBox.home\044ger.corp.intel.com) ([10.252.51.108]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Aug 2022 00:28:38 -0700 From: Adrian Hunter To: Arnaldo Carvalho de Melo Cc: Jiri Olsa , Namhyung Kim , Ian Rogers , Andi Kleen , Alexey Bayduraev , linux-kernel@vger.kernel.org Subject: [PATCH 1/5] perf record: Fix way of handling non-perf-event pollfds Date: Wed, 24 Aug 2022 10:28:10 +0300 Message-Id: <20220824072814.16422-2-adrian.hunter@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220824072814.16422-1-adrian.hunter@intel.com> References: <20220824072814.16422-1-adrian.hunter@intel.com> MIME-Version: 1.0 Organization: Intel Finland Oy, Registered Address: PL 281, 00181 Helsinki, Business Identity Code: 0357606 - 4, Domiciled in Helsinki Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" perf record __cmd_record() does not poll evlist pollfds. Instead it polls thread_data[0].pollfd. That happens whether or not threads are being used. perf record duplicates evlist mmap pollfds as needed for separate threads. The non-perf-event represented by evlist->ctl_fd has to handled separately, which is done explicitly, duplicating it into the thread_data[0] pollfds. That approach neglects any other non-perf-event file descriptors. Currently there is also done_fd which needs the same handling. Add a new generalized approach. Add fdarray_flag__non_perf_event to identify the file descriptors that need the special handling. For those cases, also keep a mapping of the evlist pollfd index and thread pollfd index, so that the evlist revents can be updated. Although this patch adds the new handling, it does not take it into use. There is no functional change, but it is the precursor to a fix, so is marked as a fix. Fixes: 415ccb58f68a ("perf record: Introduce thread specific data array") Signed-off-by: Adrian Hunter Acked-by: Ian Rogers --- tools/lib/api/fd/array.h | 5 ++- tools/perf/builtin-record.c | 80 +++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 2 deletions(-) diff --git a/tools/lib/api/fd/array.h b/tools/lib/api/fd/array.h index 60ad197c8ee9..5c01f7b05dfb 100644 --- a/tools/lib/api/fd/array.h +++ b/tools/lib/api/fd/array.h @@ -31,8 +31,9 @@ struct fdarray { }; =20 enum fdarray_flags { - fdarray_flag__default =3D 0x00000000, - fdarray_flag__nonfilterable =3D 0x00000001 + fdarray_flag__default =3D 0x00000000, + fdarray_flag__nonfilterable =3D 0x00000001, + fdarray_flag__non_perf_event =3D 0x00000002, }; =20 void fdarray__init(struct fdarray *fda, int nr_autogrow); diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 4713f0f3a6cf..e0be48c47f65 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -143,6 +143,11 @@ static const char *thread_spec_tags[THREAD_SPEC__MAX] = =3D { "undefined", "cpu", "core", "package", "numa", "user" }; =20 +struct pollfd_index_map { + int evlist_pollfd_index; + int thread_pollfd_index; +}; + struct record { struct perf_tool tool; struct record_opts opts; @@ -171,6 +176,9 @@ struct record { int nr_threads; struct thread_mask *thread_masks; struct record_thread *thread_data; + struct pollfd_index_map *index_map; + size_t index_map_sz; + size_t index_map_cnt; }; =20 static volatile int done; @@ -1074,6 +1082,70 @@ static void record__free_thread_data(struct record *= rec) zfree(&rec->thread_data); } =20 +static int record__map_thread_evlist_pollfd_indexes(struct record *rec, + int evlist_pollfd_index, + int thread_pollfd_index) +{ + size_t x =3D rec->index_map_cnt; + + if (realloc_array_as_needed(rec->index_map, rec->index_map_sz, x, NULL)) + return -ENOMEM; + rec->index_map[x].evlist_pollfd_index =3D evlist_pollfd_index; + rec->index_map[x].thread_pollfd_index =3D thread_pollfd_index; + rec->index_map_cnt +=3D 1; + return 0; +} + +static int record__update_evlist_pollfd_from_thread(struct record *rec, + struct evlist *evlist, + struct record_thread *thread_data) +{ + struct pollfd *e_entries =3D evlist->core.pollfd.entries; + struct pollfd *t_entries =3D thread_data->pollfd.entries; + int err =3D 0; + size_t i; + + for (i =3D 0; i < rec->index_map_cnt; i++) { + int e_pos =3D rec->index_map[i].evlist_pollfd_index; + int t_pos =3D rec->index_map[i].thread_pollfd_index; + + if (e_entries[e_pos].fd !=3D t_entries[t_pos].fd || + e_entries[e_pos].events !=3D t_entries[t_pos].events) { + pr_err("Thread and evlist pollfd index mismatch\n"); + err =3D -EINVAL; + continue; + } + e_entries[e_pos].revents =3D t_entries[t_pos].revents; + } + return err; +} + +static int record__dup_non_perf_events(struct record *rec, + struct evlist *evlist, + struct record_thread *thread_data) +{ + struct fdarray *fda =3D &evlist->core.pollfd; + int i, ret; + + for (i =3D 0; i < fda->nr; i++) { + if (!(fda->priv[i].flags & fdarray_flag__non_perf_event)) + continue; + ret =3D fdarray__dup_entry_from(&thread_data->pollfd, i, fda); + if (ret < 0) { + pr_err("Failed to duplicate descriptor in main thread pollfd\n"); + return ret; + } + pr_debug2("thread_data[%p]: pollfd[%d] <- non_perf_event fd=3D%d\n", + thread_data, ret, fda->entries[i].fd); + ret =3D record__map_thread_evlist_pollfd_indexes(rec, i, ret); + if (ret < 0) { + pr_err("Failed to map thread and evlist pollfd indexes\n"); + return ret; + } + } + return 0; +} + static int record__alloc_thread_data(struct record *rec, struct evlist *ev= list) { int t, ret; @@ -1121,6 +1193,11 @@ static int record__alloc_thread_data(struct record *= rec, struct evlist *evlist) thread_data[t].pipes.msg[0]); } else { thread_data[t].tid =3D gettid(); + + ret =3D record__dup_non_perf_events(rec, evlist, &thread_data[t]); + if (ret < 0) + goto out_free; + if (evlist->ctl_fd.pos =3D=3D -1) continue; ret =3D fdarray__dup_entry_from(&thread_data[t].pollfd, evlist->ctl_fd.= pos, @@ -2530,6 +2607,9 @@ static int __cmd_record(struct record *rec, int argc,= const char **argv) record__thread_munmap_filtered, NULL) =3D=3D 0) draining =3D true; =20 + err =3D record__update_evlist_pollfd_from_thread(rec, rec->evlist, thre= ad); + if (err) + goto out_child; evlist__ctlfd_update(rec->evlist, &thread->pollfd.entries[thread->ctlfd_pos]); } --=20 2.25.1