Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp4509818pxj; Tue, 22 Jun 2021 01:44:38 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzcFx3MrEJ+7a9ITG35KEg0raKVQrHz9eg/CSgLuq/xikg3Dhi7M1cF0DjSz7nh4xC0vt3+ X-Received: by 2002:a17:906:f153:: with SMTP id gw19mr373974ejb.410.1624351477869; Tue, 22 Jun 2021 01:44:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1624351477; cv=none; d=google.com; s=arc-20160816; b=wr/HwsQqYZuJTjbk6+Kniaz74jN1Yld32//nKzN1UgrXVKCB/LNE+G0T8PgpiF9P1f mashVpNBKaqG9/gKUcEI7zZ3c5HnY6KtgLYdASfnNYLGpQFUganJwDHQpr16HESaagck e0KGZYN+pJ4kDA+VxViHWAt2IxLiinzp4ZI6RjfsrGXraDKGFvS4ZIEpgwkLQWMzv327 n7AHSLaNfWNaWLPdsQ29BHwAzw4YwQrakqtj0p1D3EdIE9M/yAWZ1FV5Zdjmh8abuL1Z McvYtrKGzAH3YyAknXvKuG2KmN3wrtwKlxhsLr6MUu16+f5iX3ahHpzsEx+GD6FnQV8d nXZg== 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 :ironport-sdr:ironport-sdr; bh=9OxQo9KE77zkzBag6dGwUQ9TXXs9/U7eiOpPhR4HNHs=; b=bb6QX/14OphQwampW66EasSG7j5ABOpOafMn8iFBlxassTTZB9zN5vmKXNKVZSsWkC VwfbyoBrEdkenoI5AgHmnHRSBqaZL1qhDlpooFMfxgLr1KuB9vsMnvzhzWAK/graev// A00odemNuwGQ4Muu+hQj9FOWm2dltEjKf80ffg5SwafbIwQWZIxf34Jl7qFECtNofszi nEIm7Ki5gajjqy0+suhndpiieuLBY8ORv4rqcEwrj11eCfGeP4u1qZ320dhWYrA0g42q F6fz4ejaU/jd3bUrhDwBCvIBGm56OQVnbvK0cdSmuNo6RcnrP43VPe8i24QwdFFkUi9J qKgA== 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 el8si7407567ejc.231.2021.06.22.01.44.15; Tue, 22 Jun 2021 01:44:37 -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 S231134AbhFVIpF (ORCPT + 99 others); Tue, 22 Jun 2021 04:45:05 -0400 Received: from mga05.intel.com ([192.55.52.43]:57595 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231130AbhFVIpE (ORCPT ); Tue, 22 Jun 2021 04:45:04 -0400 IronPort-SDR: FrKcNwN5ZmWS89ESI3HQzT5PjGi55UXaobel/sLK3gtDfx1K2EhCIXejKEr96VLlJvpHDxsszq ogc/iIjiEb8w== X-IronPort-AV: E=McAfee;i="6200,9189,10022"; a="292641538" X-IronPort-AV: E=Sophos;i="5.83,291,1616482800"; d="scan'208";a="292641538" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Jun 2021 01:42:49 -0700 IronPort-SDR: iTNA7mEe5dhj+a1qDF+tNioadlwliHm4C8bupKZCfUEbB/X60RdWIquFa3Gvww6b13iExC2XPw Pvg7sDNDC2UQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.83,291,1616482800"; d="scan'208";a="417332502" Received: from nntpat99-84.inn.intel.com ([10.125.99.84]) by fmsmga007.fm.intel.com with ESMTP; 22 Jun 2021 01:42:46 -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 v7 05/20] perf record: Start threads in the beginning of trace streaming Date: Tue, 22 Jun 2021 11:42:14 +0300 Message-Id: <67409751c59b14105577869ef8a986ad0ba0b9b1.1624350588.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. Signed-off-by: Alexey Bayduraev --- tools/perf/builtin-record.c | 108 +++++++++++++++++++++++++++++++++++- 1 file changed, 107 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index d30e0c5bece3..b02d97507fcb 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,59 @@ 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: + 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