Received: by 2002:a25:ad19:0:0:0:0:0 with SMTP id y25csp5187165ybi; Tue, 30 Jul 2019 15:43:23 -0700 (PDT) X-Google-Smtp-Source: APXvYqxWtczcTOGXT7Pv/Tl1K3Vk3YgD5bcFr+FxHMq4q135Qv3tkZ8j6cGbgZpA1340pUX3CQ7H X-Received: by 2002:a17:902:2ea2:: with SMTP id r31mr13523276plb.200.1564526603273; Tue, 30 Jul 2019 15:43:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1564526603; cv=none; d=google.com; s=arc-20160816; b=aKXyrTSxyc5x/sNgAdmO7ixNd8BdEoniMU8GBHmuNxIRVMuMDEEltTT1kyIHmW0e/v 9ok3lc9mf1ahbJyoPassNEmpKDUgvAj5pfkwjL2oyXcvkr4h66aBSzrc2Ex3AsklUTYb eCU1wQm2p6DPTBvWcPq/A3GnZYDNtYZCu6PfO2Vn1Yw9RHo+tD/5W5jWTQB1fPGNIARH f9gx/gjjcjpDS614dtemrlY4kIK0Kq4z02k5YnhZJcn4EkC8cRm5hoULW7MCAdNssKNA uO9zTE+9/Qa3MUoh4mU+Aa7/9qzDcIoUpLRKxDFBTGdkw1HnFfIUHHnyP8a6Y1lh4BUo fTpQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-disposition :content-transfer-encoding:mime-version:robot-unsubscribe:robot-id :git-commit-id:subject:to:references:in-reply-to:reply-to:cc :message-id:from:date:dkim-signature:dkim-filter; bh=tMX8kpm2ip7uhZYOQjC4RDCfdHAPtGwN6agP6KB1xf0=; b=Otfg8W0DZfeAh6JnTtOQrnXFpysCRcniuVMiZH/0ux0bHcwz2dm7IeTT5TnNxeV2U4 74Zu809QZ+a5pNtTm/QeavTpmpmiow02JzTkrs9MBQdytm+O6Ps3CEMGC6cGSUi+FxTu Lm05rYE41XVKZhvcQ9HOCuBEuAgHngN3783ZNkNaR6Md2+GuucU99kzrN+r3KRhcHO7Y qpXmYsVXsAZCapKS6KWjuCoo3L8bK+iAABIOkb+10aLr5zSniTT6uz6os96QoQkOwnlI ybF5jiMfNVkVPnzhaDAb7/cGduY2sphXYK7zX1Je9WNXvYOMTU8jS2kXVM8Bq5ILq6lU tU6g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@zytor.com header.s=2019071901 header.b=wDHM0oEx; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=zytor.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r3si31617961pls.176.2019.07.30.15.43.08; Tue, 30 Jul 2019 15:43:23 -0700 (PDT) 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; dkim=pass header.i=@zytor.com header.s=2019071901 header.b=wDHM0oEx; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=zytor.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728422AbfG3THQ (ORCPT + 99 others); Tue, 30 Jul 2019 15:07:16 -0400 Received: from terminus.zytor.com ([198.137.202.136]:33667 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726133AbfG3THQ (ORCPT ); Tue, 30 Jul 2019 15:07:16 -0400 Received: from terminus.zytor.com (localhost [127.0.0.1]) by terminus.zytor.com (8.15.2/8.15.2) with ESMTPS id x6UJ73fw3340402 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Tue, 30 Jul 2019 12:07:03 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 terminus.zytor.com x6UJ73fw3340402 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2019071901; t=1564513624; bh=tMX8kpm2ip7uhZYOQjC4RDCfdHAPtGwN6agP6KB1xf0=; h=Date:From:Cc:Reply-To:In-Reply-To:References:To:Subject:From; b=wDHM0oExdoMIGC5zfMiwPZbS96aTZaCRi9mp/+zKIRAjBwcCP5Fci2FCbEqq4H7QD V/wbBG1doXLWQjPvGxd2O5Muipaz6inbRvz2s3oHWqZ0iLSDMnJpHGqRX6TyOL90jJ DVZ+o1nng8QV4jqpUSgW7PTIw11kdSOyPWGVdiV0bMd4uX9qwe5wU2VgsizqmPZHdH 510f4+2UV5z9iFjzUuF/E0VZsHv3yyks/UAX6UHJPPbUiwaULZPPKGnIkwQ6KFHeKf s7zGMw26/6ArXx6W2ngL/RxyhSbfC3X4e4jQr+NfYuzUCaoxYsDWN9qMu3mTsfYQf1 TcndxQIcpg6cg== Received: (from tipbot@localhost) by terminus.zytor.com (8.15.2/8.15.2/Submit) id x6UJ727E3340397; Tue, 30 Jul 2019 12:07:02 -0700 Date: Tue, 30 Jul 2019 12:07:02 -0700 X-Authentication-Warning: terminus.zytor.com: tipbot set sender to tipbot@zytor.com using -f From: tip-bot for Jiri Olsa Message-ID: Cc: peterz@infradead.org, alexander.shishkin@linux.intel.com, linux-kernel@vger.kernel.org, acme@redhat.com, namhyung@kernel.org, alexey.budankov@linux.intel.com, tglx@linutronix.de, mpetlan@redhat.com, ak@linux.intel.com, jolsa@kernel.org, mingo@kernel.org, hpa@zytor.com Reply-To: jolsa@kernel.org, mpetlan@redhat.com, ak@linux.intel.com, namhyung@kernel.org, alexey.budankov@linux.intel.com, linux-kernel@vger.kernel.org, mingo@kernel.org, hpa@zytor.com, tglx@linutronix.de, acme@redhat.com, alexander.shishkin@linux.intel.com, peterz@infradead.org In-Reply-To: <20190721112506.12306-80-jolsa@kernel.org> References: <20190721112506.12306-80-jolsa@kernel.org> To: linux-tip-commits@vger.kernel.org Subject: [tip:perf/core] libperf: Initial documentation Git-Commit-ID: f4f48e9c1adb49f732ac0abc4b2513f2b62a10cb X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline X-Spam-Status: No, score=-0.2 required=5.0 tests=ALL_TRUSTED,BAYES_00, DATE_IN_FUTURE_96_Q,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF autolearn=no autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on terminus.zytor.com Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: f4f48e9c1adb49f732ac0abc4b2513f2b62a10cb Gitweb: https://git.kernel.org/tip/f4f48e9c1adb49f732ac0abc4b2513f2b62a10cb Author: Jiri Olsa AuthorDate: Sun, 21 Jul 2019 13:25:06 +0200 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 29 Jul 2019 18:34:47 -0300 libperf: Initial documentation Add initial drafts of documentation files, hugely unfinished. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-80-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/Documentation/Makefile | 7 ++ tools/perf/lib/Documentation/man/libperf.rst | 100 +++++++++++++++++ tools/perf/lib/Documentation/tutorial/tutorial.rst | 123 +++++++++++++++++++++ 3 files changed, 230 insertions(+) diff --git a/tools/perf/lib/Documentation/Makefile b/tools/perf/lib/Documentation/Makefile new file mode 100644 index 000000000000..586425a88795 --- /dev/null +++ b/tools/perf/lib/Documentation/Makefile @@ -0,0 +1,7 @@ +all: + rst2man man/libperf.rst > man/libperf.7 + rst2pdf tutorial/tutorial.rst + +clean: + rm -f man/libperf.7 + rm -f tutorial/tutorial.pdf diff --git a/tools/perf/lib/Documentation/man/libperf.rst b/tools/perf/lib/Documentation/man/libperf.rst new file mode 100644 index 000000000000..09a270fccb9c --- /dev/null +++ b/tools/perf/lib/Documentation/man/libperf.rst @@ -0,0 +1,100 @@ +.. SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) + +libperf + +The libperf library provides an API to access the linux kernel perf +events subsystem. It provides the following high level objects: + + - struct perf_cpu_map + - struct perf_thread_map + - struct perf_evlist + - struct perf_evsel + +reference +========= +Function reference by header files: + +perf/core.h +----------- +.. code-block:: c + + typedef int (\*libperf_print_fn_t)(enum libperf_print_level level, + const char \*, va_list ap); + + void libperf_set_print(libperf_print_fn_t fn); + +perf/cpumap.h +------------- +.. code-block:: c + + struct perf_cpu_map \*perf_cpu_map__dummy_new(void); + struct perf_cpu_map \*perf_cpu_map__new(const char \*cpu_list); + struct perf_cpu_map \*perf_cpu_map__read(FILE \*file); + struct perf_cpu_map \*perf_cpu_map__get(struct perf_cpu_map \*map); + void perf_cpu_map__put(struct perf_cpu_map \*map); + int perf_cpu_map__cpu(const struct perf_cpu_map \*cpus, int idx); + int perf_cpu_map__nr(const struct perf_cpu_map \*cpus); + perf_cpu_map__for_each_cpu(cpu, idx, cpus) + +perf/threadmap.h +---------------- +.. code-block:: c + + struct perf_thread_map \*perf_thread_map__new_dummy(void); + void perf_thread_map__set_pid(struct perf_thread_map \*map, int thread, pid_t pid); + char \*perf_thread_map__comm(struct perf_thread_map \*map, int thread); + struct perf_thread_map \*perf_thread_map__get(struct perf_thread_map \*map); + void perf_thread_map__put(struct perf_thread_map \*map); + +perf/evlist.h +------------- +.. code-block:: + + void perf_evlist__init(struct perf_evlist \*evlist); + void perf_evlist__add(struct perf_evlist \*evlist, + struct perf_evsel \*evsel); + void perf_evlist__remove(struct perf_evlist \*evlist, + struct perf_evsel \*evsel); + struct perf_evlist \*perf_evlist__new(void); + void perf_evlist__delete(struct perf_evlist \*evlist); + struct perf_evsel\* perf_evlist__next(struct perf_evlist \*evlist, + struct perf_evsel \*evsel); + int perf_evlist__open(struct perf_evlist \*evlist); + void perf_evlist__close(struct perf_evlist \*evlist); + void perf_evlist__enable(struct perf_evlist \*evlist); + void perf_evlist__disable(struct perf_evlist \*evlist); + perf_evlist__for_each_evsel(evlist, pos) + void perf_evlist__set_maps(struct perf_evlist \*evlist, + struct perf_cpu_map \*cpus, + struct perf_thread_map \*threads); + +perf/evsel.h +------------ +.. code-block:: c + + struct perf_counts_values { + union { + struct { + uint64_t val; + uint64_t ena; + uint64_t run; + }; + uint64_t values[3]; + }; + }; + + void perf_evsel__init(struct perf_evsel \*evsel, + struct perf_event_attr \*attr); + struct perf_evsel \*perf_evsel__new(struct perf_event_attr \*attr); + void perf_evsel__delete(struct perf_evsel \*evsel); + int perf_evsel__open(struct perf_evsel \*evsel, struct perf_cpu_map \*cpus, + struct perf_thread_map \*threads); + void perf_evsel__close(struct perf_evsel \*evsel); + int perf_evsel__read(struct perf_evsel \*evsel, int cpu, int thread, + struct perf_counts_values \*count); + int perf_evsel__enable(struct perf_evsel \*evsel); + int perf_evsel__disable(struct perf_evsel \*evsel); + int perf_evsel__apply_filter(struct perf_evsel \*evsel, const char \*filter); + struct perf_cpu_map \*perf_evsel__cpus(struct perf_evsel \*evsel); + struct perf_thread_map \*perf_evsel__threads(struct perf_evsel \*evsel); + struct perf_event_attr \*perf_evsel__attr(struct perf_evsel \*evsel); diff --git a/tools/perf/lib/Documentation/tutorial/tutorial.rst b/tools/perf/lib/Documentation/tutorial/tutorial.rst new file mode 100644 index 000000000000..7be7bc27b385 --- /dev/null +++ b/tools/perf/lib/Documentation/tutorial/tutorial.rst @@ -0,0 +1,123 @@ +.. SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) + +libperf tutorial +================ + +Compile and install libperf from kernel sources +=============================================== +.. code-block:: bash + + git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git + cd linux/tools/perf/lib + make + sudo make install prefix=/usr + +Libperf object +============== +The libperf library provides several high level objects: + +struct perf_cpu_map + Provides a cpu list abstraction. + +struct perf_thread_map + Provides a thread list abstraction. + +struct perf_evsel + Provides an abstraction for single a perf event. + +struct perf_evlist + Gathers several struct perf_evsel object and performs functions on all of them. + +The exported API binds these objects together, +for full reference see the libperf.7 man page. + +Examples +======== +Examples aim to explain libperf functionality on simple use cases. +They are based in on a checked out linux kernel git tree: + +.. code-block:: bash + + $ cd tools/perf/lib/Documentation/tutorial/ + $ ls -d ex-* + ex-1-compile ex-2-evsel-stat ex-3-evlist-stat + +ex-1-compile example +==================== +This example shows the basic usage of *struct perf_cpu_map*, +how to create it and display its cpus: + +.. code-block:: bash + + $ cd ex-1-compile/ + $ make + gcc -o test test.c -lperf + $ ./test + 0 1 2 3 4 5 6 7 + + +The full code listing is here: + +.. code-block:: c + + 1 #include + 2 + 3 int main(int argc, char **Argv) + 4 { + 5 struct perf_cpu_map *cpus; + 6 int cpu, tmp; + 7 + 8 cpus = perf_cpu_map__new(NULL); + 9 + 10 perf_cpu_map__for_each_cpu(cpu, tmp, cpus) + 11 fprintf(stdout, "%d ", cpu); + 12 + 13 fprintf(stdout, "\n"); + 14 + 15 perf_cpu_map__put(cpus); + 16 return 0; + 17 } + + +First you need to include the proper header to have *struct perf_cpumap* +declaration and functions: + +.. code-block:: c + + 1 #include + + +The *struct perf_cpumap* object is created by *perf_cpu_map__new* call. +The *NULL* argument asks it to populate the object with the current online CPUs list: + +.. code-block:: c + + 8 cpus = perf_cpu_map__new(NULL); + +This is paired with a *perf_cpu_map__put*, that drops its reference at the end, possibly deleting it. + +.. code-block:: c + + 15 perf_cpu_map__put(cpus); + +The iteration through the *struct perf_cpumap* CPUs is done using the *perf_cpu_map__for_each_cpu* +macro which requires 3 arguments: + +- cpu - the cpu numer +- tmp - iteration helper variable +- cpus - the *struct perf_cpumap* object + +.. code-block:: c + + 10 perf_cpu_map__for_each_cpu(cpu, tmp, cpus) + 11 fprintf(stdout, "%d ", cpu); + +ex-2-evsel-stat example +======================= + +TBD + +ex-3-evlist-stat example +======================== + +TBD