Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

libperf: Add man pages

Change the man page generation to asciidoc, because it's easier to use
and has been more commonly used in related projects. Remove the current
rst pages.

Add 3 man pages to have a base for more additions:

libperf.3 - overall description
libperf-counting.7 - counting basics explained on simple example
libperf-sampling.7 - sampling basics explained on simple example

The plan is to add more man pages to cover the basic API.

The build generates html and man pages:

$ cd tools/lib/perf/Documentation
$ make
ASCIIDOC libperf.xml
XMLTO libperf.3
ASCIIDOC libperf-counting.xml
XMLTO libperf-counting.7
ASCIIDOC libperf-sampling.xml
XMLTO libperf-sampling.7
ASCIIDOC libperf.html
ASCIIDOC libperf-counting.html
ASCIIDOC libperf-sampling.html

Add the following install targets:

install-man - man pages
install-html - html version of man pages
install-examples - examples mentioned in the man pages

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Michael Petlan <mpetlan@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lore.kernel.org/lkml/20191206210612.8676-3-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Jiri Olsa and committed by
Arnaldo Carvalho de Melo
81de3bf3 3ce311af

+1197 -229
+154 -5
tools/lib/perf/Documentation/Makefile
··· 1 - all: 2 - rst2man man/libperf.rst > man/libperf.7 3 - rst2pdf tutorial/tutorial.rst 1 + # SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) 2 + # Most of this file is copied from tools/perf/Documentation/Makefile 3 + 4 + include ../../../scripts/Makefile.include 5 + include ../../../scripts/utilities.mak 6 + 7 + MAN3_TXT = libperf.txt 8 + MAN7_TXT = libperf-counting.txt libperf-sampling.txt 9 + MAN_EX = examples/*.c 10 + 11 + MAN_TXT = $(MAN3_TXT) $(MAN7_TXT) 12 + 13 + _MAN_XML = $(patsubst %.txt,%.xml,$(MAN_TXT)) 14 + _MAN_HTML = $(patsubst %.txt,%.html,$(MAN_TXT)) 15 + _MAN_3 = $(patsubst %.txt,%.3,$(MAN3_TXT)) 16 + _MAN_7 = $(patsubst %.txt,%.7,$(MAN7_TXT)) 17 + 18 + MAN_XML = $(addprefix $(OUTPUT),$(_MAN_XML)) 19 + MAN_HTML = $(addprefix $(OUTPUT),$(_MAN_HTML)) 20 + MAN_3 = $(addprefix $(OUTPUT),$(_MAN_3)) 21 + MAN_7 = $(addprefix $(OUTPUT),$(_MAN_7)) 22 + MAN_X = $(MAN_3) $(MAN_7) 23 + 24 + # Make the path relative to DESTDIR, not prefix 25 + ifndef DESTDIR 26 + prefix ?=$(HOME) 27 + endif 28 + 29 + mandir ?= $(prefix)/share/man 30 + man3dir = $(mandir)/man3 31 + man7dir = $(mandir)/man7 32 + 33 + docdir ?= $(prefix)/share/doc/libperf 34 + htmldir = $(docdir)/html 35 + exdir = $(docdir)/examples 36 + 37 + ASCIIDOC = asciidoc 38 + ASCIIDOC_EXTRA = --unsafe -f asciidoc.conf 39 + ASCIIDOC_HTML = xhtml11 40 + MANPAGE_XSL = manpage-normal.xsl 41 + XMLTO_EXTRA = 42 + XMLTO =xmlto 43 + 44 + INSTALL ?= install 45 + RM ?= rm -f 46 + 47 + # For asciidoc ... 48 + # -7.1.2, no extra settings are needed. 49 + # 8.0-, set ASCIIDOC8. 50 + # 51 + 52 + # For docbook-xsl ... 53 + # -1.68.1, set ASCIIDOC_NO_ROFF? (based on changelog from 1.73.0) 54 + # 1.69.0, no extra settings are needed? 55 + # 1.69.1-1.71.0, set DOCBOOK_SUPPRESS_SP? 56 + # 1.71.1, no extra settings are needed? 57 + # 1.72.0, set DOCBOOK_XSL_172. 58 + # 1.73.0-, set ASCIIDOC_NO_ROFF 59 + 60 + # If you had been using DOCBOOK_XSL_172 in an attempt to get rid 61 + # of 'the ".ft C" problem' in your generated manpages, and you 62 + # instead ended up with weird characters around callouts, try 63 + # using ASCIIDOC_NO_ROFF instead (it works fine with ASCIIDOC8). 64 + 65 + ifdef ASCIIDOC8 66 + ASCIIDOC_EXTRA += -a asciidoc7compatible 67 + endif 68 + ifdef DOCBOOK_XSL_172 69 + ASCIIDOC_EXTRA += -a libperf-asciidoc-no-roff 70 + MANPAGE_XSL = manpage-1.72.xsl 71 + else 72 + ifdef ASCIIDOC_NO_ROFF 73 + # docbook-xsl after 1.72 needs the regular XSL, but will not 74 + # pass-thru raw roff codes from asciidoc.conf, so turn them off. 75 + ASCIIDOC_EXTRA += -a libperf-asciidoc-no-roff 76 + endif 77 + endif 78 + ifdef MAN_BOLD_LITERAL 79 + XMLTO_EXTRA += -m manpage-bold-literal.xsl 80 + endif 81 + ifdef DOCBOOK_SUPPRESS_SP 82 + XMLTO_EXTRA += -m manpage-suppress-sp.xsl 83 + endif 84 + 85 + DESTDIR ?= 86 + DESTDIR_SQ = '$(subst ','\'',$(DESTDIR))' 87 + 88 + export DESTDIR DESTDIR_SQ 89 + 90 + # Please note that there is a minor bug in asciidoc. 91 + # The version after 6.0.3 _will_ include the patch found here: 92 + # http://marc.theaimsgroup.com/?l=libtraceevent&m=111558757202243&w=2 93 + # 94 + # Until that version is released you may have to apply the patch 95 + # yourself - yes, all 6 characters of it! 96 + 97 + QUIET_SUBDIR0 = +$(MAKE) -C # space to separate -C and subdir 98 + QUIET_SUBDIR1 = 99 + 100 + ifneq ($(findstring $(MAKEFLAGS),w),w) 101 + PRINT_DIR = --no-print-directory 102 + else # "make -w" 103 + NO_SUBDIR = : 104 + endif 105 + 106 + ifneq ($(findstring $(MAKEFLAGS),s),s) 107 + ifneq ($(V),1) 108 + QUIET_ASCIIDOC = @echo ' ASCIIDOC '$@; 109 + QUIET_XMLTO = @echo ' XMLTO '$@; 110 + endif 111 + endif 112 + 113 + all: $(MAN_X) $(MAN_HTML) 114 + 115 + $(MAN_HTML) $(MAN_X): asciidoc.conf 116 + 117 + install-man: all 118 + $(call QUIET_INSTALL, man) \ 119 + $(INSTALL) -d -m 755 $(DESTDIR)$(man3dir); \ 120 + $(INSTALL) -m 644 $(MAN_3) $(DESTDIR)$(man3dir); \ 121 + $(INSTALL) -d -m 755 $(DESTDIR)$(man7dir); \ 122 + $(INSTALL) -m 644 $(MAN_7) $(DESTDIR)$(man7dir); 123 + 124 + install-html: 125 + $(call QUIET_INSTALL, html) \ 126 + $(INSTALL) -d -m 755 $(DESTDIR)$(htmldir); \ 127 + $(INSTALL) -m 644 $(MAN_HTML) $(DESTDIR)$(htmldir); \ 128 + 129 + install-examples: 130 + $(call QUIET_INSTALL, examples) \ 131 + $(INSTALL) -d -m 755 $(DESTDIR)$(exdir); \ 132 + $(INSTALL) -m 644 $(MAN_EX) $(DESTDIR)$(exdir); \ 133 + 134 + CLEAN_FILES = \ 135 + $(MAN_XML) $(addsuffix +,$(MAN_XML)) \ 136 + $(MAN_HTML) $(addsuffix +,$(MAN_HTML)) \ 137 + $(MAN_X) 4 138 5 139 clean: 6 - rm -f man/libperf.7 7 - rm -f tutorial/tutorial.pdf 140 + $(call QUIET_CLEAN, Documentation) $(RM) $(CLEAN_FILES) 141 + 142 + $(MAN_3): $(OUTPUT)%.3: %.xml 143 + $(QUIET_XMLTO)$(XMLTO) -o $(OUTPUT). -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $< 144 + 145 + $(MAN_7): $(OUTPUT)%.7: %.xml 146 + $(QUIET_XMLTO)$(XMLTO) -o $(OUTPUT). -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $< 147 + 148 + $(MAN_XML): $(OUTPUT)%.xml: %.txt 149 + $(QUIET_ASCIIDOC)$(ASCIIDOC) -b docbook -d manpage \ 150 + $(ASCIIDOC_EXTRA) -alibperf_version=$(EVENT_PARSE_VERSION) -o $@+ $< && \ 151 + mv $@+ $@ 152 + 153 + $(MAN_HTML): $(OUTPUT)%.html: %.txt 154 + $(QUIET_ASCIIDOC)$(ASCIIDOC) -b $(ASCIIDOC_HTML) -d manpage \ 155 + $(ASCIIDOC_EXTRA) -aperf_version=$(EVENT_PARSE_VERSION) -o $@+ $< && \ 156 + mv $@+ $@
+120
tools/lib/perf/Documentation/asciidoc.conf
··· 1 + ## linktep: macro 2 + # 3 + # Usage: linktep:command[manpage-section] 4 + # 5 + # Note, {0} is the manpage section, while {target} is the command. 6 + # 7 + # Show TEP link as: <command>(<section>); if section is defined, else just show 8 + # the command. 9 + 10 + [macros] 11 + (?su)[\\]?(?P<name>linktep):(?P<target>\S*?)\[(?P<attrlist>.*?)\]= 12 + 13 + [attributes] 14 + asterisk=&#42; 15 + plus=&#43; 16 + caret=&#94; 17 + startsb=&#91; 18 + endsb=&#93; 19 + tilde=&#126; 20 + 21 + ifdef::backend-docbook[] 22 + [linktep-inlinemacro] 23 + {0%{target}} 24 + {0#<citerefentry>} 25 + {0#<refentrytitle>{target}</refentrytitle><manvolnum>{0}</manvolnum>} 26 + {0#</citerefentry>} 27 + endif::backend-docbook[] 28 + 29 + ifdef::backend-docbook[] 30 + ifndef::tep-asciidoc-no-roff[] 31 + # "unbreak" docbook-xsl v1.68 for manpages. v1.69 works with or without this. 32 + # v1.72 breaks with this because it replaces dots not in roff requests. 33 + [listingblock] 34 + <example><title>{title}</title> 35 + <literallayout> 36 + ifdef::doctype-manpage[] 37 + &#10;.ft C&#10; 38 + endif::doctype-manpage[] 39 + | 40 + ifdef::doctype-manpage[] 41 + &#10;.ft&#10; 42 + endif::doctype-manpage[] 43 + </literallayout> 44 + {title#}</example> 45 + endif::tep-asciidoc-no-roff[] 46 + 47 + ifdef::tep-asciidoc-no-roff[] 48 + ifdef::doctype-manpage[] 49 + # The following two small workarounds insert a simple paragraph after screen 50 + [listingblock] 51 + <example><title>{title}</title> 52 + <literallayout> 53 + | 54 + </literallayout><simpara></simpara> 55 + {title#}</example> 56 + 57 + [verseblock] 58 + <formalpara{id? id="{id}"}><title>{title}</title><para> 59 + {title%}<literallayout{id? id="{id}"}> 60 + {title#}<literallayout> 61 + | 62 + </literallayout> 63 + {title#}</para></formalpara> 64 + {title%}<simpara></simpara> 65 + endif::doctype-manpage[] 66 + endif::tep-asciidoc-no-roff[] 67 + endif::backend-docbook[] 68 + 69 + ifdef::doctype-manpage[] 70 + ifdef::backend-docbook[] 71 + [header] 72 + template::[header-declarations] 73 + <refentry> 74 + <refmeta> 75 + <refentrytitle>{mantitle}</refentrytitle> 76 + <manvolnum>{manvolnum}</manvolnum> 77 + <refmiscinfo class="source">libperf</refmiscinfo> 78 + <refmiscinfo class="version">{libperf_version}</refmiscinfo> 79 + <refmiscinfo class="manual">libperf Manual</refmiscinfo> 80 + </refmeta> 81 + <refnamediv> 82 + <refname>{manname1}</refname> 83 + <refname>{manname2}</refname> 84 + <refname>{manname3}</refname> 85 + <refname>{manname4}</refname> 86 + <refname>{manname5}</refname> 87 + <refname>{manname6}</refname> 88 + <refname>{manname7}</refname> 89 + <refname>{manname8}</refname> 90 + <refname>{manname9}</refname> 91 + <refname>{manname10}</refname> 92 + <refname>{manname11}</refname> 93 + <refname>{manname12}</refname> 94 + <refname>{manname13}</refname> 95 + <refname>{manname14}</refname> 96 + <refname>{manname15}</refname> 97 + <refname>{manname16}</refname> 98 + <refname>{manname17}</refname> 99 + <refname>{manname18}</refname> 100 + <refname>{manname19}</refname> 101 + <refname>{manname20}</refname> 102 + <refname>{manname21}</refname> 103 + <refname>{manname22}</refname> 104 + <refname>{manname23}</refname> 105 + <refname>{manname24}</refname> 106 + <refname>{manname25}</refname> 107 + <refname>{manname26}</refname> 108 + <refname>{manname27}</refname> 109 + <refname>{manname28}</refname> 110 + <refname>{manname29}</refname> 111 + <refname>{manname30}</refname> 112 + <refpurpose>{manpurpose}</refpurpose> 113 + </refnamediv> 114 + endif::backend-docbook[] 115 + endif::doctype-manpage[] 116 + 117 + ifdef::backend-xhtml11[] 118 + [linktep-inlinemacro] 119 + <a href="{target}.html">{target}{0?({0})}</a> 120 + endif::backend-xhtml11[]
+119
tools/lib/perf/Documentation/examples/sampling.c
··· 1 + #include <linux/perf_event.h> 2 + #include <perf/evlist.h> 3 + #include <perf/evsel.h> 4 + #include <perf/cpumap.h> 5 + #include <perf/threadmap.h> 6 + #include <perf/mmap.h> 7 + #include <perf/core.h> 8 + #include <perf/event.h> 9 + #include <stdio.h> 10 + #include <unistd.h> 11 + 12 + static int libperf_print(enum libperf_print_level level, 13 + const char *fmt, va_list ap) 14 + { 15 + return vfprintf(stderr, fmt, ap); 16 + } 17 + 18 + union u64_swap { 19 + __u64 val64; 20 + __u32 val32[2]; 21 + }; 22 + 23 + int main(int argc, char **argv) 24 + { 25 + struct perf_evlist *evlist; 26 + struct perf_evsel *evsel; 27 + struct perf_mmap *map; 28 + struct perf_cpu_map *cpus; 29 + struct perf_event_attr attr = { 30 + .type = PERF_TYPE_HARDWARE, 31 + .config = PERF_COUNT_HW_CPU_CYCLES, 32 + .disabled = 1, 33 + .freq = 1, 34 + .sample_freq = 10, 35 + .sample_type = PERF_SAMPLE_IP|PERF_SAMPLE_TID|PERF_SAMPLE_CPU|PERF_SAMPLE_PERIOD, 36 + }; 37 + int err = -1; 38 + union perf_event *event; 39 + 40 + libperf_init(libperf_print); 41 + 42 + cpus = perf_cpu_map__new(NULL); 43 + if (!cpus) { 44 + fprintf(stderr, "failed to create cpus\n"); 45 + return -1; 46 + } 47 + 48 + evlist = perf_evlist__new(); 49 + if (!evlist) { 50 + fprintf(stderr, "failed to create evlist\n"); 51 + goto out_cpus; 52 + } 53 + 54 + evsel = perf_evsel__new(&attr); 55 + if (!evsel) { 56 + fprintf(stderr, "failed to create cycles\n"); 57 + goto out_cpus; 58 + } 59 + 60 + perf_evlist__add(evlist, evsel); 61 + 62 + perf_evlist__set_maps(evlist, cpus, NULL); 63 + 64 + err = perf_evlist__open(evlist); 65 + if (err) { 66 + fprintf(stderr, "failed to open evlist\n"); 67 + goto out_evlist; 68 + } 69 + 70 + err = perf_evlist__mmap(evlist, 4); 71 + if (err) { 72 + fprintf(stderr, "failed to mmap evlist\n"); 73 + goto out_evlist; 74 + } 75 + 76 + perf_evlist__enable(evlist); 77 + sleep(3); 78 + perf_evlist__disable(evlist); 79 + 80 + perf_evlist__for_each_mmap(evlist, map, false) { 81 + if (perf_mmap__read_init(map) < 0) 82 + continue; 83 + 84 + while ((event = perf_mmap__read_event(map)) != NULL) { 85 + int cpu, pid, tid; 86 + __u64 ip, period, *array; 87 + union u64_swap u; 88 + 89 + array = event->sample.array; 90 + 91 + ip = *array; 92 + array++; 93 + 94 + u.val64 = *array; 95 + pid = u.val32[0]; 96 + tid = u.val32[1]; 97 + array++; 98 + 99 + u.val64 = *array; 100 + cpu = u.val32[0]; 101 + array++; 102 + 103 + period = *array; 104 + 105 + fprintf(stdout, "cpu %3d, pid %6d, tid %6d, ip %20llx, period %20llu\n", 106 + cpu, pid, tid, ip, period); 107 + 108 + perf_mmap__consume(map); 109 + } 110 + 111 + perf_mmap__read_done(map); 112 + } 113 + 114 + out_evlist: 115 + perf_evlist__delete(evlist); 116 + out_cpus: 117 + perf_cpu_map__put(cpus); 118 + return err; 119 + }
+211
tools/lib/perf/Documentation/libperf-counting.txt
··· 1 + libperf-counting(7) 2 + =================== 3 + 4 + NAME 5 + ---- 6 + libperf-counting - counting interface 7 + 8 + DESCRIPTION 9 + ----------- 10 + The counting interface provides API to meassure and get count for specific perf events. 11 + 12 + The following test tries to explain count on `counting.c` example. 13 + 14 + It is by no means complete guide to counting, but shows libperf basic API for counting. 15 + 16 + The `counting.c` comes with libbperf package and can be compiled and run like: 17 + 18 + [source,bash] 19 + -- 20 + $ gcc -o counting counting.c -lperf 21 + $ sudo ./counting 22 + count 176792, enabled 176944, run 176944 23 + count 176242, enabled 176242, run 176242 24 + -- 25 + 26 + It requires root access, because of the `PERF_COUNT_SW_CPU_CLOCK` event, 27 + which is available only for root. 28 + 29 + The `counting.c` example monitors two events on the current process and displays their count, in a nutshel it: 30 + 31 + * creates events 32 + * adds them to the event list 33 + * opens and enables events through the event list 34 + * does some workload 35 + * disables events 36 + * reads and displays event counts 37 + * destroys the event list 38 + 39 + The first thing you need to do before using libperf is to call init function: 40 + 41 + [source,c] 42 + -- 43 + 8 static int libperf_print(enum libperf_print_level level, 44 + 9 const char *fmt, va_list ap) 45 + 10 { 46 + 11 return vfprintf(stderr, fmt, ap); 47 + 12 } 48 + 49 + 14 int main(int argc, char **argv) 50 + 15 { 51 + ... 52 + 35 libperf_init(libperf_print); 53 + -- 54 + 55 + It will setup the library and sets function for debug output from library. 56 + 57 + The `libperf_print` callback will receive any message with its debug level, 58 + defined as: 59 + 60 + [source,c] 61 + -- 62 + enum libperf_print_level { 63 + LIBPERF_ERR, 64 + LIBPERF_WARN, 65 + LIBPERF_INFO, 66 + LIBPERF_DEBUG, 67 + LIBPERF_DEBUG2, 68 + LIBPERF_DEBUG3, 69 + }; 70 + -- 71 + 72 + Once the setup is complete we start by defining specific events using the `struct perf_event_attr`. 73 + 74 + We create software events for cpu and task: 75 + 76 + [source,c] 77 + -- 78 + 20 struct perf_event_attr attr1 = { 79 + 21 .type = PERF_TYPE_SOFTWARE, 80 + 22 .config = PERF_COUNT_SW_CPU_CLOCK, 81 + 23 .read_format = PERF_FORMAT_TOTAL_TIME_ENABLED|PERF_FORMAT_TOTAL_TIME_RUNNING, 82 + 24 .disabled = 1, 83 + 25 }; 84 + 26 struct perf_event_attr attr2 = { 85 + 27 .type = PERF_TYPE_SOFTWARE, 86 + 28 .config = PERF_COUNT_SW_TASK_CLOCK, 87 + 29 .read_format = PERF_FORMAT_TOTAL_TIME_ENABLED|PERF_FORMAT_TOTAL_TIME_RUNNING, 88 + 30 .disabled = 1, 89 + 31 }; 90 + -- 91 + 92 + The `read_format` setup tells perf to include timing details together with each count. 93 + 94 + Next step is to prepare threads map. 95 + 96 + In this case we will monitor current process, so we create threads map with single pid (0): 97 + 98 + [source,c] 99 + -- 100 + 37 threads = perf_thread_map__new_dummy(); 101 + 38 if (!threads) { 102 + 39 fprintf(stderr, "failed to create threads\n"); 103 + 40 return -1; 104 + 41 } 105 + 42 106 + 43 perf_thread_map__set_pid(threads, 0, 0); 107 + -- 108 + 109 + Now we create libperf's event list, which will serve as holder for the events we want: 110 + 111 + [source,c] 112 + -- 113 + 45 evlist = perf_evlist__new(); 114 + 46 if (!evlist) { 115 + 47 fprintf(stderr, "failed to create evlist\n"); 116 + 48 goto out_threads; 117 + 49 } 118 + -- 119 + 120 + We create libperf's events for the attributes we defined earlier and add them to the list: 121 + 122 + [source,c] 123 + -- 124 + 51 evsel = perf_evsel__new(&attr1); 125 + 52 if (!evsel) { 126 + 53 fprintf(stderr, "failed to create evsel1\n"); 127 + 54 goto out_evlist; 128 + 55 } 129 + 56 130 + 57 perf_evlist__add(evlist, evsel); 131 + 58 132 + 59 evsel = perf_evsel__new(&attr2); 133 + 60 if (!evsel) { 134 + 61 fprintf(stderr, "failed to create evsel2\n"); 135 + 62 goto out_evlist; 136 + 63 } 137 + 64 138 + 65 perf_evlist__add(evlist, evsel); 139 + -- 140 + 141 + Configure event list with the thread map and open events: 142 + 143 + [source,c] 144 + -- 145 + 67 perf_evlist__set_maps(evlist, NULL, threads); 146 + 68 147 + 69 err = perf_evlist__open(evlist); 148 + 70 if (err) { 149 + 71 fprintf(stderr, "failed to open evsel\n"); 150 + 72 goto out_evlist; 151 + 73 } 152 + -- 153 + 154 + Both events are created as disabled (note the `disabled = 1` assignment above), 155 + so we need to enable the whole list explicitely (both events). 156 + 157 + From this moment events are counting and we can do our workload. 158 + 159 + When we are done we disable the events list. 160 + 161 + [source,c] 162 + -- 163 + 75 perf_evlist__enable(evlist); 164 + 76 165 + 77 while (count--); 166 + 78 167 + 79 perf_evlist__disable(evlist); 168 + -- 169 + 170 + Now we need to get the counts from events, following code iterates throught the events list and read counts: 171 + 172 + [source,c] 173 + -- 174 + 81 perf_evlist__for_each_evsel(evlist, evsel) { 175 + 82 perf_evsel__read(evsel, 0, 0, &counts); 176 + 83 fprintf(stdout, "count %llu, enabled %llu, run %llu\n", 177 + 84 counts.val, counts.ena, counts.run); 178 + 85 } 179 + -- 180 + 181 + And finaly cleanup. 182 + 183 + We close the whole events list (both events) and remove it together with the threads map: 184 + 185 + [source,c] 186 + -- 187 + 87 perf_evlist__close(evlist); 188 + 88 189 + 89 out_evlist: 190 + 90 perf_evlist__delete(evlist); 191 + 91 out_threads: 192 + 92 perf_thread_map__put(threads); 193 + 93 return err; 194 + 94 } 195 + -- 196 + 197 + REPORTING BUGS 198 + -------------- 199 + Report bugs to <linux-perf-users@vger.kernel.org>. 200 + 201 + LICENSE 202 + ------- 203 + libperf is Free Software licensed under the GNU LGPL 2.1 204 + 205 + RESOURCES 206 + --------- 207 + https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 208 + 209 + SEE ALSO 210 + -------- 211 + libperf(3), libperf-sampling(7)
+243
tools/lib/perf/Documentation/libperf-sampling.txt
··· 1 + libperf-sampling(7) 2 + =================== 3 + 4 + NAME 5 + ---- 6 + libperf-sampling - sampling interface 7 + 8 + 9 + DESCRIPTION 10 + ----------- 11 + The sampling interface provides API to meassure and get count for specific perf events. 12 + 13 + The following test tries to explain count on `sampling.c` example. 14 + 15 + It is by no means complete guide to sampling, but shows libperf basic API for sampling. 16 + 17 + The `sampling.c` comes with libbperf package and can be compiled and run like: 18 + 19 + [source,bash] 20 + -- 21 + $ gcc -o sampling sampling.c -lperf 22 + $ sudo ./sampling 23 + cpu 0, pid 0, tid 0, ip ffffffffad06c4e6, period 1 24 + cpu 0, pid 4465, tid 4469, ip ffffffffad118748, period 18322959 25 + cpu 0, pid 0, tid 0, ip ffffffffad115722, period 33544846 26 + cpu 0, pid 4465, tid 4470, ip 7f84fe0cdad6, period 23687474 27 + cpu 0, pid 0, tid 0, ip ffffffffad9e0349, period 34255790 28 + cpu 0, pid 4465, tid 4469, ip ffffffffad136581, period 38664069 29 + cpu 0, pid 0, tid 0, ip ffffffffad9e55e2, period 21922384 30 + cpu 0, pid 4465, tid 4470, ip 7f84fe0ebebf, period 17655175 31 + ... 32 + -- 33 + 34 + It requires root access, because it uses hardware cycles event. 35 + 36 + The `sampling.c` example profiles/samples all CPUs with hardware cycles, in a nutshel it: 37 + 38 + - creates events 39 + - adds them to the event list 40 + - opens and enables events through the event list 41 + - sleeps for 3 seconds 42 + - disables events 43 + - reads and displays recorded samples 44 + - destroys the event list 45 + 46 + The first thing you need to do before using libperf is to call init function: 47 + 48 + [source,c] 49 + -- 50 + 12 static int libperf_print(enum libperf_print_level level, 51 + 13 const char *fmt, va_list ap) 52 + 14 { 53 + 15 return vfprintf(stderr, fmt, ap); 54 + 16 } 55 + 56 + 23 int main(int argc, char **argv) 57 + 24 { 58 + ... 59 + 40 libperf_init(libperf_print); 60 + -- 61 + 62 + It will setup the library and sets function for debug output from library. 63 + 64 + The `libperf_print` callback will receive any message with its debug level, 65 + defined as: 66 + 67 + [source,c] 68 + -- 69 + enum libperf_print_level { 70 + LIBPERF_ERR, 71 + LIBPERF_WARN, 72 + LIBPERF_INFO, 73 + LIBPERF_DEBUG, 74 + LIBPERF_DEBUG2, 75 + LIBPERF_DEBUG3, 76 + }; 77 + -- 78 + 79 + Once the setup is complete we start by defining cycles event using the `struct perf_event_attr`: 80 + 81 + [source,c] 82 + -- 83 + 29 struct perf_event_attr attr = { 84 + 30 .type = PERF_TYPE_HARDWARE, 85 + 31 .config = PERF_COUNT_HW_CPU_CYCLES, 86 + 32 .disabled = 1, 87 + 33 .freq = 1, 88 + 34 .sample_freq = 10, 89 + 35 .sample_type = PERF_SAMPLE_IP|PERF_SAMPLE_TID|PERF_SAMPLE_CPU|PERF_SAMPLE_PERIOD, 90 + 36 }; 91 + -- 92 + 93 + Next step is to prepare cpus map. 94 + 95 + In this case we will monitor all the available CPUs: 96 + 97 + [source,c] 98 + -- 99 + 42 cpus = perf_cpu_map__new(NULL); 100 + 43 if (!cpus) { 101 + 44 fprintf(stderr, "failed to create cpus\n"); 102 + 45 return -1; 103 + 46 } 104 + -- 105 + 106 + Now we create libperf's event list, which will serve as holder for the cycles event: 107 + 108 + [source,c] 109 + -- 110 + 48 evlist = perf_evlist__new(); 111 + 49 if (!evlist) { 112 + 50 fprintf(stderr, "failed to create evlist\n"); 113 + 51 goto out_cpus; 114 + 52 } 115 + -- 116 + 117 + We create libperf's event for the cycles attribute we defined earlier and add it to the list: 118 + 119 + [source,c] 120 + -- 121 + 54 evsel = perf_evsel__new(&attr); 122 + 55 if (!evsel) { 123 + 56 fprintf(stderr, "failed to create cycles\n"); 124 + 57 goto out_cpus; 125 + 58 } 126 + 59 127 + 60 perf_evlist__add(evlist, evsel); 128 + -- 129 + 130 + Configure event list with the cpus map and open event: 131 + 132 + [source,c] 133 + -- 134 + 62 perf_evlist__set_maps(evlist, cpus, NULL); 135 + 63 136 + 64 err = perf_evlist__open(evlist); 137 + 65 if (err) { 138 + 66 fprintf(stderr, "failed to open evlist\n"); 139 + 67 goto out_evlist; 140 + 68 } 141 + -- 142 + 143 + Once the events list is open, we can create memory maps AKA perf ring buffers: 144 + 145 + [source,c] 146 + -- 147 + 70 err = perf_evlist__mmap(evlist, 4); 148 + 71 if (err) { 149 + 72 fprintf(stderr, "failed to mmap evlist\n"); 150 + 73 goto out_evlist; 151 + 74 } 152 + -- 153 + 154 + The event is created as disabled (note the `disabled = 1` assignment above), 155 + so we need to enable the events list explicitely. 156 + 157 + From this moment the cycles event is sampling. 158 + 159 + We will sleep for 3 seconds while the ring buffers get data from all CPUs, then we disable the events list. 160 + 161 + [source,c] 162 + -- 163 + 76 perf_evlist__enable(evlist); 164 + 77 sleep(3); 165 + 78 perf_evlist__disable(evlist); 166 + -- 167 + 168 + Following code walks through the ring buffers and reads stored events/samples: 169 + 170 + [source,c] 171 + -- 172 + 80 perf_evlist__for_each_mmap(evlist, map, false) { 173 + 81 if (perf_mmap__read_init(map) < 0) 174 + 82 continue; 175 + 83 176 + 84 while ((event = perf_mmap__read_event(map)) != NULL) { 177 + 178 + /* process event */ 179 + 180 + 108 perf_mmap__consume(map); 181 + 109 } 182 + 110 perf_mmap__read_done(map); 183 + 111 } 184 + 185 + -- 186 + 187 + Each sample needs to get parsed: 188 + 189 + [source,c] 190 + -- 191 + 85 int cpu, pid, tid; 192 + 86 __u64 ip, period, *array; 193 + 87 union u64_swap u; 194 + 88 195 + 89 array = event->sample.array; 196 + 90 197 + 91 ip = *array; 198 + 92 array++; 199 + 93 200 + 94 u.val64 = *array; 201 + 95 pid = u.val32[0]; 202 + 96 tid = u.val32[1]; 203 + 97 array++; 204 + 98 205 + 99 u.val64 = *array; 206 + 100 cpu = u.val32[0]; 207 + 101 array++; 208 + 102 209 + 103 period = *array; 210 + 104 211 + 105 fprintf(stdout, "cpu %3d, pid %6d, tid %6d, ip %20llx, period %20llu\n", 212 + 106 cpu, pid, tid, ip, period); 213 + -- 214 + 215 + And finaly cleanup. 216 + 217 + We close the whole events list (both events) and remove it together with the threads map: 218 + 219 + [source,c] 220 + -- 221 + 113 out_evlist: 222 + 114 perf_evlist__delete(evlist); 223 + 115 out_cpus: 224 + 116 perf_cpu_map__put(cpus); 225 + 117 return err; 226 + 118 } 227 + -- 228 + 229 + REPORTING BUGS 230 + -------------- 231 + Report bugs to <linux-perf-users@vger.kernel.org>. 232 + 233 + LICENSE 234 + ------- 235 + libperf is Free Software licensed under the GNU LGPL 2.1 236 + 237 + RESOURCES 238 + --------- 239 + https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 240 + 241 + SEE ALSO 242 + -------- 243 + libperf(3), libperf-counting(7)
+246
tools/lib/perf/Documentation/libperf.txt
··· 1 + libperf(3) 2 + ========== 3 + 4 + NAME 5 + ---- 6 + libperf - Linux kernel perf event library 7 + 8 + 9 + SYNOPSIS 10 + -------- 11 + *Generic API:* 12 + 13 + [source,c] 14 + -- 15 + #include <perf/core.h> 16 + 17 + enum libperf_print_level { 18 + LIBPERF_ERR, 19 + LIBPERF_WARN, 20 + LIBPERF_INFO, 21 + LIBPERF_DEBUG, 22 + LIBPERF_DEBUG2, 23 + LIBPERF_DEBUG3, 24 + }; 25 + 26 + typedef int (*libperf_print_fn_t)(enum libperf_print_level level, 27 + const char *, va_list ap); 28 + 29 + void libperf_init(libperf_print_fn_t fn); 30 + -- 31 + 32 + *API to handle cpu maps:* 33 + 34 + [source,c] 35 + -- 36 + #include <perf/cpumap.h> 37 + 38 + struct perf_cpu_map; 39 + 40 + struct perf_cpu_map *perf_cpu_map__dummy_new(void); 41 + struct perf_cpu_map *perf_cpu_map__new(const char *cpu_list); 42 + struct perf_cpu_map *perf_cpu_map__read(FILE *file); 43 + struct perf_cpu_map *perf_cpu_map__get(struct perf_cpu_map *map); 44 + struct perf_cpu_map *perf_cpu_map__merge(struct perf_cpu_map *orig, 45 + struct perf_cpu_map *other); 46 + void perf_cpu_map__put(struct perf_cpu_map *map); 47 + int perf_cpu_map__cpu(const struct perf_cpu_map *cpus, int idx); 48 + int perf_cpu_map__nr(const struct perf_cpu_map *cpus); 49 + bool perf_cpu_map__empty(const struct perf_cpu_map *map); 50 + int perf_cpu_map__max(struct perf_cpu_map *map); 51 + 52 + #define perf_cpu_map__for_each_cpu(cpu, idx, cpus) 53 + -- 54 + 55 + *API to handle thread maps:* 56 + 57 + [source,c] 58 + -- 59 + #include <perf/threadmap.h> 60 + 61 + struct perf_thread_map; 62 + 63 + struct perf_thread_map *perf_thread_map__new_dummy(void); 64 + 65 + void perf_thread_map__set_pid(struct perf_thread_map *map, int thread, pid_t pid); 66 + char *perf_thread_map__comm(struct perf_thread_map *map, int thread); 67 + int perf_thread_map__nr(struct perf_thread_map *threads); 68 + pid_t perf_thread_map__pid(struct perf_thread_map *map, int thread); 69 + 70 + struct perf_thread_map *perf_thread_map__get(struct perf_thread_map *map); 71 + void perf_thread_map__put(struct perf_thread_map *map); 72 + -- 73 + 74 + *API to handle event lists:* 75 + 76 + [source,c] 77 + -- 78 + #include <perf/evlist.h> 79 + 80 + struct perf_evlist; 81 + 82 + void perf_evlist__add(struct perf_evlist *evlist, 83 + struct perf_evsel *evsel); 84 + void perf_evlist__remove(struct perf_evlist *evlist, 85 + struct perf_evsel *evsel); 86 + struct perf_evlist *perf_evlist__new(void); 87 + void perf_evlist__delete(struct perf_evlist *evlist); 88 + struct perf_evsel* perf_evlist__next(struct perf_evlist *evlist, 89 + struct perf_evsel *evsel); 90 + int perf_evlist__open(struct perf_evlist *evlist); 91 + void perf_evlist__close(struct perf_evlist *evlist); 92 + void perf_evlist__enable(struct perf_evlist *evlist); 93 + void perf_evlist__disable(struct perf_evlist *evlist); 94 + 95 + #define perf_evlist__for_each_evsel(evlist, pos) 96 + 97 + void perf_evlist__set_maps(struct perf_evlist *evlist, 98 + struct perf_cpu_map *cpus, 99 + struct perf_thread_map *threads); 100 + int perf_evlist__poll(struct perf_evlist *evlist, int timeout); 101 + int perf_evlist__filter_pollfd(struct perf_evlist *evlist, 102 + short revents_and_mask); 103 + 104 + int perf_evlist__mmap(struct perf_evlist *evlist, int pages); 105 + void perf_evlist__munmap(struct perf_evlist *evlist); 106 + 107 + struct perf_mmap *perf_evlist__next_mmap(struct perf_evlist *evlist, 108 + struct perf_mmap *map, 109 + bool overwrite); 110 + 111 + #define perf_evlist__for_each_mmap(evlist, pos, overwrite) 112 + -- 113 + 114 + *API to handle events:* 115 + 116 + [source,c] 117 + -- 118 + #include <perf/evsel.h>* 119 + 120 + struct perf_evsel; 121 + 122 + struct perf_counts_values { 123 + union { 124 + struct { 125 + uint64_t val; 126 + uint64_t ena; 127 + uint64_t run; 128 + }; 129 + uint64_t values[3]; 130 + }; 131 + }; 132 + 133 + struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr); 134 + void perf_evsel__delete(struct perf_evsel *evsel); 135 + int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus, 136 + struct perf_thread_map *threads); 137 + void perf_evsel__close(struct perf_evsel *evsel); 138 + void perf_evsel__close_cpu(struct perf_evsel *evsel, int cpu); 139 + int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread, 140 + struct perf_counts_values *count); 141 + int perf_evsel__enable(struct perf_evsel *evsel); 142 + int perf_evsel__enable_cpu(struct perf_evsel *evsel, int cpu); 143 + int perf_evsel__disable(struct perf_evsel *evsel); 144 + int perf_evsel__disable_cpu(struct perf_evsel *evsel, int cpu); 145 + struct perf_cpu_map *perf_evsel__cpus(struct perf_evsel *evsel); 146 + struct perf_thread_map *perf_evsel__threads(struct perf_evsel *evsel); 147 + struct perf_event_attr *perf_evsel__attr(struct perf_evsel *evsel); 148 + -- 149 + 150 + *API to handle maps (perf ring buffers):* 151 + 152 + [source,c] 153 + -- 154 + #include <perf/mmap.h> 155 + 156 + struct perf_mmap; 157 + 158 + void perf_mmap__consume(struct perf_mmap *map); 159 + int perf_mmap__read_init(struct perf_mmap *map); 160 + void perf_mmap__read_done(struct perf_mmap *map); 161 + union perf_event *perf_mmap__read_event(struct perf_mmap *map); 162 + -- 163 + 164 + *Structures to access perf API events:* 165 + 166 + [source,c] 167 + -- 168 + #include <perf/event.h> 169 + 170 + struct perf_record_mmap; 171 + struct perf_record_mmap2; 172 + struct perf_record_comm; 173 + struct perf_record_namespaces; 174 + struct perf_record_fork; 175 + struct perf_record_lost; 176 + struct perf_record_lost_samples; 177 + struct perf_record_read; 178 + struct perf_record_throttle; 179 + struct perf_record_ksymbol; 180 + struct perf_record_bpf_event; 181 + struct perf_record_sample; 182 + struct perf_record_switch; 183 + struct perf_record_header_attr; 184 + struct perf_record_record_cpu_map; 185 + struct perf_record_cpu_map_data; 186 + struct perf_record_cpu_map; 187 + struct perf_record_event_update_cpus; 188 + struct perf_record_event_update_scale; 189 + struct perf_record_event_update; 190 + struct perf_trace_event_type; 191 + struct perf_record_header_event_type; 192 + struct perf_record_header_tracing_data; 193 + struct perf_record_header_build_id; 194 + struct perf_record_id_index; 195 + struct perf_record_auxtrace_info; 196 + struct perf_record_auxtrace; 197 + struct perf_record_auxtrace_error; 198 + struct perf_record_aux; 199 + struct perf_record_itrace_start; 200 + struct perf_record_thread_map_entry; 201 + struct perf_record_thread_map; 202 + struct perf_record_stat_config_entry; 203 + struct perf_record_stat_config; 204 + struct perf_record_stat; 205 + struct perf_record_stat_round; 206 + struct perf_record_time_conv; 207 + struct perf_record_header_feature; 208 + struct perf_record_compressed; 209 + -- 210 + 211 + DESCRIPTION 212 + ----------- 213 + The libperf library provides an API to access the linux kernel perf 214 + events subsystem. 215 + 216 + Following objects are key to the libperf interface: 217 + 218 + [horizontal] 219 + 220 + struct perf_cpu_map:: Provides a cpu list abstraction. 221 + 222 + struct perf_thread_map:: Provides a thread list abstraction. 223 + 224 + struct perf_evsel:: Provides an abstraction for single a perf event. 225 + 226 + struct perf_evlist:: Gathers several struct perf_evsel object and performs functions on all of them. 227 + 228 + struct perf_mmap:: Provides an abstraction for accessing perf ring buffer. 229 + 230 + The exported API functions bind these objects together. 231 + 232 + REPORTING BUGS 233 + -------------- 234 + Report bugs to <linux-perf-users@vger.kernel.org>. 235 + 236 + LICENSE 237 + ------- 238 + libperf is Free Software licensed under the GNU LGPL 2.1 239 + 240 + RESOURCES 241 + --------- 242 + https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 243 + 244 + SEE ALSO 245 + -------- 246 + libperf-sampling(7), libperf-counting(7)
-100
tools/lib/perf/Documentation/man/libperf.rst
··· 1 - .. SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) 2 - 3 - libperf 4 - 5 - The libperf library provides an API to access the linux kernel perf 6 - events subsystem. It provides the following high level objects: 7 - 8 - - struct perf_cpu_map 9 - - struct perf_thread_map 10 - - struct perf_evlist 11 - - struct perf_evsel 12 - 13 - reference 14 - ========= 15 - Function reference by header files: 16 - 17 - perf/core.h 18 - ----------- 19 - .. code-block:: c 20 - 21 - typedef int (\*libperf_print_fn_t)(enum libperf_print_level level, 22 - const char \*, va_list ap); 23 - 24 - void libperf_set_print(libperf_print_fn_t fn); 25 - 26 - perf/cpumap.h 27 - ------------- 28 - .. code-block:: c 29 - 30 - struct perf_cpu_map \*perf_cpu_map__dummy_new(void); 31 - struct perf_cpu_map \*perf_cpu_map__new(const char \*cpu_list); 32 - struct perf_cpu_map \*perf_cpu_map__read(FILE \*file); 33 - struct perf_cpu_map \*perf_cpu_map__get(struct perf_cpu_map \*map); 34 - void perf_cpu_map__put(struct perf_cpu_map \*map); 35 - int perf_cpu_map__cpu(const struct perf_cpu_map \*cpus, int idx); 36 - int perf_cpu_map__nr(const struct perf_cpu_map \*cpus); 37 - perf_cpu_map__for_each_cpu(cpu, idx, cpus) 38 - 39 - perf/threadmap.h 40 - ---------------- 41 - .. code-block:: c 42 - 43 - struct perf_thread_map \*perf_thread_map__new_dummy(void); 44 - void perf_thread_map__set_pid(struct perf_thread_map \*map, int thread, pid_t pid); 45 - char \*perf_thread_map__comm(struct perf_thread_map \*map, int thread); 46 - struct perf_thread_map \*perf_thread_map__get(struct perf_thread_map \*map); 47 - void perf_thread_map__put(struct perf_thread_map \*map); 48 - 49 - perf/evlist.h 50 - ------------- 51 - .. code-block:: 52 - 53 - void perf_evlist__init(struct perf_evlist \*evlist); 54 - void perf_evlist__add(struct perf_evlist \*evlist, 55 - struct perf_evsel \*evsel); 56 - void perf_evlist__remove(struct perf_evlist \*evlist, 57 - struct perf_evsel \*evsel); 58 - struct perf_evlist \*perf_evlist__new(void); 59 - void perf_evlist__delete(struct perf_evlist \*evlist); 60 - struct perf_evsel\* perf_evlist__next(struct perf_evlist \*evlist, 61 - struct perf_evsel \*evsel); 62 - int perf_evlist__open(struct perf_evlist \*evlist); 63 - void perf_evlist__close(struct perf_evlist \*evlist); 64 - void perf_evlist__enable(struct perf_evlist \*evlist); 65 - void perf_evlist__disable(struct perf_evlist \*evlist); 66 - perf_evlist__for_each_evsel(evlist, pos) 67 - void perf_evlist__set_maps(struct perf_evlist \*evlist, 68 - struct perf_cpu_map \*cpus, 69 - struct perf_thread_map \*threads); 70 - 71 - perf/evsel.h 72 - ------------ 73 - .. code-block:: c 74 - 75 - struct perf_counts_values { 76 - union { 77 - struct { 78 - uint64_t val; 79 - uint64_t ena; 80 - uint64_t run; 81 - }; 82 - uint64_t values[3]; 83 - }; 84 - }; 85 - 86 - void perf_evsel__init(struct perf_evsel \*evsel, 87 - struct perf_event_attr \*attr); 88 - struct perf_evsel \*perf_evsel__new(struct perf_event_attr \*attr); 89 - void perf_evsel__delete(struct perf_evsel \*evsel); 90 - int perf_evsel__open(struct perf_evsel \*evsel, struct perf_cpu_map \*cpus, 91 - struct perf_thread_map \*threads); 92 - void perf_evsel__close(struct perf_evsel \*evsel); 93 - int perf_evsel__read(struct perf_evsel \*evsel, int cpu, int thread, 94 - struct perf_counts_values \*count); 95 - int perf_evsel__enable(struct perf_evsel \*evsel); 96 - int perf_evsel__disable(struct perf_evsel \*evsel); 97 - int perf_evsel__apply_filter(struct perf_evsel \*evsel, const char \*filter); 98 - struct perf_cpu_map \*perf_evsel__cpus(struct perf_evsel \*evsel); 99 - struct perf_thread_map \*perf_evsel__threads(struct perf_evsel \*evsel); 100 - struct perf_event_attr \*perf_evsel__attr(struct perf_evsel \*evsel);
+14
tools/lib/perf/Documentation/manpage-1.72.xsl
··· 1 + <!-- manpage-1.72.xsl: 2 + special settings for manpages rendered from asciidoc+docbook 3 + handles peculiarities in docbook-xsl 1.72.0 --> 4 + <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 5 + version="1.0"> 6 + 7 + <xsl:import href="manpage-base.xsl"/> 8 + 9 + <!-- these are the special values for the roff control characters 10 + needed for docbook-xsl 1.72.0 --> 11 + <xsl:param name="git.docbook.backslash">&#x2593;</xsl:param> 12 + <xsl:param name="git.docbook.dot" >&#x2302;</xsl:param> 13 + 14 + </xsl:stylesheet>
+35
tools/lib/perf/Documentation/manpage-base.xsl
··· 1 + <!-- manpage-base.xsl: 2 + special formatting for manpages rendered from asciidoc+docbook --> 3 + <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 4 + version="1.0"> 5 + 6 + <!-- these params silence some output from xmlto --> 7 + <xsl:param name="man.output.quietly" select="1"/> 8 + <xsl:param name="refentry.meta.get.quietly" select="1"/> 9 + 10 + <!-- convert asciidoc callouts to man page format; 11 + git.docbook.backslash and git.docbook.dot params 12 + must be supplied by another XSL file or other means --> 13 + <xsl:template match="co"> 14 + <xsl:value-of select="concat( 15 + $git.docbook.backslash,'fB(', 16 + substring-after(@id,'-'),')', 17 + $git.docbook.backslash,'fR')"/> 18 + </xsl:template> 19 + <xsl:template match="calloutlist"> 20 + <xsl:value-of select="$git.docbook.dot"/> 21 + <xsl:text>sp&#10;</xsl:text> 22 + <xsl:apply-templates/> 23 + <xsl:text>&#10;</xsl:text> 24 + </xsl:template> 25 + <xsl:template match="callout"> 26 + <xsl:value-of select="concat( 27 + $git.docbook.backslash,'fB', 28 + substring-after(@arearefs,'-'), 29 + '. ',$git.docbook.backslash,'fR')"/> 30 + <xsl:apply-templates/> 31 + <xsl:value-of select="$git.docbook.dot"/> 32 + <xsl:text>br&#10;</xsl:text> 33 + </xsl:template> 34 + 35 + </xsl:stylesheet>
+17
tools/lib/perf/Documentation/manpage-bold-literal.xsl
··· 1 + <!-- manpage-bold-literal.xsl: 2 + special formatting for manpages rendered from asciidoc+docbook --> 3 + <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 4 + version="1.0"> 5 + 6 + <!-- render literal text as bold (instead of plain or monospace); 7 + this makes literal text easier to distinguish in manpages 8 + viewed on a tty --> 9 + <xsl:template match="literal"> 10 + <xsl:value-of select="$git.docbook.backslash"/> 11 + <xsl:text>fB</xsl:text> 12 + <xsl:apply-templates/> 13 + <xsl:value-of select="$git.docbook.backslash"/> 14 + <xsl:text>fR</xsl:text> 15 + </xsl:template> 16 + 17 + </xsl:stylesheet>
+13
tools/lib/perf/Documentation/manpage-normal.xsl
··· 1 + <!-- manpage-normal.xsl: 2 + special settings for manpages rendered from asciidoc+docbook 3 + handles anything we want to keep away from docbook-xsl 1.72.0 --> 4 + <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 5 + version="1.0"> 6 + 7 + <xsl:import href="manpage-base.xsl"/> 8 + 9 + <!-- these are the normal values for the roff control characters --> 10 + <xsl:param name="git.docbook.backslash">\</xsl:param> 11 + <xsl:param name="git.docbook.dot" >.</xsl:param> 12 + 13 + </xsl:stylesheet>
+21
tools/lib/perf/Documentation/manpage-suppress-sp.xsl
··· 1 + <!-- manpage-suppress-sp.xsl: 2 + special settings for manpages rendered from asciidoc+docbook 3 + handles erroneous, inline .sp in manpage output of some 4 + versions of docbook-xsl --> 5 + <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 6 + version="1.0"> 7 + 8 + <!-- attempt to work around spurious .sp at the tail of the line 9 + that some versions of docbook stylesheets seem to add --> 10 + <xsl:template match="simpara"> 11 + <xsl:variable name="content"> 12 + <xsl:apply-templates/> 13 + </xsl:variable> 14 + <xsl:value-of select="normalize-space($content)"/> 15 + <xsl:if test="not(ancestor::authorblurb) and 16 + not(ancestor::personblurb)"> 17 + <xsl:text>&#10;&#10;</xsl:text> 18 + </xsl:if> 19 + </xsl:template> 20 + 21 + </xsl:stylesheet>
-123
tools/lib/perf/Documentation/tutorial/tutorial.rst
··· 1 - .. SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) 2 - 3 - libperf tutorial 4 - ================ 5 - 6 - Compile and install libperf from kernel sources 7 - =============================================== 8 - .. code-block:: bash 9 - 10 - git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 11 - cd linux/tools/perf/lib 12 - make 13 - sudo make install prefix=/usr 14 - 15 - Libperf object 16 - ============== 17 - The libperf library provides several high level objects: 18 - 19 - struct perf_cpu_map 20 - Provides a cpu list abstraction. 21 - 22 - struct perf_thread_map 23 - Provides a thread list abstraction. 24 - 25 - struct perf_evsel 26 - Provides an abstraction for single a perf event. 27 - 28 - struct perf_evlist 29 - Gathers several struct perf_evsel object and performs functions on all of them. 30 - 31 - The exported API binds these objects together, 32 - for full reference see the libperf.7 man page. 33 - 34 - Examples 35 - ======== 36 - Examples aim to explain libperf functionality on simple use cases. 37 - They are based in on a checked out linux kernel git tree: 38 - 39 - .. code-block:: bash 40 - 41 - $ cd tools/perf/lib/Documentation/tutorial/ 42 - $ ls -d ex-* 43 - ex-1-compile ex-2-evsel-stat ex-3-evlist-stat 44 - 45 - ex-1-compile example 46 - ==================== 47 - This example shows the basic usage of *struct perf_cpu_map*, 48 - how to create it and display its cpus: 49 - 50 - .. code-block:: bash 51 - 52 - $ cd ex-1-compile/ 53 - $ make 54 - gcc -o test test.c -lperf 55 - $ ./test 56 - 0 1 2 3 4 5 6 7 57 - 58 - 59 - The full code listing is here: 60 - 61 - .. code-block:: c 62 - 63 - 1 #include <perf/cpumap.h> 64 - 2 65 - 3 int main(int argc, char **Argv) 66 - 4 { 67 - 5 struct perf_cpu_map *cpus; 68 - 6 int cpu, tmp; 69 - 7 70 - 8 cpus = perf_cpu_map__new(NULL); 71 - 9 72 - 10 perf_cpu_map__for_each_cpu(cpu, tmp, cpus) 73 - 11 fprintf(stdout, "%d ", cpu); 74 - 12 75 - 13 fprintf(stdout, "\n"); 76 - 14 77 - 15 perf_cpu_map__put(cpus); 78 - 16 return 0; 79 - 17 } 80 - 81 - 82 - First you need to include the proper header to have *struct perf_cpumap* 83 - declaration and functions: 84 - 85 - .. code-block:: c 86 - 87 - 1 #include <perf/cpumap.h> 88 - 89 - 90 - The *struct perf_cpumap* object is created by *perf_cpu_map__new* call. 91 - The *NULL* argument asks it to populate the object with the current online CPUs list: 92 - 93 - .. code-block:: c 94 - 95 - 8 cpus = perf_cpu_map__new(NULL); 96 - 97 - This is paired with a *perf_cpu_map__put*, that drops its reference at the end, possibly deleting it. 98 - 99 - .. code-block:: c 100 - 101 - 15 perf_cpu_map__put(cpus); 102 - 103 - The iteration through the *struct perf_cpumap* CPUs is done using the *perf_cpu_map__for_each_cpu* 104 - macro which requires 3 arguments: 105 - 106 - - cpu - the cpu numer 107 - - tmp - iteration helper variable 108 - - cpus - the *struct perf_cpumap* object 109 - 110 - .. code-block:: c 111 - 112 - 10 perf_cpu_map__for_each_cpu(cpu, tmp, cpus) 113 - 11 fprintf(stdout, "%d ", cpu); 114 - 115 - ex-2-evsel-stat example 116 - ======================= 117 - 118 - TBD 119 - 120 - ex-3-evlist-stat example 121 - ======================== 122 - 123 - TBD
+4 -1
tools/lib/perf/Makefile
··· 181 181 $(call QUIET_INSTALL, $(LIBPERF_PC)) \ 182 182 $(call do_install,$(LIBPERF_PC),$(libdir_SQ)/pkgconfig,644) 183 183 184 - install: install_lib install_headers install_pkgconfig 184 + install_doc: 185 + $(Q)$(MAKE) -C Documentation install-man install-html install-examples 186 + 187 + install: install_lib install_headers install_pkgconfig install_doc 185 188 186 189 FORCE: 187 190