Received: by 2002:a25:7ec1:0:0:0:0:0 with SMTP id z184csp2540486ybc; Wed, 20 Nov 2019 16:17:35 -0800 (PST) X-Google-Smtp-Source: APXvYqynJhFtTpKDGSUfYgEbTgq2TZ5lF2KOX+UUFEoeVlDY9EbAcKumURqSG8jiVYZ5MHgUO6Uo X-Received: by 2002:a17:907:20d2:: with SMTP id qq18mr9141423ejb.305.1574295455480; Wed, 20 Nov 2019 16:17:35 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1574295455; cv=none; d=google.com; s=arc-20160816; b=Q/RtTb9nPrC7169lyQhPVHXNLCtcwfMecEuNDu7F7yJtU14EEbIOUECHdSUhjEAf1O S/BmWATagItOCD23YIyHQBLm2u+GRDjUvJv/btewOSbmVHcQHWiMc5eMmWBkSm9MhR5C wos2P/vVTIaH6BmLMiABZZQdJH2whI5a9U1mLRnFwr8ZhTMclpSYqtxWbUHcvbEwClHY AhRHgWGqmD1L+NUYpJGRmLJ6t1k3cqx4PuUutAA+dzcP+gumob0xkE0aHs2udQDSTfMo V8PeUdi95wc7JR67gPVMVDxHmsfAwtOFYN5b5Q1Pkx9c70dVH03djNmPcqg7eAKUS42b bm/Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=LPyH1aWX+03zGqHgOvnZh4AGR+CGvu6Mr/MMdw49zlw=; b=X7s4Vh/xwuyaeL4av1BK0UXSm10npBI+sG/mdh7k+qYu4EAJyxwS8MfnTQKqfw1zx5 NS6jAsCfOvz++IborveTJHnDGc+yBUvPtlT+YuOalQ83Hn1SlUookm5vyw8rYMjVLajQ 3oO5wLacs+w/D2lbP9v/LAfE8sj4G8uQKrvg5RC3zDCQb6QzB4MJiMqURIz0WmX/oqUF 6CxqvPGvWrs/AgteW9M9I5yHds4uNKHNaXVrtUkrSPZLr3yO180IIVmM02cRw2Pq7hmT xsnMn8cq4l1CsY4ke+pWQUD0wvFHGdRTUFTwljP38FhCcxV6fyhWewUAxrW+ajEUEfAu BQYA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i13si529499ejz.428.2019.11.20.16.17.12; Wed, 20 Nov 2019 16:17:35 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727146AbfKUAPq (ORCPT + 99 others); Wed, 20 Nov 2019 19:15:46 -0500 Received: from mga06.intel.com ([134.134.136.31]:58451 "EHLO mga06.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727050AbfKUAPg (ORCPT ); Wed, 20 Nov 2019 19:15:36 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Nov 2019 16:15:34 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,223,1571727600"; d="scan'208";a="381553874" Received: from tassilo.jf.intel.com (HELO tassilo.localdomain) ([10.7.201.21]) by orsmga005.jf.intel.com with ESMTP; 20 Nov 2019 16:15:34 -0800 Received: by tassilo.localdomain (Postfix, from userid 1000) id 86B94300FC7; Wed, 20 Nov 2019 16:15:34 -0800 (PST) From: Andi Kleen To: acme@kernel.org Cc: jolsa@kernel.org, linux-kernel@vger.kernel.org, Andi Kleen Subject: [PATCH 02/12] perf affinity: Add infrastructure to save/restore affinity Date: Wed, 20 Nov 2019 16:15:12 -0800 Message-Id: <20191121001522.180827-3-andi@firstfloor.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191121001522.180827-1-andi@firstfloor.org> References: <20191121001522.180827-1-andi@firstfloor.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Andi Kleen The kernel perf subsystem has to IPI to the target CPU for many operations. On systems with many CPUs and when managing many events the overhead can be dominated by lots of IPIs. An alternative is to set up CPU affinity in the perf tool, then set up all the events for that CPU, and then move on to the next CPU. Add some affinity management infrastructure to enable such a model. Used in followon patches. Signed-off-by: Andi Kleen --- v2: Use linux/bitmap.h functions. v3: Add affinity.c to the python-ext-sources to fix the python interface. Thanks 0day! --- tools/perf/util/Build | 1 + tools/perf/util/affinity.c | 72 ++++++++++++++++++++++++++++++ tools/perf/util/affinity.h | 15 +++++++ tools/perf/util/python-ext-sources | 1 + 4 files changed, 89 insertions(+) create mode 100644 tools/perf/util/affinity.c create mode 100644 tools/perf/util/affinity.h diff --git a/tools/perf/util/Build b/tools/perf/util/Build index aab05e2c01a5..07da6c790b63 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -77,6 +77,7 @@ perf-y += sort.o perf-y += hist.o perf-y += util.o perf-y += cpumap.o +perf-y += affinity.o perf-y += cputopo.o perf-y += cgroup.o perf-y += target.o diff --git a/tools/perf/util/affinity.c b/tools/perf/util/affinity.c new file mode 100644 index 000000000000..e197b0416f56 --- /dev/null +++ b/tools/perf/util/affinity.c @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Manage affinity to optimize IPIs inside the kernel perf API. */ +#define _GNU_SOURCE 1 +#include +#include +#include +#include "perf.h" +#include "cpumap.h" +#include "affinity.h" + +static int get_cpu_set_size(void) +{ + int sz = cpu__max_cpu() + 8 - 1; + /* + * sched_getaffinity doesn't like masks smaller than the kernel. + * Hopefully that's big enough. + */ + if (sz < 4096) + sz = 4096; + return sz/8; +} + +int affinity__setup(struct affinity *a) +{ + int cpu_set_size = get_cpu_set_size(); + + a->orig_cpus = bitmap_alloc(cpu_set_size*8); + if (!a->orig_cpus) + return -1; + sched_getaffinity(0, cpu_set_size, (cpu_set_t *)a->orig_cpus); + a->sched_cpus = bitmap_alloc(cpu_set_size*8); + if (!a->sched_cpus) { + free(a->orig_cpus); + return -1; + } + bitmap_zero((unsigned long *)a->sched_cpus, cpu_set_size); + a->changed = false; + return 0; +} + +/* + * perf_event_open does an IPI internally to the target CPU. + * It is more efficient to change perf's affinity to the target + * CPU and then set up all events on that CPU, so we amortize + * CPU communication. + */ +void affinity__set(struct affinity *a, int cpu) +{ + int cpu_set_size = get_cpu_set_size(); + + if (cpu == -1) + return; + a->changed = true; + set_bit(cpu, a->sched_cpus); + /* + * We ignore errors because affinity is just an optimization. + * This could happen for example with isolated CPUs or cpusets. + * In this case the IPIs inside the kernel's perf API still work. + */ + sched_setaffinity(0, cpu_set_size, (cpu_set_t *)a->sched_cpus); + clear_bit(cpu, a->sched_cpus); +} + +void affinity__cleanup(struct affinity *a) +{ + int cpu_set_size = get_cpu_set_size(); + + if (a->changed) + sched_setaffinity(0, cpu_set_size, (cpu_set_t *)a->orig_cpus); + free(a->sched_cpus); + free(a->orig_cpus); +} diff --git a/tools/perf/util/affinity.h b/tools/perf/util/affinity.h new file mode 100644 index 000000000000..008e2c3995b9 --- /dev/null +++ b/tools/perf/util/affinity.h @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0 +#ifndef AFFINITY_H +#define AFFINITY_H 1 + +struct affinity { + unsigned long *orig_cpus; + unsigned long *sched_cpus; + bool changed; +}; + +void affinity__cleanup(struct affinity *a); +void affinity__set(struct affinity *a, int cpu); +int affinity__setup(struct affinity *a); + +#endif diff --git a/tools/perf/util/python-ext-sources b/tools/perf/util/python-ext-sources index 9af183860fbd..e7279ea6043a 100644 --- a/tools/perf/util/python-ext-sources +++ b/tools/perf/util/python-ext-sources @@ -33,3 +33,4 @@ util/trace-event.c util/string.c util/symbol_fprintf.c util/units.c +util/affinity.c -- 2.23.0