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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull perf tooling updates from Thomas Gleixner:
"A set of perf improvements and fixes:

perf db-export:
- Improvements in how COMM details are exported to databases for post
processing and use in the sql-viewer.py UI.

- Export switch events to the database.

BPF:
- Bump rlimit(MEMLOCK) for 'perf test bpf' and 'perf trace', just
like selftests/bpf/bpf_rlimit.h do, which makes errors due to
exhaustion of this limit, which are kinda cryptic (EPERM sometimes)
less frequent.

perf version:
- Fix segfault due to missing OPT_END(), noticed on PowerPC.

perf vendor events:
- Add JSON files for IBM s/390 machine type 8561.

perf cs-etm (ARM):
- Fix two cases of error returns not bing done properly: Invalid
ERR_PTR() use and loss of propagation error codes"

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (28 commits)
perf version: Fix segfault due to missing OPT_END()
perf vendor events s390: Add JSON files for machine type 8561
perf cs-etm: Return errcode in cs_etm__process_auxtrace_info()
perf cs-etm: Remove errnoeous ERR_PTR() usage in cs_etm__process_auxtrace_info
perf scripts python: export-to-postgresql.py: Export switch events
perf scripts python: export-to-sqlite.py: Export switch events
perf db-export: Export switch events
perf db-export: Factor out db_export__threads()
perf script: Add scripting operation process_switch()
perf scripts python: exported-sql-viewer.py: Use new 'has_calls' column
perf scripts python: exported-sql-viewer.py: Remove redundant semi-colons
perf scripts python: export-to-postgresql.py: Add has_calls column to comms table
perf scripts python: export-to-sqlite.py: Add has_calls column to comms table
perf db-export: Also export thread's current comm
perf db-export: Factor out db_export__comm()
perf scripts python: export-to-postgresql.py: Export comm details
perf scripts python: export-to-sqlite.py: Export comm details
perf db-export: Export comm details
perf db-export: Fix a white space issue in db_export__sample()
perf db-export: Move export__comm_thread into db_export__sample()
...

