brintos

brintos / linux-shallow public Read only

0
0
Text · 5.5 KiB · 8b75efc Raw
214 lines · plain
1libperf-counting(7)2===================3 4NAME5----6libperf-counting - counting interface7 8DESCRIPTION9-----------10The counting interface provides API to measure and get count for specific perf events.11 12The following test tries to explain count on `counting.c` example.13 14It is by no means complete guide to counting, but shows libperf basic API for counting.15 16The `counting.c` comes with libperf package and can be compiled and run like:17 18[source,bash]19--20$ gcc -o counting counting.c -lperf21$ sudo ./counting22count 176792, enabled 176944, run 17694423count 176242, enabled 176242, run 17624224--25 26It requires root access, because of the `PERF_COUNT_SW_CPU_CLOCK` event,27which is available only for root.28 29The `counting.c` example monitors two events on the current process and displays30their count, in a nutshell it:31 32* creates events33* adds them to the event list34* opens and enables events through the event list35* does some workload36* disables events37* reads and displays event counts38* destroys the event list39 40The first thing you need to do before using libperf is to call init function:41 42[source,c]43--44  8 static int libperf_print(enum libperf_print_level level,45  9                          const char *fmt, va_list ap)46 10 {47 11         return vfprintf(stderr, fmt, ap);48 12 }49 50 14 int main(int argc, char **argv)51 15 {52 ...53 35         libperf_init(libperf_print);54--55 56It will setup the library and sets function for debug output from library.57 58The `libperf_print` callback will receive any message with its debug level,59defined as:60 61[source,c]62--63enum libperf_print_level {64        LIBPERF_ERR,65        LIBPERF_WARN,66        LIBPERF_INFO,67        LIBPERF_DEBUG,68        LIBPERF_DEBUG2,69        LIBPERF_DEBUG3,70};71--72 73Once the setup is complete we start by defining specific events using the `struct perf_event_attr`.74 75We create software events for cpu and task:76 77[source,c]78--79 20         struct perf_event_attr attr1 = {80 21                 .type        = PERF_TYPE_SOFTWARE,81 22                 .config      = PERF_COUNT_SW_CPU_CLOCK,82 23                 .read_format = PERF_FORMAT_TOTAL_TIME_ENABLED|PERF_FORMAT_TOTAL_TIME_RUNNING,83 24                 .disabled    = 1,84 25         };85 26         struct perf_event_attr attr2 = {86 27                 .type        = PERF_TYPE_SOFTWARE,87 28                 .config      = PERF_COUNT_SW_TASK_CLOCK,88 29                 .read_format = PERF_FORMAT_TOTAL_TIME_ENABLED|PERF_FORMAT_TOTAL_TIME_RUNNING,89 30                 .disabled    = 1,90 31         };91--92 93The `read_format` setup tells perf to include timing details together with each count.94 95Next step is to prepare threads map.96 97In this case we will monitor current process, so we create threads map with single pid (0):98 99[source,c]100--101 37         threads = perf_thread_map__new_dummy();102 38         if (!threads) {103 39                 fprintf(stderr, "failed to create threads\n");104 40                 return -1;105 41         }106 42107 43         perf_thread_map__set_pid(threads, 0, 0);108--109 110Now we create libperf's event list, which will serve as holder for the events we want:111 112[source,c]113--114 45         evlist = perf_evlist__new();115 46         if (!evlist) {116 47                 fprintf(stderr, "failed to create evlist\n");117 48                 goto out_threads;118 49         }119--120 121We create libperf's events for the attributes we defined earlier and add them to the list:122 123[source,c]124--125 51         evsel = perf_evsel__new(&attr1);126 52         if (!evsel) {127 53                 fprintf(stderr, "failed to create evsel1\n");128 54                 goto out_evlist;129 55         }130 56131 57         perf_evlist__add(evlist, evsel);132 58133 59         evsel = perf_evsel__new(&attr2);134 60         if (!evsel) {135 61                 fprintf(stderr, "failed to create evsel2\n");136 62                 goto out_evlist;137 63         }138 64139 65         perf_evlist__add(evlist, evsel);140--141 142Configure event list with the thread map and open events:143 144[source,c]145--146 67         perf_evlist__set_maps(evlist, NULL, threads);147 68148 69         err = perf_evlist__open(evlist);149 70         if (err) {150 71                 fprintf(stderr, "failed to open evsel\n");151 72                 goto out_evlist;152 73         }153--154 155Both events are created as disabled (note the `disabled = 1` assignment above),156so we need to enable the whole list explicitly (both events).157 158From this moment events are counting and we can do our workload.159 160When we are done we disable the events list.161 162[source,c]163--164 75         perf_evlist__enable(evlist);165 76166 77         while (count--);167 78168 79         perf_evlist__disable(evlist);169--170 171Now we need to get the counts from events, following code iterates through the172events list and read counts:173 174[source,c]175--176 81         perf_evlist__for_each_evsel(evlist, evsel) {177 82                 perf_evsel__read(evsel, 0, 0, &counts);178 83                 fprintf(stdout, "count %llu, enabled %llu, run %llu\n",179 84                         counts.val, counts.ena, counts.run);180 85         }181--182 183And finally cleanup.184 185We close the whole events list (both events) and remove it together with the threads map:186 187[source,c]188--189 87         perf_evlist__close(evlist);190 88191 89 out_evlist:192 90         perf_evlist__delete(evlist);193 91 out_threads:194 92         perf_thread_map__put(threads);195 93         return err;196 94 }197--198 199REPORTING BUGS200--------------201Report bugs to <linux-perf-users@vger.kernel.org>.202 203LICENSE204-------205libperf is Free Software licensed under the GNU LGPL 2.1206 207RESOURCES208---------209https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git210 211SEE ALSO212--------213libperf(3), libperf-sampling(7)214