Received: by 2002:a05:6a10:1d13:0:0:0:0 with SMTP id pp19csp1012961pxb; Tue, 17 Aug 2021 01:26:17 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzJ23vHitt6KswC28r614VPOYIvDqD3uY5kcCa5Cy6X25ESb/EQ3iZ5BdF+rO033iKelstW X-Received: by 2002:a50:fd82:: with SMTP id o2mr2857501edt.294.1629188776968; Tue, 17 Aug 2021 01:26:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1629188776; cv=none; d=google.com; s=arc-20160816; b=Azdr6jRqu5gH7yv0yQEiE2oMNkpfXrv0jQFSIRRzz49CyJL3My+iMxk3eniwCk58ut tYh3PVTCgdgZqhcoEGNiDHjqpv4JkWQzd7S0ng1sMuh8gkIM8C8xNEGKYmu3xF+9zc+i eJwzAcLcGJi9nJFFWe806Wcw/hIB/iwIEtrJvn6rt6XnEsiLRD2xFze/AO8vCnop96DR Woz07SeGM9FlGpLf5s1MN2MAhDNP12RvDHlluQl4j1+Mrq5YX5f6neqIILTE8n3g9Gl6 qLeaWSe3i1+l73Zwq6tQeUJCLT43Splo69zivBgfBXtwX9yRGH33633+aMf0RbwqRCgU gZZw== 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 :references:in-reply-to:message-id:date:subject:cc:to:from; bh=xWBVqBVlrffqvisV8GQNZ3csF8aXb8vAbwyKaGioHBM=; b=xR0M/FlSCe7ceY2aL/o+u2TfCUta7u4e+kO4Zkpk2SzY0/ayfNy9j23t5M9YUxFIQi cs1TpGlJ1hAJKuMRv+y0K+2yjRWisi3rdlbsxsQCn5jw5UWZBHMlUOtz4m2vCPGMbjfy sNzdE1ZjUqSQoIGxGkFM1XM1Jt1GE9jBzOm/lj4WNJOsTyoY3FjS9Ry+E962Pl8APkUh a2eJqrclbbzJk05FpS0J+d3p23mY894urpcvWtFjdElXodm9Zp14AGzHC4LrbQvPDOhU 0l8AOVk3EB9K/qFUH8Iif9XAeAHO8PA6DfdmCYgDk4JbKPVs04Nsk1Bs3hGlZ8HG4koH +ETA== ARC-Authentication-Results: i=1; mx.google.com; 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=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id y21si1659018edo.603.2021.08.17.01.25.54; Tue, 17 Aug 2021 01:26:16 -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; 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=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239248AbhHQIYm (ORCPT + 99 others); Tue, 17 Aug 2021 04:24:42 -0400 Received: from mga07.intel.com ([134.134.136.100]:11537 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239268AbhHQIY0 (ORCPT ); Tue, 17 Aug 2021 04:24:26 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10078"; a="279763211" X-IronPort-AV: E=Sophos;i="5.84,328,1620716400"; d="scan'208";a="279763211" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Aug 2021 01:23:54 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.84,328,1620716400"; d="scan'208";a="471080242" Received: from nntpat99-84.inn.intel.com ([10.125.99.84]) by orsmga008.jf.intel.com with ESMTP; 17 Aug 2021 01:23:51 -0700 From: Alexey Bayduraev To: Arnaldo Carvalho de Melo Cc: Jiri Olsa , Namhyung Kim , Alexander Shishkin , Peter Zijlstra , Ingo Molnar , linux-kernel , Andi Kleen , Adrian Hunter , Alexander Antonov , Alexei Budankov , Riccardo Mancini Subject: [PATCH v11 07/24] perf record: Start threads in the beginning of trace streaming Date: Tue, 17 Aug 2021 11:23:10 +0300 Message-Id: <0b55237124aee9e348449540691320b66879be6c.1629186429.git.alexey.v.bayduraev@linux.intel.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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. Acked-by: Namhyung Kim Reviewed-by: Riccardo Mancini Tested-by: Riccardo Mancini Signed-off-by: Alexey Bayduraev --- tools/perf/builtin-record.c | 109 +++++++++++++++++++++++++++++++++++- 1 file changed, 108 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 04e77b5487bb..fb1c1b46dd04 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -1484,6 +1484,67 @@ 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 = 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]); + thread->pipes.msg[0] = -1; + 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; @@ -1918,13 +1979,59 @@ static int record__terminate_thread(struct record_thread *thread_data) static int record__start_threads(struct record *rec) { + int t, tt, ret = 0, nr_threads = rec->nr_threads; struct record_thread *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: + pthread_attr_destroy(&attrs); + + if (sigprocmask(SIG_SETMASK, &mask, NULL)) { + pr_err("Failed to unblock signals on threads start: %s\n", strerror(errno)); + ret = -1; + } + + return ret; } static int record__stop_threads(struct record *rec, unsigned long *waking) -- 2.19.0