+1029 -142
+7 -1
tools/perf/builtin-script.c
··· 2289 2289 if (perf_event__process_switch(tool, event, sample, machine) < 0) 2290 2290 return -1; 2291 2291 2292 + if (scripting_ops && scripting_ops->process_switch) 2293 + scripting_ops->process_switch(event, sample, machine); 2294 + 2295 + if (!script->show_switch_events) 2296 + return 0; 2297 + 2292 2298 thread = machine__findnew_thread(machine, sample->pid, 2293 2299 sample->tid); 2294 2300 if (thread == NULL) { ··· 2473 2467 script->tool.mmap = process_mmap_event; 2474 2468 script->tool.mmap2 = process_mmap2_event; 2475 2469 } 2476 - if (script->show_switch_events) 2470 + if (script->show_switch_events || (scripting_ops && scripting_ops->process_switch)) 2477 2471 script->tool.context_switch = process_switch_event; 2478 2472 if (script->show_namespace_events) 2479 2473 script->tool.namespaces = process_namespaces_event;
+10
tools/perf/builtin-trace.c
··· 19 19 #include <api/fs/tracing_path.h> 20 20 #include <bpf/bpf.h> 21 21 #include "util/bpf_map.h" 22 + #include "util/rlimit.h" 22 23 #include "builtin.h" 23 24 #include "util/cgroup.h" 24 25 #include "util/color.h" ··· 3864 3863 err = -ENOMEM; 3865 3864 goto out; 3866 3865 } 3866 + 3867 + /* 3868 + * Parsing .perfconfig may entail creating a BPF event, that may need 3869 + * to create BPF maps, so bump RLIM_MEMLOCK as the default 64K setting 3870 + * is too small. This affects just this process, not touching the 3871 + * global setting. If it fails we'll get something in 'perf trace -v' 3872 + * to help diagnose the problem. 3873 + */ 3874 + rlimit__bump_memlock(); 3867 3875 3868 3876 err = perf_config(trace__config, &trace); 3869 3877 if (err)
+1
tools/perf/builtin-version.c
··· 19 19 static struct option version_options[] = { 20 20 OPT_BOOLEAN(0, "build-options", &version.build_options, 21 21 "display the build options"), 22 + OPT_END(), 22 23 }; 23 24 24 25 static const char * const version_usage[] = {
+58
tools/perf/pmu-events/arch/s390/cf_m8561/basic.json
··· 1 + [ 2 + { 3 + "Unit": "CPU-M-CF", 4 + "EventCode": "0", 5 + "EventName": "CPU_CYCLES", 6 + "BriefDescription": "CPU Cycles", 7 + "PublicDescription": "Cycle Count" 8 + }, 9 + { 10 + "Unit": "CPU-M-CF", 11 + "EventCode": "1", 12 + "EventName": "INSTRUCTIONS", 13 + "BriefDescription": "Instructions", 14 + "PublicDescription": "Instruction Count" 15 + }, 16 + { 17 + "Unit": "CPU-M-CF", 18 + "EventCode": "2", 19 + "EventName": "L1I_DIR_WRITES", 20 + "BriefDescription": "L1I Directory Writes", 21 + "PublicDescription": "Level-1 I-Cache Directory Write Count" 22 + }, 23 + { 24 + "Unit": "CPU-M-CF", 25 + "EventCode": "3", 26 + "EventName": "L1I_PENALTY_CYCLES", 27 + "BriefDescription": "L1I Penalty Cycles", 28 + "PublicDescription": "Level-1 I-Cache Penalty Cycle Count" 29 + }, 30 + { 31 + "Unit": "CPU-M-CF", 32 + "EventCode": "4", 33 + "EventName": "L1D_DIR_WRITES", 34 + "BriefDescription": "L1D Directory Writes", 35 + "PublicDescription": "Level-1 D-Cache Directory Write Count" 36 + }, 37 + { 38 + "Unit": "CPU-M-CF", 39 + "EventCode": "5", 40 + "EventName": "L1D_PENALTY_CYCLES", 41 + "BriefDescription": "L1D Penalty Cycles", 42 + "PublicDescription": "Level-1 D-Cache Penalty Cycle Count" 43 + }, 44 + { 45 + "Unit": "CPU-M-CF", 46 + "EventCode": "32", 47 + "EventName": "PROBLEM_STATE_CPU_CYCLES", 48 + "BriefDescription": "Problem-State CPU Cycles", 49 + "PublicDescription": "Problem-State Cycle Count" 50 + }, 51 + { 52 + "Unit": "CPU-M-CF", 53 + "EventCode": "33", 54 + "EventName": "PROBLEM_STATE_INSTRUCTIONS", 55 + "BriefDescription": "Problem-State Instructions", 56 + "PublicDescription": "Problem-State Instruction Count" 57 + }, 58 + ]
+114
tools/perf/pmu-events/arch/s390/cf_m8561/crypto.json
··· 1 + [ 2 + { 3 + "Unit": "CPU-M-CF", 4 + "EventCode": "64", 5 + "EventName": "PRNG_FUNCTIONS", 6 + "BriefDescription": "PRNG Functions", 7 + "PublicDescription": "Total number of the PRNG functions issued by the CPU" 8 + }, 9 + { 10 + "Unit": "CPU-M-CF", 11 + "EventCode": "65", 12 + "EventName": "PRNG_CYCLES", 13 + "BriefDescription": "PRNG Cycles", 14 + "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing PRNG functions issued by the CPU" 15 + }, 16 + { 17 + "Unit": "CPU-M-CF", 18 + "EventCode": "66", 19 + "EventName": "PRNG_BLOCKED_FUNCTIONS", 20 + "BriefDescription": "PRNG Blocked Functions", 21 + "PublicDescription": "Total number of the PRNG functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" 22 + }, 23 + { 24 + "Unit": "CPU-M-CF", 25 + "EventCode": "67", 26 + "EventName": "PRNG_BLOCKED_CYCLES", 27 + "BriefDescription": "PRNG Blocked Cycles", 28 + "PublicDescription": "Total number of CPU cycles blocked for the PRNG functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" 29 + }, 30 + { 31 + "Unit": "CPU-M-CF", 32 + "EventCode": "68", 33 + "EventName": "SHA_FUNCTIONS", 34 + "BriefDescription": "SHA Functions", 35 + "PublicDescription": "Total number of SHA functions issued by the CPU" 36 + }, 37 + { 38 + "Unit": "CPU-M-CF", 39 + "EventCode": "69", 40 + "EventName": "SHA_CYCLES", 41 + "BriefDescription": "SHA Cycles", 42 + "PublicDescription": "Total number of CPU cycles when the SHA coprocessor is busy performing the SHA functions issued by the CPU" 43 + }, 44 + { 45 + "Unit": "CPU-M-CF", 46 + "EventCode": "70", 47 + "EventName": "SHA_BLOCKED_FUNCTIONS", 48 + "BriefDescription": "SHA Blocked Functions", 49 + "PublicDescription": "Total number of the SHA functions that are issued by the CPU and are blocked because the SHA coprocessor is busy performing a function issued by another CPU" 50 + }, 51 + { 52 + "Unit": "CPU-M-CF", 53 + "EventCode": "71", 54 + "EventName": "SHA_BLOCKED_CYCLES", 55 + "BriefDescription": "SHA Bloced Cycles", 56 + "PublicDescription": "Total number of CPU cycles blocked for the SHA functions issued by the CPU because the SHA coprocessor is busy performing a function issued by another CPU" 57 + }, 58 + { 59 + "Unit": "CPU-M-CF", 60 + "EventCode": "72", 61 + "EventName": "DEA_FUNCTIONS", 62 + "BriefDescription": "DEA Functions", 63 + "PublicDescription": "Total number of the DEA functions issued by the CPU" 64 + }, 65 + { 66 + "Unit": "CPU-M-CF", 67 + "EventCode": "73", 68 + "EventName": "DEA_CYCLES", 69 + "BriefDescription": "DEA Cycles", 70 + "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the DEA functions issued by the CPU" 71 + }, 72 + { 73 + "Unit": "CPU-M-CF", 74 + "EventCode": "74", 75 + "EventName": "DEA_BLOCKED_FUNCTIONS", 76 + "BriefDescription": "DEA Blocked Functions", 77 + "PublicDescription": "Total number of the DEA functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" 78 + }, 79 + { 80 + "Unit": "CPU-M-CF", 81 + "EventCode": "75", 82 + "EventName": "DEA_BLOCKED_CYCLES", 83 + "BriefDescription": "DEA Blocked Cycles", 84 + "PublicDescription": "Total number of CPU cycles blocked for the DEA functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" 85 + }, 86 + { 87 + "Unit": "CPU-M-CF", 88 + "EventCode": "76", 89 + "EventName": "AES_FUNCTIONS", 90 + "BriefDescription": "AES Functions", 91 + "PublicDescription": "Total number of AES functions issued by the CPU" 92 + }, 93 + { 94 + "Unit": "CPU-M-CF", 95 + "EventCode": "77", 96 + "EventName": "AES_CYCLES", 97 + "BriefDescription": "AES Cycles", 98 + "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the AES functions issued by the CPU" 99 + }, 100 + { 101 + "Unit": "CPU-M-CF", 102 + "EventCode": "78", 103 + "EventName": "AES_BLOCKED_FUNCTIONS", 104 + "BriefDescription": "AES Blocked Functions", 105 + "PublicDescription": "Total number of AES functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" 106 + }, 107 + { 108 + "Unit": "CPU-M-CF", 109 + "EventCode": "79", 110 + "EventName": "AES_BLOCKED_CYCLES", 111 + "BriefDescription": "AES Blocked Cycles", 112 + "PublicDescription": "Total number of CPU cycles blocked for the AES functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" 113 + }, 114 + ]
+30
tools/perf/pmu-events/arch/s390/cf_m8561/crypto6.json
··· 1 + [ 2 + { 3 + "Unit": "CPU-M-CF", 4 + "EventCode": "80", 5 + "EventName": "ECC_FUNCTION_COUNT", 6 + "BriefDescription": "ECC Function Count", 7 + "PublicDescription": "Long ECC function Count" 8 + }, 9 + { 10 + "Unit": "CPU-M-CF", 11 + "EventCode": "81", 12 + "EventName": "ECC_CYCLES_COUNT", 13 + "BriefDescription": "ECC Cycles Count", 14 + "PublicDescription": "Long ECC Function cycles count" 15 + }, 16 + { 17 + "Unit": "CPU-M-CF", 18 + "EventCode": "82", 19 + "EventName": "ECC_BLOCKED_FUNCTION_COUNT", 20 + "BriefDescription": "Ecc Blocked Function Count", 21 + "PublicDescription": "Long ECC blocked function count" 22 + }, 23 + { 24 + "Unit": "CPU-M-CF", 25 + "EventCode": "83", 26 + "EventName": "ECC_BLOCKED_CYCLES_COUNT", 27 + "BriefDescription": "ECC Blocked Cycles Count", 28 + "PublicDescription": "Long ECC blocked cycles count" 29 + }, 30 + ]
+373
tools/perf/pmu-events/arch/s390/cf_m8561/extended.json
··· 1 + [ 2 + { 3 + "Unit": "CPU-M-CF", 4 + "EventCode": "128", 5 + "EventName": "L1D_RO_EXCL_WRITES", 6 + "BriefDescription": "L1D Read-only Exclusive Writes", 7 + "PublicDescription": "A directory write to the Level-1 Data cache where the line was originally in a Read-Only state in the cache but has been updated to be in the Exclusive state that allows stores to the cache line" 8 + }, 9 + { 10 + "Unit": "CPU-M-CF", 11 + "EventCode": "129", 12 + "EventName": "DTLB2_WRITES", 13 + "BriefDescription": "DTLB2 Writes", 14 + "PublicDescription": "A translation has been written into The Translation Lookaside Buffer 2 (TLB2) and the request was made by the data cache" 15 + }, 16 + { 17 + "Unit": "CPU-M-CF", 18 + "EventCode": "130", 19 + "EventName": "DTLB2_MISSES", 20 + "BriefDescription": "DTLB2 Misses", 21 + "PublicDescription": "A TLB2 miss is in progress for a request made by the data cache. Incremented by one for every TLB2 miss in progress for the Level-1 Data cache on this cycle" 22 + }, 23 + { 24 + "Unit": "CPU-M-CF", 25 + "EventCode": "131", 26 + "EventName": "DTLB2_HPAGE_WRITES", 27 + "BriefDescription": "DTLB2 One-Megabyte Page Writes", 28 + "PublicDescription": "A translation entry was written into the Combined Region and Segment Table Entry array in the Level-2 TLB for a one-megabyte page or a Last Host Translation was done" 29 + }, 30 + { 31 + "Unit": "CPU-M-CF", 32 + "EventCode": "132", 33 + "EventName": "DTLB2_GPAGE_WRITES", 34 + "BriefDescription": "DTLB2 Two-Gigabyte Page Writes", 35 + "PublicDescription": "A translation entry for a two-gigabyte page was written into the Level-2 TLB" 36 + }, 37 + { 38 + "Unit": "CPU-M-CF", 39 + "EventCode": "133", 40 + "EventName": "L1D_L2D_SOURCED_WRITES", 41 + "BriefDescription": "L1D L2D Sourced Writes", 42 + "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from the Level-2 Data cache" 43 + }, 44 + { 45 + "Unit": "CPU-M-CF", 46 + "EventCode": "134", 47 + "EventName": "ITLB2_WRITES", 48 + "BriefDescription": "ITLB2 Writes", 49 + "PublicDescription": "A translation entry has been written into the Translation Lookaside Buffer 2 (TLB2) and the request was made by the instruction cache" 50 + }, 51 + { 52 + "Unit": "CPU-M-CF", 53 + "EventCode": "135", 54 + "EventName": "ITLB2_MISSES", 55 + "BriefDescription": "ITLB2 Misses", 56 + "PublicDescription": "A TLB2 miss is in progress for a request made by the instruction cache. Incremented by one for every TLB2 miss in progress for the Level-1 Instruction cache in a cycle" 57 + }, 58 + { 59 + "Unit": "CPU-M-CF", 60 + "EventCode": "136", 61 + "EventName": "L1I_L2I_SOURCED_WRITES", 62 + "BriefDescription": "L1I L2I Sourced Writes", 63 + "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from the Level-2 Instruction cache" 64 + }, 65 + { 66 + "Unit": "CPU-M-CF", 67 + "EventCode": "137", 68 + "EventName": "TLB2_PTE_WRITES", 69 + "BriefDescription": "TLB2 PTE Writes", 70 + "PublicDescription": "A translation entry was written into the Page Table Entry array in the Level-2 TLB" 71 + }, 72 + { 73 + "Unit": "CPU-M-CF", 74 + "EventCode": "138", 75 + "EventName": "TLB2_CRSTE_WRITES", 76 + "BriefDescription": "TLB2 CRSTE Writes", 77 + "PublicDescription": "Translation entries were written into the Combined Region and Segment Table Entry array and the Page Table Entry array in the Level-2 TLB" 78 + }, 79 + { 80 + "Unit": "CPU-M-CF", 81 + "EventCode": "139", 82 + "EventName": "TLB2_ENGINES_BUSY", 83 + "BriefDescription": "TLB2 Engines Busy", 84 + "PublicDescription": "The number of Level-2 TLB translation engines busy in a cycle" 85 + }, 86 + { 87 + "Unit": "CPU-M-CF", 88 + "EventCode": "140", 89 + "EventName": "TX_C_TEND", 90 + "BriefDescription": "Completed TEND instructions in constrained TX mode", 91 + "PublicDescription": "A TEND instruction has completed in a constrained transactional-execution mode" 92 + }, 93 + { 94 + "Unit": "CPU-M-CF", 95 + "EventCode": "141", 96 + "EventName": "TX_NC_TEND", 97 + "BriefDescription": "Completed TEND instructions in non-constrained TX mode", 98 + "PublicDescription": "A TEND instruction has completed in a non-constrained transactional-execution mode" 99 + }, 100 + { 101 + "Unit": "CPU-M-CF", 102 + "EventCode": "143", 103 + "EventName": "L1C_TLB2_MISSES", 104 + "BriefDescription": "L1C TLB2 Misses", 105 + "PublicDescription": "Increments by one for any cycle where a level-1 cache or level-2 TLB miss is in progress" 106 + }, 107 + { 108 + "Unit": "CPU-M-CF", 109 + "EventCode": "144", 110 + "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES", 111 + "BriefDescription": "L1D On-Chip L3 Sourced Writes", 112 + "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Chip Level-3 cache without intervention" 113 + }, 114 + { 115 + "Unit": "CPU-M-CF", 116 + "EventCode": "145", 117 + "EventName": "L1D_ONCHIP_MEMORY_SOURCED_WRITES", 118 + "BriefDescription": "L1D On-Chip Memory Sourced Writes", 119 + "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Chip memory" 120 + }, 121 + { 122 + "Unit": "CPU-M-CF", 123 + "EventCode": "146", 124 + "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_IV", 125 + "BriefDescription": "L1D On-Chip L3 Sourced Writes with Intervention", 126 + "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Chip Level-3 cache with intervention" 127 + }, 128 + { 129 + "Unit": "CPU-M-CF", 130 + "EventCode": "147", 131 + "EventName": "L1D_ONCLUSTER_L3_SOURCED_WRITES", 132 + "BriefDescription": "L1D On-Cluster L3 Sourced Writes", 133 + "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Cluster Level-3 cache withountervention" 134 + }, 135 + { 136 + "Unit": "CPU-M-CF", 137 + "EventCode": "148", 138 + "EventName": "L1D_ONCLUSTER_MEMORY_SOURCED_WRITES", 139 + "BriefDescription": "L1D On-Cluster Memory Sourced Writes", 140 + "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Cluster memory" 141 + }, 142 + { 143 + "Unit": "CPU-M-CF", 144 + "EventCode": "149", 145 + "EventName": "L1D_ONCLUSTER_L3_SOURCED_WRITES_IV", 146 + "BriefDescription": "L1D On-Cluster L3 Sourced Writes with Intervention", 147 + "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Cluster Level-3 cache with intervention" 148 + }, 149 + { 150 + "Unit": "CPU-M-CF", 151 + "EventCode": "150", 152 + "EventName": "L1D_OFFCLUSTER_L3_SOURCED_WRITES", 153 + "BriefDescription": "L1D Off-Cluster L3 Sourced Writes", 154 + "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache without intervention" 155 + }, 156 + { 157 + "Unit": "CPU-M-CF", 158 + "EventCode": "151", 159 + "EventName": "L1D_OFFCLUSTER_MEMORY_SOURCED_WRITES", 160 + "BriefDescription": "L1D Off-Cluster Memory Sourced Writes", 161 + "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Cluster memory" 162 + }, 163 + { 164 + "Unit": "CPU-M-CF", 165 + "EventCode": "152", 166 + "EventName": "L1D_OFFCLUSTER_L3_SOURCED_WRITES_IV", 167 + "BriefDescription": "L1D Off-Cluster L3 Sourced Writes with Intervention", 168 + "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache with intervention" 169 + }, 170 + { 171 + "Unit": "CPU-M-CF", 172 + "EventCode": "153", 173 + "EventName": "L1D_OFFDRAWER_L3_SOURCED_WRITES", 174 + "BriefDescription": "L1D Off-Drawer L3 Sourced Writes", 175 + "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache without intervention" 176 + }, 177 + { 178 + "Unit": "CPU-M-CF", 179 + "EventCode": "154", 180 + "EventName": "L1D_OFFDRAWER_MEMORY_SOURCED_WRITES", 181 + "BriefDescription": "L1D Off-Drawer Memory Sourced Writes", 182 + "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Drawer memory" 183 + }, 184 + { 185 + "Unit": "CPU-M-CF", 186 + "EventCode": "155", 187 + "EventName": "L1D_OFFDRAWER_L3_SOURCED_WRITES_IV", 188 + "BriefDescription": "L1D Off-Drawer L3 Sourced Writes with Intervention", 189 + "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache with intervention" 190 + }, 191 + { 192 + "Unit": "CPU-M-CF", 193 + "EventCode": "156", 194 + "EventName": "L1D_ONDRAWER_L4_SOURCED_WRITES", 195 + "BriefDescription": "L1D On-Drawer L4 Sourced Writes", 196 + "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Drawer Level-4 cache" 197 + }, 198 + { 199 + "Unit": "CPU-M-CF", 200 + "EventCode": "157", 201 + "EventName": "L1D_OFFDRAWER_L4_SOURCED_WRITES", 202 + "BriefDescription": "L1D Off-Drawer L4 Sourced Writes", 203 + "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Drawer Level-4 cache" 204 + }, 205 + { 206 + "Unit": "CPU-M-CF", 207 + "EventCode": "158", 208 + "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_RO", 209 + "BriefDescription": "L1D On-Chip L3 Sourced Writes read-only", 210 + "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Chip L3 but a read-only invalidate was done to remove other copies of the cache line" 211 + }, 212 + { 213 + "Unit": "CPU-M-CF", 214 + "EventCode": "162", 215 + "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES", 216 + "BriefDescription": "L1I On-Chip L3 Sourced Writes", 217 + "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from an On-Chip Level-3 cache without intervention" 218 + }, 219 + { 220 + "Unit": "CPU-M-CF", 221 + "EventCode": "163", 222 + "EventName": "L1I_ONCHIP_MEMORY_SOURCED_WRITES", 223 + "BriefDescription": "L1I On-Chip Memory Sourced Writes", 224 + "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from On-Chip memory" 225 + }, 226 + { 227 + "Unit": "CPU-M-CF", 228 + "EventCode": "164", 229 + "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES_IV", 230 + "BriefDescription": "L1I On-Chip L3 Sourced Writes with Intervention", 231 + "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from an On-Chip Level-3 cache with intervention" 232 + }, 233 + { 234 + "Unit": "CPU-M-CF", 235 + "EventCode": "165", 236 + "EventName": "L1I_ONCLUSTER_L3_SOURCED_WRITES", 237 + "BriefDescription": "L1I On-Cluster L3 Sourced Writes", 238 + "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Cluster Level-3 cache without intervention" 239 + }, 240 + { 241 + "Unit": "CPU-M-CF", 242 + "EventCode": "166", 243 + "EventName": "L1I_ONCLUSTER_MEMORY_SOURCED_WRITES", 244 + "BriefDescription": "L1I On-Cluster Memory Sourced Writes", 245 + "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Cluster memory" 246 + }, 247 + { 248 + "Unit": "CPU-M-CF", 249 + "EventCode": "167", 250 + "EventName": "L1I_ONCLUSTER_L3_SOURCED_WRITES_IV", 251 + "BriefDescription": "L1I On-Cluster L3 Sourced Writes with Intervention", 252 + "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Cluster Level-3 cache with intervention" 253 + }, 254 + { 255 + "Unit": "CPU-M-CF", 256 + "EventCode": "168", 257 + "EventName": "L1I_OFFCLUSTER_L3_SOURCED_WRITES", 258 + "BriefDescription": "L1I Off-Cluster L3 Sourced Writes", 259 + "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache without intervention" 260 + }, 261 + { 262 + "Unit": "CPU-M-CF", 263 + "EventCode": "169", 264 + "EventName": "L1I_OFFCLUSTER_MEMORY_SOURCED_WRITES", 265 + "BriefDescription": "L1I Off-Cluster Memory Sourced Writes", 266 + "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Cluster memory" 267 + }, 268 + { 269 + "Unit": "CPU-M-CF", 270 + "EventCode": "170", 271 + "EventName": "L1I_OFFCLUSTER_L3_SOURCED_WRITES_IV", 272 + "BriefDescription": "L1I Off-Cluster L3 Sourced Writes with Intervention", 273 + "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache with intervention" 274 + }, 275 + { 276 + "Unit": "CPU-M-CF", 277 + "EventCode": "171", 278 + "EventName": "L1I_OFFDRAWER_L3_SOURCED_WRITES", 279 + "BriefDescription": "L1I Off-Drawer L3 Sourced Writes", 280 + "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache without intervention" 281 + }, 282 + { 283 + "Unit": "CPU-M-CF", 284 + "EventCode": "172", 285 + "EventName": "L1I_OFFDRAWER_MEMORY_SOURCED_WRITES", 286 + "BriefDescription": "L1I Off-Drawer Memory Sourced Writes", 287 + "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Drawer memory" 288 + }, 289 + { 290 + "Unit": "CPU-M-CF", 291 + "EventCode": "173", 292 + "EventName": "L1I_OFFDRAWER_L3_SOURCED_WRITES_IV", 293 + "BriefDescription": "L1I Off-Drawer L3 Sourced Writes with Intervention", 294 + "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache with intervention" 295 + }, 296 + { 297 + "Unit": "CPU-M-CF", 298 + "EventCode": "174", 299 + "EventName": "L1I_ONDRAWER_L4_SOURCED_WRITES", 300 + "BriefDescription": "L1I On-Drawer L4 Sourced Writes", 301 + "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Drawer Level-4 cache" 302 + }, 303 + { 304 + "Unit": "CPU-M-CF", 305 + "EventCode": "175", 306 + "EventName": "L1I_OFFDRAWER_L4_SOURCED_WRITES", 307 + "BriefDescription": "L1I Off-Drawer L4 Sourced Writes", 308 + "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Drawer Level-4 cache" 309 + }, 310 + { 311 + "Unit": "CPU-M-CF", 312 + "EventCode": "224", 313 + "EventName": "BCD_DFP_EXECUTION_SLOTS", 314 + "BriefDescription": "BCD DFP Execution Slots", 315 + "PublicDescription": "Count of floating point execution slots used for finished Binary Coded Decimal to Decimal Floating Point conversions. Instructions: CDZT, CXZT, CZDT, CZXT" 316 + }, 317 + { 318 + "Unit": "CPU-M-CF", 319 + "EventCode": "225", 320 + "EventName": "VX_BCD_EXECUTION_SLOTS", 321 + "BriefDescription": "VX BCD Execution Slots", 322 + "PublicDescription": "Count of floating point execution slots used for finished vector arithmetic Binary Coded Decimal instructions. Instructions: VAP, VSP, VMPVMSP, VDP, VSDP, VRP, VLIP, VSRP, VPSOPVCP, VTP, VPKZ, VUPKZ, VCVB, VCVBG, VCVDVCVDG" 323 + }, 324 + { 325 + "Unit": "CPU-M-CF", 326 + "EventCode": "226", 327 + "EventName": "DECIMAL_INSTRUCTIONS", 328 + "BriefDescription": "Decimal Instructions", 329 + "PublicDescription": "Decimal instructions dispatched. Instructions: CVB, CVD, AP, CP, DP, ED, EDMK, MP, SRP, SP, ZAP" 330 + }, 331 + { 332 + "Unit": "CPU-M-CF", 333 + "EventCode": "232", 334 + "EventName": "LAST_HOST_TRANSLATIONS", 335 + "BriefDescription": "Last host translation done", 336 + "PublicDescription": "Last Host Translation done" 337 + }, 338 + { 339 + "Unit": "CPU-M-CF", 340 + "EventCode": "243", 341 + "EventName": "TX_NC_TABORT", 342 + "BriefDescription": "Aborted transactions in non-constrained TX mode", 343 + "PublicDescription": "A transaction abort has occurred in a non-constrained transactional-execution mode" 344 + }, 345 + { 346 + "Unit": "CPU-M-CF", 347 + "EventCode": "244", 348 + "EventName": "TX_C_TABORT_NO_SPECIAL", 349 + "BriefDescription": "Aborted transactions in constrained TX mode not using special completion logic", 350 + "PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is not using any special logic to allow the transaction to complete" 351 + }, 352 + { 353 + "Unit": "CPU-M-CF", 354 + "EventCode": "245", 355 + "EventName": "TX_C_TABORT_SPECIAL", 356 + "BriefDescription": "Aborted transactions in constrained TX mode using special completion logic", 357 + "PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is using special logic to allow the transaction to complete" 358 + }, 359 + { 360 + "Unit": "CPU-M-CF", 361 + "EventCode": "448", 362 + "EventName": "MT_DIAG_CYCLES_ONE_THR_ACTIVE", 363 + "BriefDescription": "Cycle count with one thread active", 364 + "PublicDescription": "Cycle count with one thread active" 365 + }, 366 + { 367 + "Unit": "CPU-M-CF", 368 + "EventCode": "449", 369 + "EventName": "MT_DIAG_CYCLES_TWO_THR_ACTIVE", 370 + "BriefDescription": "Cycle count with two threads active", 371 + "PublicDescription": "Cycle count with two threads active" 372 + }, 373 + ]
+1
tools/perf/pmu-events/arch/s390/mapfile.csv
··· 4 4 ^IBM.282[78].*[13]\.[1-5].[[:xdigit:]]+$,1,cf_zec12,core 5 5 ^IBM.296[45].*[13]\.[1-5].[[:xdigit:]]+$,1,cf_z13,core 6 6 ^IBM.390[67].*[13]\.[1-5].[[:xdigit:]]+$,3,cf_z14,core 7 + ^IBM.856[12].*3\.6.[[:xdigit:]]+$,3,cf_m8561,core
+63 -5
tools/perf/scripts/python/export-to-postgresql.py
··· 353 353 'tid integer)') 354 354 do_query(query, 'CREATE TABLE comms (' 355 355 'id bigint NOT NULL,' 356 - 'comm varchar(16))') 356 + 'comm varchar(16),' 357 + 'c_thread_id bigint,' 358 + 'c_time bigint,' 359 + 'exec_flag boolean)') 357 360 do_query(query, 'CREATE TABLE comm_threads (' 358 361 'id bigint NOT NULL,' 359 362 'comm_id bigint,' ··· 481 478 'deepest_cstate integer,' 482 479 'last_cstate integer,' 483 480 'wake_reason integer)') 481 + 482 + do_query(query, 'CREATE TABLE context_switches (' 483 + 'id bigint NOT NULL,' 484 + 'machine_id bigint,' 485 + 'time bigint,' 486 + 'cpu integer,' 487 + 'thread_out_id bigint,' 488 + 'comm_out_id bigint,' 489 + 'thread_in_id bigint,' 490 + 'comm_in_id bigint,' 491 + 'flags integer)') 484 492 485 493 do_query(query, 'CREATE VIEW machines_view AS ' 486 494 'SELECT ' ··· 706 692 ' INNER JOIN selected_events ON selected_events.id = samples.evsel_id' 707 693 ' ORDER BY samples.id') 708 694 695 + do_query(query, 'CREATE VIEW context_switches_view AS ' 696 + 'SELECT ' 697 + 'context_switches.id,' 698 + 'context_switches.machine_id,' 699 + 'context_switches.time,' 700 + 'context_switches.cpu,' 701 + 'th_out.pid AS pid_out,' 702 + 'th_out.tid AS tid_out,' 703 + 'comm_out.comm AS comm_out,' 704 + 'th_in.pid AS pid_in,' 705 + 'th_in.tid AS tid_in,' 706 + 'comm_in.comm AS comm_in,' 707 + 'CASE WHEN context_switches.flags = 0 THEN \'in\'' 708 + ' WHEN context_switches.flags = 1 THEN \'out\'' 709 + ' WHEN context_switches.flags = 3 THEN \'out preempt\'' 710 + ' ELSE CAST ( context_switches.flags AS VARCHAR(11) )' 711 + 'END AS flags' 712 + ' FROM context_switches' 713 + ' INNER JOIN threads AS th_out ON th_out.id = context_switches.thread_out_id' 714 + ' INNER JOIN threads AS th_in ON th_in.id = context_switches.thread_in_id' 715 + ' INNER JOIN comms AS comm_out ON comm_out.id = context_switches.comm_out_id' 716 + ' INNER JOIN comms AS comm_in ON comm_in.id = context_switches.comm_in_id') 717 + 709 718 file_header = struct.pack("!11sii", b"PGCOPY\n\377\r\n\0", 0, 0) 710 719 file_trailer = b"\377\377" 711 720 ··· 793 756 pwre_file = open_output_file("pwre_table.bin") 794 757 exstop_file = open_output_file("exstop_table.bin") 795 758 pwrx_file = open_output_file("pwrx_table.bin") 759 + context_switches_file = open_output_file("context_switches_table.bin") 796 760 797 761 def trace_begin(): 798 762 printdate("Writing to intermediate files...") ··· 801 763 evsel_table(0, "unknown") 802 764 machine_table(0, 0, "unknown") 803 765 thread_table(0, 0, 0, -1, -1) 804 - comm_table(0, "unknown") 766 + comm_table(0, "unknown", 0, 0, 0) 805 767 dso_table(0, 0, "unknown", "unknown", "") 806 768 symbol_table(0, 0, 0, 0, 0, "unknown") 807 769 sample_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) ··· 842 804 copy_output_file(pwre_file, "pwre") 843 805 copy_output_file(exstop_file, "exstop") 844 806 copy_output_file(pwrx_file, "pwrx") 807 + copy_output_file(context_switches_file, "context_switches") 845 808 846 809 printdate("Removing intermediate files...") 847 810 remove_output_file(evsel_file) ··· 864 825 remove_output_file(pwre_file) 865 826 remove_output_file(exstop_file) 866 827 remove_output_file(pwrx_file) 828 + remove_output_file(context_switches_file) 867 829 os.rmdir(output_dir_name) 868 830 printdate("Adding primary keys") 869 831 do_query(query, 'ALTER TABLE selected_events ADD PRIMARY KEY (id)') ··· 886 846 do_query(query, 'ALTER TABLE pwre ADD PRIMARY KEY (id)') 887 847 do_query(query, 'ALTER TABLE exstop ADD PRIMARY KEY (id)') 888 848 do_query(query, 'ALTER TABLE pwrx ADD PRIMARY KEY (id)') 849 + do_query(query, 'ALTER TABLE context_switches ADD PRIMARY KEY (id)') 889 850 890 851 printdate("Adding foreign keys") 891 852 do_query(query, 'ALTER TABLE threads ' 892 853 'ADD CONSTRAINT machinefk FOREIGN KEY (machine_id) REFERENCES machines (id),' 893 854 'ADD CONSTRAINT processfk FOREIGN KEY (process_id) REFERENCES threads (id)') 855 + do_query(query, 'ALTER TABLE comms ' 856 + 'ADD CONSTRAINT threadfk FOREIGN KEY (c_thread_id) REFERENCES threads (id)') 894 857 do_query(query, 'ALTER TABLE comm_threads ' 895 858 'ADD CONSTRAINT commfk FOREIGN KEY (comm_id) REFERENCES comms (id),' 896 859 'ADD CONSTRAINT threadfk FOREIGN KEY (thread_id) REFERENCES threads (id)') ··· 924 881 'ADD CONSTRAINT parent_call_pathfk FOREIGN KEY (parent_call_path_id) REFERENCES call_paths (id)') 925 882 do_query(query, 'CREATE INDEX pcpid_idx ON calls (parent_call_path_id)') 926 883 do_query(query, 'CREATE INDEX pid_idx ON calls (parent_id)') 884 + do_query(query, 'ALTER TABLE comms ADD has_calls boolean') 885 + do_query(query, 'UPDATE comms SET has_calls = TRUE WHERE comms.id IN (SELECT DISTINCT comm_id FROM calls)') 927 886 do_query(query, 'ALTER TABLE ptwrite ' 928 887 'ADD CONSTRAINT idfk FOREIGN KEY (id) REFERENCES samples (id)') 929 888 do_query(query, 'ALTER TABLE cbr ' ··· 938 893 'ADD CONSTRAINT idfk FOREIGN KEY (id) REFERENCES samples (id)') 939 894 do_query(query, 'ALTER TABLE pwrx ' 940 895 'ADD CONSTRAINT idfk FOREIGN KEY (id) REFERENCES samples (id)') 896 + do_query(query, 'ALTER TABLE context_switches ' 897 + 'ADD CONSTRAINT machinefk FOREIGN KEY (machine_id) REFERENCES machines (id),' 898 + 'ADD CONSTRAINT toutfk FOREIGN KEY (thread_out_id) REFERENCES threads (id),' 899 + 'ADD CONSTRAINT tinfk FOREIGN KEY (thread_in_id) REFERENCES threads (id),' 900 + 'ADD CONSTRAINT coutfk FOREIGN KEY (comm_out_id) REFERENCES comms (id),' 901 + 'ADD CONSTRAINT cinfk FOREIGN KEY (comm_in_id) REFERENCES comms (id)') 941 902 942 903 printdate("Dropping unused tables") 943 904 if is_table_empty("ptwrite"): ··· 956 905 drop("pwrx") 957 906 if is_table_empty("cbr"): 958 907 drop("cbr") 908 + if is_table_empty("context_switches"): 909 + drop("context_switches") 959 910 960 911 if (unhandled_count): 961 912 printdate("Warning: ", unhandled_count, " unhandled events") ··· 988 935 value = struct.pack("!hiqiqiqiiii", 5, 8, thread_id, 8, machine_id, 8, process_id, 4, pid, 4, tid) 989 936 thread_file.write(value) 990 937 991 - def comm_table(comm_id, comm_str, *x): 938 + def comm_table(comm_id, comm_str, thread_id, time, exec_flag, *x): 992 939 comm_str = toserverstr(comm_str) 993 940 n = len(comm_str) 994 - fmt = "!hiqi" + str(n) + "s" 995 - value = struct.pack(fmt, 2, 8, comm_id, n, comm_str) 941 + fmt = "!hiqi" + str(n) + "s" + "iqiqiB" 942 + value = struct.pack(fmt, 5, 8, comm_id, n, comm_str, 8, thread_id, 8, time, 1, exec_flag) 996 943 comm_file.write(value) 997 944 998 945 def comm_thread_table(comm_thread_id, comm_id, thread_id, *x): ··· 1104 1051 pwrx(id, raw_buf) 1105 1052 elif config == 5: 1106 1053 cbr(id, raw_buf) 1054 + 1055 + def context_switch_table(id, machine_id, time, cpu, thread_out_id, comm_out_id, thread_in_id, comm_in_id, flags, *x): 1056 + fmt = "!hiqiqiqiiiqiqiqiqii" 1057 + value = struct.pack(fmt, 9, 8, id, 8, machine_id, 8, time, 4, cpu, 8, thread_out_id, 8, comm_out_id, 8, thread_in_id, 8, comm_in_id, 4, flags) 1058 + context_switches_file.write(value)
+50 -4
tools/perf/scripts/python/export-to-sqlite.py
··· 177 177 'tid integer)') 178 178 do_query(query, 'CREATE TABLE comms (' 179 179 'id integer NOT NULL PRIMARY KEY,' 180 - 'comm varchar(16))') 180 + 'comm varchar(16),' 181 + 'c_thread_id bigint,' 182 + 'c_time bigint,' 183 + 'exec_flag boolean)') 181 184 do_query(query, 'CREATE TABLE comm_threads (' 182 185 'id integer NOT NULL PRIMARY KEY,' 183 186 'comm_id bigint,' ··· 305 302 'deepest_cstate integer,' 306 303 'last_cstate integer,' 307 304 'wake_reason integer)') 305 + 306 + do_query(query, 'CREATE TABLE context_switches (' 307 + 'id integer NOT NULL PRIMARY KEY,' 308 + 'machine_id bigint,' 309 + 'time bigint,' 310 + 'cpu integer,' 311 + 'thread_out_id bigint,' 312 + 'comm_out_id bigint,' 313 + 'thread_in_id bigint,' 314 + 'comm_in_id bigint,' 315 + 'flags integer)') 308 316 309 317 # printf was added to sqlite in version 3.8.3 310 318 sqlite_has_printf = False ··· 541 527 ' INNER JOIN selected_events ON selected_events.id = evsel_id' 542 528 ' WHERE selected_events.name IN (\'cbr\',\'mwait\',\'exstop\',\'pwre\',\'pwrx\')') 543 529 530 + do_query(query, 'CREATE VIEW context_switches_view AS ' 531 + 'SELECT ' 532 + 'context_switches.id,' 533 + 'context_switches.machine_id,' 534 + 'context_switches.time,' 535 + 'context_switches.cpu,' 536 + 'th_out.pid AS pid_out,' 537 + 'th_out.tid AS tid_out,' 538 + 'comm_out.comm AS comm_out,' 539 + 'th_in.pid AS pid_in,' 540 + 'th_in.tid AS tid_in,' 541 + 'comm_in.comm AS comm_in,' 542 + 'CASE WHEN context_switches.flags = 0 THEN \'in\'' 543 + ' WHEN context_switches.flags = 1 THEN \'out\'' 544 + ' WHEN context_switches.flags = 3 THEN \'out preempt\'' 545 + ' ELSE context_switches.flags ' 546 + 'END AS flags' 547 + ' FROM context_switches' 548 + ' INNER JOIN threads AS th_out ON th_out.id = context_switches.thread_out_id' 549 + ' INNER JOIN threads AS th_in ON th_in.id = context_switches.thread_in_id' 550 + ' INNER JOIN comms AS comm_out ON comm_out.id = context_switches.comm_out_id' 551 + ' INNER JOIN comms AS comm_in ON comm_in.id = context_switches.comm_in_id') 552 + 544 553 do_query(query, 'END TRANSACTION') 545 554 546 555 evsel_query = QSqlQuery(db) ··· 573 536 thread_query = QSqlQuery(db) 574 537 thread_query.prepare("INSERT INTO threads VALUES (?, ?, ?, ?, ?)") 575 538 comm_query = QSqlQuery(db) 576 - comm_query.prepare("INSERT INTO comms VALUES (?, ?)") 539 + comm_query.prepare("INSERT INTO comms VALUES (?, ?, ?, ?, ?)") 577 540 comm_thread_query = QSqlQuery(db) 578 541 comm_thread_query.prepare("INSERT INTO comm_threads VALUES (?, ?, ?)") 579 542 dso_query = QSqlQuery(db) ··· 605 568 exstop_query.prepare("INSERT INTO exstop VALUES (?, ?)") 606 569 pwrx_query = QSqlQuery(db) 607 570 pwrx_query.prepare("INSERT INTO pwrx VALUES (?, ?, ?, ?)") 571 + context_switch_query = QSqlQuery(db) 572 + context_switch_query.prepare("INSERT INTO context_switches VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)") 608 573 609 574 def trace_begin(): 610 575 printdate("Writing records...") ··· 615 576 evsel_table(0, "unknown") 616 577 machine_table(0, 0, "unknown") 617 578 thread_table(0, 0, 0, -1, -1) 618 - comm_table(0, "unknown") 579 + comm_table(0, "unknown", 0, 0, 0) 619 580 dso_table(0, 0, "unknown", "unknown", "") 620 581 symbol_table(0, 0, 0, 0, 0, "unknown") 621 582 sample_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) ··· 642 603 if perf_db_export_calls: 643 604 do_query(query, 'CREATE INDEX pcpid_idx ON calls (parent_call_path_id)') 644 605 do_query(query, 'CREATE INDEX pid_idx ON calls (parent_id)') 606 + do_query(query, 'ALTER TABLE comms ADD has_calls boolean') 607 + do_query(query, 'UPDATE comms SET has_calls = 1 WHERE comms.id IN (SELECT DISTINCT comm_id FROM calls)') 645 608 646 609 printdate("Dropping unused tables") 647 610 if is_table_empty("ptwrite"): ··· 656 615 drop("pwrx") 657 616 if is_table_empty("cbr"): 658 617 drop("cbr") 618 + if is_table_empty("context_switches"): 619 + drop("context_switches") 659 620 660 621 if (unhandled_count): 661 622 printdate("Warning: ", unhandled_count, " unhandled events") ··· 685 642 bind_exec(thread_query, 5, x) 686 643 687 644 def comm_table(*x): 688 - bind_exec(comm_query, 2, x) 645 + bind_exec(comm_query, 5, x) 689 646 690 647 def comm_thread_table(*x): 691 648 bind_exec(comm_thread_query, 3, x) ··· 791 748 pwrx(id, raw_buf) 792 749 elif config == 5: 793 750 cbr(id, raw_buf) 751 + 752 + def context_switch_table(*x): 753 + bind_exec(context_switch_query, 9, x)
+20 -14
tools/perf/scripts/python/exported-sql-viewer.py
··· 392 392 self.hbox.addWidget(self.close_button) 393 393 394 394 self.bar = QWidget() 395 - self.bar.setLayout(self.hbox); 395 + self.bar.setLayout(self.hbox) 396 396 self.bar.hide() 397 397 398 398 def Widget(self): ··· 470 470 self.params = params 471 471 self.row = row 472 472 self.parent_item = parent_item 473 - self.query_done = False; 473 + self.query_done = False 474 474 self.child_count = 0 475 475 self.child_items = [] 476 476 if parent_item: ··· 517 517 self.time = time 518 518 519 519 def Select(self): 520 - self.query_done = True; 520 + self.query_done = True 521 521 query = QSqlQuery(self.glb.db) 522 522 if self.params.have_ipc: 523 523 ipc_str = ", SUM(insn_count), SUM(cyc_count)" ··· 604 604 self.dbid = comm_id 605 605 606 606 def Select(self): 607 - self.query_done = True; 607 + self.query_done = True 608 608 query = QSqlQuery(self.glb.db) 609 609 QueryExec(query, "SELECT thread_id, pid, tid" 610 610 " FROM comm_threads" ··· 622 622 def __init__(self, glb, params): 623 623 super(CallGraphRootItem, self).__init__(glb, params, 0, None) 624 624 self.dbid = 0 625 - self.query_done = True; 625 + self.query_done = True 626 + if_has_calls = "" 627 + if IsSelectable(glb.db, "comms", columns = "has_calls"): 628 + if_has_calls = " WHERE has_calls = TRUE" 626 629 query = QSqlQuery(glb.db) 627 - QueryExec(query, "SELECT id, comm FROM comms") 630 + QueryExec(query, "SELECT id, comm FROM comms" + if_has_calls) 628 631 while query.next(): 629 632 if not query.value(0): 630 633 continue ··· 796 793 self.time = time 797 794 798 795 def Select(self): 799 - self.query_done = True; 796 + self.query_done = True 800 797 if self.calls_id == 0: 801 798 comm_thread = " AND comm_id = " + str(self.comm_id) + " AND thread_id = " + str(self.thread_id) 802 799 else: ··· 884 881 self.dbid = comm_id 885 882 886 883 def Select(self): 887 - self.query_done = True; 884 + self.query_done = True 888 885 query = QSqlQuery(self.glb.db) 889 886 QueryExec(query, "SELECT thread_id, pid, tid" 890 887 " FROM comm_threads" ··· 902 899 def __init__(self, glb, params): 903 900 super(CallTreeRootItem, self).__init__(glb, params, 0, None) 904 901 self.dbid = 0 905 - self.query_done = True; 902 + self.query_done = True 903 + if_has_calls = "" 904 + if IsSelectable(glb.db, "comms", columns = "has_calls"): 905 + if_has_calls = " WHERE has_calls = TRUE" 906 906 query = QSqlQuery(glb.db) 907 - QueryExec(query, "SELECT id, comm FROM comms") 907 + QueryExec(query, "SELECT id, comm FROM comms" + if_has_calls) 908 908 while query.next(): 909 909 if not query.value(0): 910 910 continue ··· 977 971 978 972 def __init__(self, w1, w2, w3=None): 979 973 self.vbox = QWidget() 980 - self.vbox.setLayout(QVBoxLayout()); 974 + self.vbox.setLayout(QVBoxLayout()) 981 975 982 976 self.vbox.layout().setContentsMargins(0, 0, 0, 0) 983 977 ··· 1397 1391 self.hbox.addWidget(self.close_button) 1398 1392 1399 1393 self.bar = QWidget() 1400 - self.bar.setLayout(self.hbox); 1394 + self.bar.setLayout(self.hbox) 1401 1395 self.bar.show() 1402 1396 1403 1397 self.in_progress = False ··· 2212 2206 self.vbox.addLayout(self.grid) 2213 2207 self.vbox.addLayout(self.hbox) 2214 2208 2215 - self.setLayout(self.vbox); 2209 + self.setLayout(self.vbox) 2216 2210 2217 2211 def Ok(self): 2218 2212 vars = self.report_vars ··· 3145 3139 self.vbox = QVBoxLayout() 3146 3140 self.vbox.addWidget(self.text) 3147 3141 3148 - self.setLayout(self.vbox); 3142 + self.setLayout(self.vbox) 3149 3143 3150 3144 # Font resize 3151 3145
+6
tools/perf/tests/builtin-test.c
··· 21 21 #include <subcmd/parse-options.h> 22 22 #include "string2.h" 23 23 #include "symbol.h" 24 + #include "util/rlimit.h" 24 25 #include <linux/kernel.h> 25 26 #include <linux/string.h> 26 27 #include <subcmd/exec-cmd.h> ··· 728 727 729 728 if (skip != NULL) 730 729 skiplist = intlist__new(skip); 730 + /* 731 + * Tests that create BPF maps, for instance, need more than the 64K 732 + * default: 733 + */ 734 + rlimit__bump_memlock(); 731 735 732 736 return __cmd_test(argc, argv, skiplist); 733 737 }
+1
tools/perf/util/Build
··· 20 20 perf-y += perf_regs.o 21 21 perf-y += path.o 22 22 perf-y += print_binary.o 23 + perf-y += rlimit.o 23 24 perf-y += argv_split.o 24 25 perf-y += rbtree.o 25 26 perf-y += libstring.o
+8 -4
tools/perf/util/cs-etm.c
··· 2460 2460 2461 2461 /* Something went wrong, no need to continue */ 2462 2462 if (!inode) { 2463 - err = PTR_ERR(inode); 2463 + err = -ENOMEM; 2464 2464 goto err_free_metadata; 2465 2465 } 2466 2466 ··· 2517 2517 session->auxtrace = &etm->auxtrace; 2518 2518 2519 2519 etm->unknown_thread = thread__new(999999999, 999999999); 2520 - if (!etm->unknown_thread) 2520 + if (!etm->unknown_thread) { 2521 + err = -ENOMEM; 2521 2522 goto err_free_queues; 2523 + } 2522 2524 2523 2525 /* 2524 2526 * Initialize list node so that at thread__zput() we can avoid ··· 2532 2530 if (err) 2533 2531 goto err_delete_thread; 2534 2532 2535 - if (thread__init_map_groups(etm->unknown_thread, etm->machine)) 2533 + if (thread__init_map_groups(etm->unknown_thread, etm->machine)) { 2534 + err = -ENOMEM; 2536 2535 goto err_delete_thread; 2536 + } 2537 2537 2538 2538 if (dump_trace) { 2539 2539 cs_etm__print_auxtrace_info(auxtrace_info->priv, num_cpu); ··· 2579 2575 err_free_hdr: 2580 2576 zfree(&hdr); 2581 2577 2582 - return -EINVAL; 2578 + return err; 2583 2579 }
+187 -104
tools/perf/util/db-export.c
··· 20 20 #include "db-export.h" 21 21 #include <linux/zalloc.h> 22 22 23 - struct deferred_export { 24 - struct list_head node; 25 - struct comm *comm; 26 - }; 27 - 28 - static int db_export__deferred(struct db_export *dbe) 29 - { 30 - struct deferred_export *de; 31 - int err; 32 - 33 - while (!list_empty(&dbe->deferred)) { 34 - de = list_entry(dbe->deferred.next, struct deferred_export, 35 - node); 36 - err = dbe->export_comm(dbe, de->comm); 37 - list_del_init(&de->node); 38 - free(de); 39 - if (err) 40 - return err; 41 - } 42 - 43 - return 0; 44 - } 45 - 46 - static void db_export__free_deferred(struct db_export *dbe) 47 - { 48 - struct deferred_export *de; 49 - 50 - while (!list_empty(&dbe->deferred)) { 51 - de = list_entry(dbe->deferred.next, struct deferred_export, 52 - node); 53 - list_del_init(&de->node); 54 - free(de); 55 - } 56 - } 57 - 58 - static int db_export__defer_comm(struct db_export *dbe, struct comm *comm) 59 - { 60 - struct deferred_export *de; 61 - 62 - de = zalloc(sizeof(struct deferred_export)); 63 - if (!de) 64 - return -ENOMEM; 65 - 66 - de->comm = comm; 67 - list_add_tail(&de->node, &dbe->deferred); 68 - 69 - return 0; 70 - } 71 - 72 23 int db_export__init(struct db_export *dbe) 73 24 { 74 25 memset(dbe, 0, sizeof(struct db_export)); 75 - INIT_LIST_HEAD(&dbe->deferred); 76 26 return 0; 77 - } 78 - 79 - int db_export__flush(struct db_export *dbe) 80 - { 81 - return db_export__deferred(dbe); 82 27 } 83 28 84 29 void db_export__exit(struct db_export *dbe) 85 30 { 86 - db_export__free_deferred(dbe); 87 31 call_return_processor__free(dbe->crp); 88 32 dbe->crp = NULL; 89 33 } ··· 59 115 } 60 116 61 117 int db_export__thread(struct db_export *dbe, struct thread *thread, 62 - struct machine *machine, struct comm *comm) 118 + struct machine *machine, struct thread *main_thread) 63 119 { 64 - struct thread *main_thread; 65 120 u64 main_thread_db_id = 0; 66 - int err; 67 121 68 122 if (thread->db_id) 69 123 return 0; 70 124 71 125 thread->db_id = ++dbe->thread_last_db_id; 72 126 73 - if (thread->pid_ != -1) { 74 - if (thread->pid_ == thread->tid) { 75 - main_thread = thread; 76 - } else { 77 - main_thread = machine__findnew_thread(machine, 78 - thread->pid_, 79 - thread->pid_); 80 - if (!main_thread) 81 - return -ENOMEM; 82 - err = db_export__thread(dbe, main_thread, machine, 83 - comm); 84 - if (err) 85 - goto out_put; 86 - if (comm) { 87 - err = db_export__comm_thread(dbe, comm, thread); 88 - if (err) 89 - goto out_put; 90 - } 91 - } 127 + if (main_thread) 92 128 main_thread_db_id = main_thread->db_id; 93 - if (main_thread != thread) 94 - thread__put(main_thread); 95 - } 96 129 97 130 if (dbe->export_thread) 98 131 return dbe->export_thread(dbe, thread, main_thread_db_id, 99 132 machine); 100 133 101 134 return 0; 135 + } 102 136 103 - out_put: 104 - thread__put(main_thread); 105 - return err; 137 + static int __db_export__comm(struct db_export *dbe, struct comm *comm, 138 + struct thread *thread) 139 + { 140 + comm->db_id = ++dbe->comm_last_db_id; 141 + 142 + if (dbe->export_comm) 143 + return dbe->export_comm(dbe, comm, thread); 144 + 145 + return 0; 106 146 } 107 147 108 148 int db_export__comm(struct db_export *dbe, struct comm *comm, 109 - struct thread *main_thread) 149 + struct thread *thread) 150 + { 151 + if (comm->db_id) 152 + return 0; 153 + 154 + return __db_export__comm(dbe, comm, thread); 155 + } 156 + 157 + /* 158 + * Export the "exec" comm. The "exec" comm is the program / application command 159 + * name at the time it first executes. It is used to group threads for the same 160 + * program. Note that the main thread pid (or thread group id tgid) cannot be 161 + * used because it does not change when a new program is exec'ed. 162 + */ 163 + int db_export__exec_comm(struct db_export *dbe, struct comm *comm, 164 + struct thread *main_thread) 110 165 { 111 166 int err; 112 167 113 168 if (comm->db_id) 114 169 return 0; 115 170 116 - comm->db_id = ++dbe->comm_last_db_id; 171 + err = __db_export__comm(dbe, comm, main_thread); 172 + if (err) 173 + return err; 117 174 118 - if (dbe->export_comm) { 119 - if (main_thread->comm_set) 120 - err = dbe->export_comm(dbe, comm); 121 - else 122 - err = db_export__defer_comm(dbe, comm); 123 - if (err) 124 - return err; 125 - } 126 - 175 + /* 176 + * Record the main thread for this comm. Note that the main thread can 177 + * have many "exec" comms because there will be a new one every time it 178 + * exec's. An "exec" comm however will only ever have 1 main thread. 179 + * That is different to any other threads for that same program because 180 + * exec() will effectively kill them, so the relationship between the 181 + * "exec" comm and non-main threads is 1-to-1. That is why 182 + * db_export__comm_thread() is called here for the main thread, but it 183 + * is called for non-main threads when they are exported. 184 + */ 127 185 return db_export__comm_thread(dbe, comm, main_thread); 128 186 } 129 187 ··· 286 340 return 0; 287 341 } 288 342 343 + static int db_export__threads(struct db_export *dbe, struct thread *thread, 344 + struct thread *main_thread, 345 + struct machine *machine, struct comm **comm_ptr) 346 + { 347 + struct comm *comm = NULL; 348 + struct comm *curr_comm; 349 + int err; 350 + 351 + if (main_thread) { 352 + /* 353 + * A thread has a reference to the main thread, so export the 354 + * main thread first. 355 + */ 356 + err = db_export__thread(dbe, main_thread, machine, main_thread); 357 + if (err) 358 + return err; 359 + /* 360 + * Export comm before exporting the non-main thread because 361 + * db_export__comm_thread() can be called further below. 362 + */ 363 + comm = machine__thread_exec_comm(machine, main_thread); 364 + if (comm) { 365 + err = db_export__exec_comm(dbe, comm, main_thread); 366 + if (err) 367 + return err; 368 + *comm_ptr = comm; 369 + } 370 + } 371 + 372 + if (thread != main_thread) { 373 + /* 374 + * For a non-main thread, db_export__comm_thread() must be 375 + * called only if thread has not previously been exported. 376 + */ 377 + bool export_comm_thread = comm && !thread->db_id; 378 + 379 + err = db_export__thread(dbe, thread, machine, main_thread); 380 + if (err) 381 + return err; 382 + 383 + if (export_comm_thread) { 384 + err = db_export__comm_thread(dbe, comm, thread); 385 + if (err) 386 + return err; 387 + } 388 + } 389 + 390 + curr_comm = thread__comm(thread); 391 + if (curr_comm) 392 + return db_export__comm(dbe, curr_comm, thread); 393 + 394 + return 0; 395 + } 396 + 289 397 int db_export__sample(struct db_export *dbe, union perf_event *event, 290 398 struct perf_sample *sample, struct perf_evsel *evsel, 291 399 struct addr_location *al) 292 400 { 293 - struct thread* thread = al->thread; 401 + struct thread *thread = al->thread; 294 402 struct export_sample es = { 295 403 .event = event, 296 404 .sample = sample, ··· 364 364 return err; 365 365 366 366 main_thread = thread__main_thread(al->machine, thread); 367 - if (main_thread) 368 - comm = machine__thread_exec_comm(al->machine, main_thread); 369 367 370 - err = db_export__thread(dbe, thread, al->machine, comm); 368 + err = db_export__threads(dbe, thread, main_thread, al->machine, &comm); 371 369 if (err) 372 370 goto out_put; 373 371 374 - if (comm) { 375 - err = db_export__comm(dbe, comm, main_thread); 376 - if (err) 377 - goto out_put; 372 + if (comm) 378 373 es.comm_db_id = comm->db_id; 379 - } 380 374 381 375 es.db_id = ++dbe->sample_last_db_id; 382 376 ··· 517 523 if (dbe->export_call_return) 518 524 return dbe->export_call_return(dbe, cr); 519 525 526 + return 0; 527 + } 528 + 529 + static int db_export__pid_tid(struct db_export *dbe, struct machine *machine, 530 + pid_t pid, pid_t tid, u64 *db_id, 531 + struct comm **comm_ptr, bool *is_idle) 532 + { 533 + struct thread *thread = machine__find_thread(machine, pid, tid); 534 + struct thread *main_thread; 535 + int err = 0; 536 + 537 + if (!thread || !thread->comm_set) 538 + goto out_put; 539 + 540 + *is_idle = !thread->pid_ && !thread->tid; 541 + 542 + main_thread = thread__main_thread(machine, thread); 543 + 544 + err = db_export__threads(dbe, thread, main_thread, machine, comm_ptr); 545 + 546 + *db_id = thread->db_id; 547 + 548 + thread__put(main_thread); 549 + out_put: 550 + thread__put(thread); 551 + 552 + return err; 553 + } 554 + 555 + int db_export__switch(struct db_export *dbe, union perf_event *event, 556 + struct perf_sample *sample, struct machine *machine) 557 + { 558 + bool out = event->header.misc & PERF_RECORD_MISC_SWITCH_OUT; 559 + bool out_preempt = out && 560 + (event->header.misc & PERF_RECORD_MISC_SWITCH_OUT_PREEMPT); 561 + int flags = out | (out_preempt << 1); 562 + bool is_idle_a = false, is_idle_b = false; 563 + u64 th_a_id = 0, th_b_id = 0; 564 + u64 comm_out_id, comm_in_id; 565 + struct comm *comm_a = NULL; 566 + struct comm *comm_b = NULL; 567 + u64 th_out_id, th_in_id; 568 + u64 db_id; 569 + int err; 570 + 571 + err = db_export__machine(dbe, machine); 572 + if (err) 573 + return err; 574 + 575 + err = db_export__pid_tid(dbe, machine, sample->pid, sample->tid, 576 + &th_a_id, &comm_a, &is_idle_a); 577 + if (err) 578 + return err; 579 + 580 + if (event->header.type == PERF_RECORD_SWITCH_CPU_WIDE) { 581 + pid_t pid = event->context_switch.next_prev_pid; 582 + pid_t tid = event->context_switch.next_prev_tid; 583 + 584 + err = db_export__pid_tid(dbe, machine, pid, tid, &th_b_id, 585 + &comm_b, &is_idle_b); 586 + if (err) 587 + return err; 588 + } 589 + 590 + /* 591 + * Do not export if both threads are unknown (i.e. not being traced), 592 + * or one is unknown and the other is the idle task. 593 + */ 594 + if ((!th_a_id || is_idle_a) && (!th_b_id || is_idle_b)) 595 + return 0; 596 + 597 + db_id = ++dbe->context_switch_last_db_id; 598 + 599 + if (out) { 600 + th_out_id = th_a_id; 601 + th_in_id = th_b_id; 602 + comm_out_id = comm_a ? comm_a->db_id : 0; 603 + comm_in_id = comm_b ? comm_b->db_id : 0; 604 + } else { 605 + th_out_id = th_b_id; 606 + th_in_id = th_a_id; 607 + comm_out_id = comm_b ? comm_b->db_id : 0; 608 + comm_in_id = comm_a ? comm_a->db_id : 0; 609 + } 610 + 611 + if (dbe->export_context_switch) 612 + return dbe->export_context_switch(dbe, db_id, machine, sample, 613 + th_out_id, comm_out_id, 614 + th_in_id, comm_in_id, flags); 520 615 return 0; 521 616 }
+14 -5
tools/perf/util/db-export.h
··· 43 43 int (*export_machine)(struct db_export *dbe, struct machine *machine); 44 44 int (*export_thread)(struct db_export *dbe, struct thread *thread, 45 45 u64 main_thread_db_id, struct machine *machine); 46 - int (*export_comm)(struct db_export *dbe, struct comm *comm); 46 + int (*export_comm)(struct db_export *dbe, struct comm *comm, 47 + struct thread *thread); 47 48 int (*export_comm_thread)(struct db_export *dbe, u64 db_id, 48 49 struct comm *comm, struct thread *thread); 49 50 int (*export_dso)(struct db_export *dbe, struct dso *dso, ··· 57 56 int (*export_call_path)(struct db_export *dbe, struct call_path *cp); 58 57 int (*export_call_return)(struct db_export *dbe, 59 58 struct call_return *cr); 59 + int (*export_context_switch)(struct db_export *dbe, u64 db_id, 60 + struct machine *machine, 61 + struct perf_sample *sample, 62 + u64 th_out_id, u64 comm_out_id, 63 + u64 th_in_id, u64 comm_in_id, int flags); 60 64 struct call_return_processor *crp; 61 65 struct call_path_root *cpr; 62 66 u64 evsel_last_db_id; ··· 74 68 u64 sample_last_db_id; 75 69 u64 call_path_last_db_id; 76 70 u64 call_return_last_db_id; 77 - struct list_head deferred; 71 + u64 context_switch_last_db_id; 78 72 }; 79 73 80 74 int db_export__init(struct db_export *dbe); 81 - int db_export__flush(struct db_export *dbe); 82 75 void db_export__exit(struct db_export *dbe); 83 76 int db_export__evsel(struct db_export *dbe, struct perf_evsel *evsel); 84 77 int db_export__machine(struct db_export *dbe, struct machine *machine); 85 78 int db_export__thread(struct db_export *dbe, struct thread *thread, 86 - struct machine *machine, struct comm *comm); 79 + struct machine *machine, struct thread *main_thread); 87 80 int db_export__comm(struct db_export *dbe, struct comm *comm, 88 - struct thread *main_thread); 81 + struct thread *thread); 82 + int db_export__exec_comm(struct db_export *dbe, struct comm *comm, 83 + struct thread *main_thread); 89 84 int db_export__comm_thread(struct db_export *dbe, struct comm *comm, 90 85 struct thread *thread); 91 86 int db_export__dso(struct db_export *dbe, struct dso *dso, ··· 104 97 int db_export__call_path(struct db_export *dbe, struct call_path *cp); 105 98 int db_export__call_return(struct db_export *dbe, struct call_return *cr, 106 99 u64 *parent_db_id); 100 + int db_export__switch(struct db_export *dbe, union perf_event *event, 101 + struct perf_sample *sample, struct machine *machine); 107 102 108 103 #endif
+29
tools/perf/util/rlimit.c
··· 1 + /* SPDX-License-Identifier: LGPL-2.1 */ 2 + 3 + #include "util/debug.h" 4 + #include "util/rlimit.h" 5 + #include <sys/time.h> 6 + #include <sys/resource.h> 7 + 8 + /* 9 + * Bump the memlock so that we can get bpf maps of a reasonable size, 10 + * like the ones used with 'perf trace' and with 'perf test bpf', 11 + * improve this to some specific request if needed. 12 + */ 13 + void rlimit__bump_memlock(void) 14 + { 15 + struct rlimit rlim; 16 + 17 + if (getrlimit(RLIMIT_MEMLOCK, &rlim) == 0) { 18 + rlim.rlim_cur *= 4; 19 + rlim.rlim_max *= 4; 20 + 21 + if (setrlimit(RLIMIT_MEMLOCK, &rlim) < 0) { 22 + rlim.rlim_cur /= 2; 23 + rlim.rlim_max /= 2; 24 + 25 + if (setrlimit(RLIMIT_MEMLOCK, &rlim) < 0) 26 + pr_debug("Couldn't bump rlimit(MEMLOCK), failures may take place when creating BPF maps, etc\n"); 27 + } 28 + } 29 + }
+6
tools/perf/util/rlimit.h
··· 1 + #ifndef __PERF_RLIMIT_H_ 2 + #define __PERF_RLIMIT_H_ 3 + /* SPDX-License-Identifier: LGPL-2.1 */ 4 + 5 + void rlimit__bump_memlock(void); 6 + #endif // __PERF_RLIMIT_H_
+48 -5
tools/perf/util/scripting-engines/trace-event-python.c
··· 113 113 PyObject *call_path_handler; 114 114 PyObject *call_return_handler; 115 115 PyObject *synth_handler; 116 + PyObject *context_switch_handler; 116 117 bool db_export_mode; 117 118 }; 118 119 ··· 1012 1011 return 0; 1013 1012 } 1014 1013 1015 - static int python_export_comm(struct db_export *dbe, struct comm *comm) 1014 + static int python_export_comm(struct db_export *dbe, struct comm *comm, 1015 + struct thread *thread) 1016 1016 { 1017 1017 struct tables *tables = container_of(dbe, struct tables, dbe); 1018 1018 PyObject *t; 1019 1019 1020 - t = tuple_new(2); 1020 + t = tuple_new(5); 1021 1021 1022 1022 tuple_set_u64(t, 0, comm->db_id); 1023 1023 tuple_set_string(t, 1, comm__str(comm)); 1024 + tuple_set_u64(t, 2, thread->db_id); 1025 + tuple_set_u64(t, 3, comm->start); 1026 + tuple_set_s32(t, 4, comm->exec); 1024 1027 1025 1028 call_object(tables->comm_handler, t, "comm_table"); 1026 1029 ··· 1238 1233 return 0; 1239 1234 } 1240 1235 1236 + static int python_export_context_switch(struct db_export *dbe, u64 db_id, 1237 + struct machine *machine, 1238 + struct perf_sample *sample, 1239 + u64 th_out_id, u64 comm_out_id, 1240 + u64 th_in_id, u64 comm_in_id, int flags) 1241 + { 1242 + struct tables *tables = container_of(dbe, struct tables, dbe); 1243 + PyObject *t; 1244 + 1245 + t = tuple_new(9); 1246 + 1247 + tuple_set_u64(t, 0, db_id); 1248 + tuple_set_u64(t, 1, machine->db_id); 1249 + tuple_set_u64(t, 2, sample->time); 1250 + tuple_set_s32(t, 3, sample->cpu); 1251 + tuple_set_u64(t, 4, th_out_id); 1252 + tuple_set_u64(t, 5, comm_out_id); 1253 + tuple_set_u64(t, 6, th_in_id); 1254 + tuple_set_u64(t, 7, comm_in_id); 1255 + tuple_set_s32(t, 8, flags); 1256 + 1257 + call_object(tables->context_switch_handler, t, "context_switch"); 1258 + 1259 + Py_DECREF(t); 1260 + 1261 + return 0; 1262 + } 1263 + 1241 1264 static int python_process_call_return(struct call_return *cr, u64 *parent_db_id, 1242 1265 void *data) 1243 1266 { ··· 1327 1294 else 1328 1295 python_process_general_event(sample, evsel, al); 1329 1296 } 1297 + } 1298 + 1299 + static void python_process_switch(union perf_event *event, 1300 + struct perf_sample *sample, 1301 + struct machine *machine) 1302 + { 1303 + struct tables *tables = &tables_global; 1304 + 1305 + if (tables->db_export_mode) 1306 + db_export__switch(&tables->dbe, event, sample, machine); 1330 1307 } 1331 1308 1332 1309 static void get_handler_name(char *str, size_t size, ··· 1554 1511 SET_TABLE_HANDLER(sample); 1555 1512 SET_TABLE_HANDLER(call_path); 1556 1513 SET_TABLE_HANDLER(call_return); 1514 + SET_TABLE_HANDLER(context_switch); 1557 1515 1558 1516 /* 1559 1517 * Synthesized events are samples but with architecture-specific data ··· 1664 1620 1665 1621 static int python_flush_script(void) 1666 1622 { 1667 - struct tables *tables = &tables_global; 1668 - 1669 - return db_export__flush(&tables->dbe); 1623 + return 0; 1670 1624 } 1671 1625 1672 1626 /* ··· 1873 1831 .flush_script = python_flush_script, 1874 1832 .stop_script = python_stop_script, 1875 1833 .process_event = python_process_event, 1834 + .process_switch = python_process_switch, 1876 1835 .process_stat = python_process_stat, 1877 1836 .process_stat_interval = python_process_stat_interval, 1878 1837 .generate_script = python_generate_script,
+3
tools/perf/util/trace-event.h
··· 81 81 struct perf_sample *sample, 82 82 struct perf_evsel *evsel, 83 83 struct addr_location *al); 84 + void (*process_switch)(union perf_event *event, 85 + struct perf_sample *sample, 86 + struct machine *machine); 84 87 void (*process_stat)(struct perf_stat_config *config, 85 88 struct perf_evsel *evsel, u64 tstamp); 86 89 void (*process_stat_interval)(u64 tstamp);