Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp645361pxj; Thu, 3 Jun 2021 16:04:32 -0700 (PDT) X-Google-Smtp-Source: ABdhPJy7mvU2l+S40bUquKrISrCDLauZPsgxmywgojUuMp+5mW7R6KktTmmDiHfinkREj4OobMlG X-Received: by 2002:a17:906:dbc2:: with SMTP id yc2mr1430236ejb.390.1622761471932; Thu, 03 Jun 2021 16:04:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622761471; cv=none; d=google.com; s=arc-20160816; b=Lt1840r9C0Nn5x/7/hLqVcsQxuTuPjSFjI4XHi918Kxk1T0Uk9PKi68dtUGjnEObjz AVSWM/k5ZdTbmlcJo1+zWnIPC0q3PK4CLg4/xhvFvHBdNKsnhuRSeQhQ2LL+ItNd+s6p yLKLV0EcAzydKnMi9QZz4X1Q8s+ePTE4/+Am4IibOr6TUdHNFFrlmsdeZo1Nya9HfVvV HI/JlcqIARzvlCKvbDdMhHUtkA0kR9S8tJ0HGe4ELp+qHrT5L0/rAu5OTZ3CcvCAJUQw 15I8YmUQtXfJfOnuG31HciK8mAsqVSwkX5l+v0M6VAHMi1elsCnk1Qk5BfFspt5aGN+J TVhA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:date:cc:to:from:subject :message-id:dkim-signature; bh=NYpcrUNiLcsOZAXAtknUpjfz3k6LyTw1gP/lM5pt/8Y=; b=HyPjOrd4Rn1HqysL/9EtHW1EZZL81pPPF2J0+uMuKaG6jrUu2VMbnupT6RLSSNnzbL 7cwwiX+VS51OIlvn6e8B3RFewhdPClSvfM6EpyfpxLYwa/kiiVSxgpdisCpgunvlsdEb s7tXMa3qfxX7vWfl8f1g0ye9kFXescMIsjY2EA6dUWyVGxfX9Ve5Xts67VOD9xHzrFZn cdmMBSAepClQx8Ik7DfIXEUtLxQmPHo715x/AGAYZ7aXKpLpEesvxb9UoD8YF/zW0s87 5SGpXZVBACh9wpExpfArgWMQeW4Wh7c4sLmxPBAuNdPqCRI7UK824LxakdDNDpWvoykG lL5A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=NnzxAdM5; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id b7si3182315edy.268.2021.06.03.16.04.06; Thu, 03 Jun 2021 16:04:31 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=NnzxAdM5; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229726AbhFCXEX (ORCPT + 99 others); Thu, 3 Jun 2021 19:04:23 -0400 Received: from mail-ej1-f54.google.com ([209.85.218.54]:38521 "EHLO mail-ej1-f54.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229675AbhFCXEX (ORCPT ); Thu, 3 Jun 2021 19:04:23 -0400 Received: by mail-ej1-f54.google.com with SMTP id og14so6314991ejc.5; Thu, 03 Jun 2021 16:02:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:subject:from:to:cc:date:in-reply-to:references :user-agent:mime-version:content-transfer-encoding; bh=NYpcrUNiLcsOZAXAtknUpjfz3k6LyTw1gP/lM5pt/8Y=; b=NnzxAdM5hXb/P1M6I2y/Ha3S32u9L6sCl4gYrU41dmMmiCvAWmBTxtYDh5bI85sDsi X7Zbxh+C6yZYn4lUA/GGaXIfJ7ehhyq0h3hu9PFD52+9eTzVATtVNcwdWPXhnTb4wRfU ln35a60owcjq0U9izacZBJTFDyATvr8t/ZvneNLQIMmtN6zfPJ7n7DApsxC94SyhfMRU yJ0ywYj5VN3Z5k7p6uS4SjnGO5lEVOpiT+aIpqovdSMfCzReMkdtDOyGW/NDkros459T zVZntf9Vs0oL5b4dakT24uiVnIGC6SIERTyTf5BY7eY0rfN+L7uO1LAX9TeMARnhWhEn bdtg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:subject:from:to:cc:date:in-reply-to :references:user-agent:mime-version:content-transfer-encoding; bh=NYpcrUNiLcsOZAXAtknUpjfz3k6LyTw1gP/lM5pt/8Y=; b=szETCIomvV4Ik/sDW5WrKPRRQTljlrgfhxY+mv0aSFlLX2T7Jr4jNw/X6La4AEOHhT czcDnvp0GrdtCGvPQHYRx9UiMM9SGQwYYtfouT0VtcZV9iBmtZiF6u2+J2yfcUFiezD8 FPQCEmhekJaBqeueqberUtpZQft+GU1plvPHUcVMeMzL++gU7dgut8AEdB48AnZygoH8 RGAVeFFivA68WF67n1KoeurZe9JZiOeTKyXUziLDN9s43iWa3lEhyx5+j6IhmqyW7MrU z27YUoJVG12w/y94GdfPbShvPqBoDw3SXZre0i8bpNN8Aj4/MZ8x0TE22qYpypOSV2c7 wk0Q== X-Gm-Message-State: AOAM531rvd8m9ebj5t+2K5/7i28+G1hDNbwgX+3ponwzdqNwVd+br9MK oJtQ0WpWoqdvg2bhRBrqyns= X-Received: by 2002:a17:906:7d0:: with SMTP id m16mr1411579ejc.319.1622761283387; Thu, 03 Jun 2021 16:01:23 -0700 (PDT) Received: from [192.168.1.15] ([151.29.179.73]) by smtp.gmail.com with ESMTPSA id r19sm2393816eds.75.2021.06.03.16.01.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 16:01:19 -0700 (PDT) Message-ID: <9df174c09795b1f8e42f1ac31877a6ea9d3ecae3.camel@gmail.com> Subject: Re: [PATCH v6 05/20] perf record: Start threads in the beginning of trace streaming From: Riccardo Mancini To: Alexey Bayduraev Cc: Jiri Olsa , Namhyung Kim , Alexander Shishkin , Peter Zijlstra , Ingo Molnar , linux-kernel , Andi Kleen , Adrian Hunter , Alexander Antonov , Alexei Budankov , linux-perf-users@vger.kernel.org, Ian Rogers , Arnaldo Carvalho de Melo Date: Fri, 04 Jun 2021 01:01:17 +0200 In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" User-Agent: Evolution 3.40.1 (3.40.1-1.fc34) MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi, On Wed, 2021-05-26 at 13:52 +0300, Alexey Bayduraev wrote: > Start thread in detached state because its management is implemented > via messaging to avoid any scaling issues. Block signals prior thread > start so only main tool thread would be notified on external async > signals during data collection. Thread affinity mask is used to assign > eligible cpus for the thread to run. Wait and sync on thread start using > thread ack pipe. > > Signed-off-by: Alexey Bayduraev > --- >  tools/perf/builtin-record.c | 106 +++++++++++++++++++++++++++++++++++- >  1 file changed, 105 insertions(+), 1 deletion(-) > > diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c > index 838c1f779849..88fad12cbe5b 100644 > --- a/tools/perf/builtin-record.c > +++ b/tools/perf/builtin-record.c > @@ -1423,6 +1423,66 @@ static void record__thread_munmap_filtered(struct > fdarray *fda, int fd, >                 perf_mmap__put(map); >  } >   > +static void *record__thread(void *arg) > +{ > +       enum thread_msg msg = THREAD_MSG__READY; > +       bool terminate = false; > +       struct fdarray *pollfd; > +       int err, ctlfd_pos; > + > +       thread = arg; > +       thread->tid = syscall(SYS_gettid); > + > +       err = write(thread->pipes.ack[1], &msg, sizeof(msg)); > +       if (err == -1) > +               pr_err("threads[%d]: failed to notify on start: %s", thread- > >tid, strerror(errno)); > + > +       pr_debug("threads[%d]: started on cpu=%d\n", thread->tid, > sched_getcpu()); > + > +       pollfd = &thread->pollfd; > +       ctlfd_pos = thread->ctlfd_pos; > + > +       for (;;) { > +               unsigned long long hits = thread->samples; > + > +               if (record__mmap_read_all(thread->rec, false) < 0 || > terminate) > +                       break; > + > +               if (hits == thread->samples) { > + > +                       err = fdarray__poll(pollfd, -1); > +                       /* > +                        * Propagate error, only if there's any. Ignore > positive > +                        * number of returned events and interrupt error. > +                        */ > +                       if (err > 0 || (err < 0 && errno == EINTR)) > +                               err = 0; > +                       thread->waking++; > + > +                       if (fdarray__filter(pollfd, POLLERR | POLLHUP, > +                                           record__thread_munmap_filtered, > NULL) == 0) > +                               break; > +               } > + > +               if (pollfd->entries[ctlfd_pos].revents & POLLHUP) { > +                       terminate = true; > +                       close(thread->pipes.msg[0]); > +                       pollfd->entries[ctlfd_pos].fd = -1; > +                       pollfd->entries[ctlfd_pos].events = 0; > +               } > + > +               pollfd->entries[ctlfd_pos].revents = 0; > +       } > +       record__mmap_read_all(thread->rec, true); > + > +       err = write(thread->pipes.ack[1], &msg, sizeof(msg)); > +       if (err == -1) > +               pr_err("threads[%d]: failed to notify on termination: %s", > +                      thread->tid, strerror(errno)); > + > +       return NULL; > +} > + >  static void record__init_features(struct record *rec) >  { >         struct perf_session *session = rec->session; > @@ -1886,13 +1946,57 @@ static int record__terminate_thread(struct thread_data > *thread_data) >   >  static int record__start_threads(struct record *rec) >  { > +       int t, tt, ret = 0, nr_threads = rec->nr_threads; >         struct thread_data *thread_data = rec->thread_data; > +       sigset_t full, mask; > +       pthread_t handle; > +       pthread_attr_t attrs; > + > +       sigfillset(&full); > +       if (sigprocmask(SIG_SETMASK, &full, &mask)) { > +               pr_err("Failed to block signals on threads start: %s\n", > strerror(errno)); > +               return -1; > +       } > + > +       pthread_attr_init(&attrs); > +       pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED); > + > +       for (t = 1; t < nr_threads; t++) { > +               enum thread_msg msg = THREAD_MSG__UNDEFINED; > + > +               pthread_attr_setaffinity_np(&attrs, > +                                           > MMAP_CPU_MASK_BYTES(&(thread_data[t].mask->affinity)), > +                                           (cpu_set_t *)(thread_data[t].mask- > >affinity.bits)); > + > +               if (pthread_create(&handle, &attrs, record__thread, > &thread_data[t])) { > +                       for (tt = 1; tt < t; tt++) > +                               record__terminate_thread(&thread_data[t]); > +                       pr_err("Failed to start threads: %s\n", > strerror(errno)); > +                       ret = -1; > +                       goto out_err; > +               } > + > +               if (read(thread_data[t].pipes.ack[0], &msg, sizeof(msg)) > 0) > +                       pr_debug2("threads[%d]: sent %s\n", rec- > >thread_data[t].tid, > +                                thread_msg_tags[msg]); > +       } > + > +       if (nr_threads > 1) { > +               sched_setaffinity(0, MMAP_CPU_MASK_BYTES(&thread_data[0].mask- > >affinity), > +                                 (cpu_set_t *)thread_data[0].mask- > >affinity.bits); > +       } >   >         thread = &thread_data[0]; >   >         pr_debug("threads[%d]: started on cpu=%d\n", thread->tid, > sched_getcpu()); >   > -       return 0; > +out_err: > +       if (sigprocmask(SIG_SETMASK, &mask, NULL)) { > +               pr_err("Failed to unblock signals on threads start: %s\n", > strerror(errno)); > +               ret = -1; > +       } > + > +       return ret; >  } ASan complains of a memory leak of the attrs, since pthread_attr_destroy is missing. It could be added just after out_err label. Thanks, Riccardo >   >  static int record__stop_threads(struct record *rec, unsigned long *waking)