Received: by 2002:a05:6a10:9848:0:0:0:0 with SMTP id x8csp4224254pxf; Tue, 6 Apr 2021 10:48:14 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxGFUfuXXtBxs2fVl6l86k5fmfcoeIxiooNs22g1s3mH6iU1CfyU9xQ5Z/HLISVIsErSSGB X-Received: by 2002:a17:906:6d4c:: with SMTP id a12mr6077121ejt.459.1617731294568; Tue, 06 Apr 2021 10:48:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1617731294; cv=none; d=google.com; s=arc-20160816; b=LoXgMrY0tZHKPEn+pvNP5Gm7k8+oVgi9xd8yDBEjOcc6xeSj2RIV7hg1SztTvAjboT LpuBDjerwIqxV/u5k6BICLZKva6fqqNUll32VN2os7yk6m1PUTZvLVJjlzbHx4TxsZVb yN38fJk+HibPC7ynKSLfViWIJGmGUnm+zOfF+ulb/ptg+fQ6q2Fyim0XOv7ejGXn7K+c e3FRVedECEcWmbBSoiOekUuV63B29YGhaVz1LN9XyOQorSdjIWyAaQfKBR0lZIdf/odi iUstaTtp6Ul0/vGk38fz7/HdtiZnAJfSuSh7du9Z+ETrJwgN5t7kKAiW5QUhE85/qpM2 PUUQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:content-language :in-reply-to:mime-version:user-agent:date:message-id:organization :references:cc:to:from:subject:ironport-sdr:ironport-sdr; bh=470O854S9lb0cenfdVnXSVB6Qi6IPMdiqW3LRXGbAx0=; b=zRc8nIzUTr+rK242JG9FUN7G1T9OYdHO6mbBaKiN1yOrWlCTwd90d0eXadaOQw0wCa /+a0ECZgTl2/njhCmZHcziwc9/m1in7sep97wgekPZ6w025qoXk4aonKEwMLJ4SplkSl uwS3BEQGZVu12bTu9jHubUWbRr8e3cSz7HNNr+yJh5kwTbJaJA8/kNAI/KRqWqvl6sPB Y1KMndcgO/iOuSupdQJwePwj4IOVg6Fq3gC+/uBupVYW/TTz3lKfjy3IDuDI5bfqFuCm ET+wwEpoZGwYiquTB/jXxfpqtkeojbY6gr0cWMMo7OOCHTX5Fz1cDUZS9hGwH3pXn3en CeFw== 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 o7si5587143ejj.449.2021.04.06.10.47.51; Tue, 06 Apr 2021 10:48:14 -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 S244521AbhDFIpu (ORCPT + 99 others); Tue, 6 Apr 2021 04:45:50 -0400 Received: from mga17.intel.com ([192.55.52.151]:34325 "EHLO mga17.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S244513AbhDFIpu (ORCPT ); Tue, 6 Apr 2021 04:45:50 -0400 IronPort-SDR: HjHu8DPAyTtu03q0ABuzgmaJpRUeYXRZL0m/9/XJqsdEDiQo6iUcjGw6kko3QdmOT8WyB0CmeE ooSxMsuKmRlg== X-IronPort-AV: E=McAfee;i="6000,8403,9945"; a="173099344" X-IronPort-AV: E=Sophos;i="5.81,308,1610438400"; d="scan'208";a="173099344" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Apr 2021 01:45:42 -0700 IronPort-SDR: 4tFQ4+jP7sD6tNAgsAfsZnSKSeK0xs4FhzPtyH85rpGskQlfhzlN0dnWaDIIIy4hTliXHdY+9Z 4/iCW4Ie+U4g== X-IronPort-AV: E=Sophos;i="5.81,308,1610438400"; d="scan'208";a="421122029" Received: from abaydur-mobl1.ccr.corp.intel.com (HELO [10.249.228.164]) ([10.249.228.164]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Apr 2021 01:45:39 -0700 Subject: [PATCH v4 05/12] perf record: start threads in the beginning of trace streaming From: "Bayduraev, Alexey V" To: Arnaldo Carvalho de Melo Cc: Jiri Olsa , Namhyung Kim , Alexander Shishkin , Peter Zijlstra , Ingo Molnar , linux-kernel , Andi Kleen , Adrian Hunter , Alexei Budankov , Alexander Antonov References: <6c15adcb-6a9d-320e-70b5-957c4c8b6ff2@linux.intel.com> Organization: Intel Corporation Message-ID: Date: Tue, 6 Apr 2021 11:45:37 +0300 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Thunderbird/78.9.0 MIME-Version: 1.0 In-Reply-To: <6c15adcb-6a9d-320e-70b5-957c4c8b6ff2@linux.intel.com> Content-Type: text/plain; charset=utf-8 Content-Language: en-GB Content-Transfer-Encoding: 7bit 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 | 103 +++++++++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 4612314853c1..339198b2e37d 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -1412,6 +1412,64 @@ 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. Error %m", thread->tid); + + 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; + } + + err = write(thread->pipes.ack[1], &msg, sizeof(msg)); + if (err == -1) + pr_err("threads[%d]: failed to notify on termination. Error %m", thread->tid); + + return NULL; +} + static void record__init_features(struct record *rec) { struct perf_session *session = rec->session; @@ -1849,13 +1907,56 @@ 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. Error: %m\n"); + 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. Error: %m\n"); + 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. Error: %m\n"); + ret = -1; + } + + return ret; } static int record__stop_threads(struct record *rec, unsigned long *waking) -- 2.19.0