perfmon: add Arm event bundles
[vpp.git] / src / plugins / perfmon / arm / bundle / inst_clock.c
1 /*
2  * Copyright (c) 2022 Arm and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include <vnet/vnet.h>
17 #include <vppinfra/linux/sysfs.h>
18 #include <perfmon/perfmon.h>
19 #include <perfmon/arm/events.h>
20
21 /* as per .events[n] in PERFMON_REGISTER_BUNDLE */
22 enum
23 {
24   CPU_CYCLES,
25   INST_RETIRED
26 };
27
28 static u8 *
29 format_arm_inst_clock (u8 *s, va_list *args)
30 {
31   perfmon_node_stats_t *ns = va_arg (*args, perfmon_node_stats_t *);
32   int row = va_arg (*args, int);
33
34   switch (row)
35     {
36     case 0:
37       s = format (s, "%llu", ns->n_packets);
38       break;
39
40     case 1:
41       s = format (s, "%llu", ns->n_calls);
42       break;
43
44     case 2:
45       s = format (s, "%llu", ns->value[0]); /* Cycles */
46       break;
47
48     case 3:
49       s = format (s, "%llu", ns->value[1]); /* Inst */
50       break;
51
52     case 4:
53       s = format (s, "%.2f",
54                   (f64) ns->n_packets / ns->n_calls); /* Packets/Call */
55       break;
56
57     case 5:
58       s = format (s, "%.2f",
59                   (f64) ns->value[0] / ns->n_packets); /* Clocks/Packet */
60       break;
61
62     case 6:
63       s =
64         format (s, "%.2f",
65                 (f64) ns->value[1] / ns->n_packets); /* Instructions/Packet */
66       break;
67
68     case 7:
69       s = format (s, "%.2f", (f64) ns->value[1] / ns->value[0]); /* IPC */
70       break;
71     }
72   return s;
73 }
74
75 PERFMON_REGISTER_BUNDLE (arm_inst_clock) = {
76   .name = "inst-and-clock",
77   .description =
78     "CPU cycles, instructions, instructions/packet, cycles/packet and IPC",
79   .source = "arm",
80   .type = PERFMON_BUNDLE_TYPE_NODE,
81   .events[0] = ARMV8_PMUV3_CPU_CYCLES,
82   .events[1] = ARMV8_PMUV3_INST_RETIRED,
83   .n_events = 2,
84   .n_columns = 8,
85   .format_fn = format_arm_inst_clock,
86   .column_headers = PERFMON_STRINGS ("Packets", "Calls", "CPU Cycles", "Inst*",
87                                      "Pkts/Call", "Cycles/Pkt", "Inst/Pkt",
88                                      "IPC"),
89   /*
90    * set a bit for every event used in each column
91    * this allows us to disable columns at bundle registration if an
92    * event is not supported
93    */
94   .column_events =
95     PERFMON_COLUMN_EVENTS (0, 0, SET_BIT (CPU_CYCLES), SET_BIT (INST_RETIRED),
96                            0, SET_BIT (CPU_CYCLES), SET_BIT (INST_RETIRED),
97                            SET_BIT (CPU_CYCLES) | SET_BIT (INST_RETIRED)),
98   .footer = "* Instructions retired: the counter increments for every "
99             "architecturally executed instruction\n"
100             "- See Armv8-A Architecture Reference Manual, D7.10 PMU events and"
101             " event numbers for full description.\n"
102 };