~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/perf/scripts/python/export-to-sqlite.py

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 # export-to-sqlite.py: export perf data to a sqlite3 database
  2 # Copyright (c) 2017, Intel Corporation.
  3 #
  4 # This program is free software; you can redistribute it and/or modify it
  5 # under the terms and conditions of the GNU General Public License,
  6 # version 2, as published by the Free Software Foundation.
  7 #
  8 # This program is distributed in the hope it will be useful, but WITHOUT
  9 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 10 # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 11 # more details.
 12 
 13 from __future__ import print_function
 14 
 15 import os
 16 import sys
 17 import struct
 18 import datetime
 19 
 20 # To use this script you will need to have installed package python-pyside which
 21 # provides LGPL-licensed Python bindings for Qt.  You will also need the package
 22 # libqt4-sql-sqlite for Qt sqlite3 support.
 23 #
 24 # Examples of installing pyside:
 25 #
 26 # ubuntu:
 27 #
 28 #       $ sudo apt-get install python-pyside.qtsql libqt4-sql-psql
 29 #
 30 #       Alternately, to use Python3 and/or pyside 2, one of the following:
 31 #
 32 #               $ sudo apt-get install python3-pyside.qtsql libqt4-sql-psql
 33 #               $ sudo apt-get install python-pyside2.qtsql libqt5sql5-psql
 34 #               $ sudo apt-get install python3-pyside2.qtsql libqt5sql5-psql
 35 # fedora:
 36 #
 37 #       $ sudo yum install python-pyside
 38 #
 39 #       Alternately, to use Python3 and/or pyside 2, one of the following:
 40 #               $ sudo yum install python3-pyside
 41 #               $ pip install --user PySide2
 42 #               $ pip3 install --user PySide2
 43 #
 44 # An example of using this script with Intel PT:
 45 #
 46 #       $ perf record -e intel_pt//u ls
 47 #       $ perf script -s ~/libexec/perf-core/scripts/python/export-to-sqlite.py pt_example branches calls
 48 #       2017-07-31 14:26:07.326913 Creating database...
 49 #       2017-07-31 14:26:07.538097 Writing records...
 50 #       2017-07-31 14:26:09.889292 Adding indexes
 51 #       2017-07-31 14:26:09.958746 Done
 52 #
 53 # To browse the database, sqlite3 can be used e.g.
 54 #
 55 #       $ sqlite3 pt_example
 56 #       sqlite> .header on
 57 #       sqlite> select * from samples_view where id < 10;
 58 #       sqlite> .mode column
 59 #       sqlite> select * from samples_view where id < 10;
 60 #       sqlite> .tables
 61 #       sqlite> .schema samples_view
 62 #       sqlite> .quit
 63 #
 64 # An example of using the database is provided by the script
 65 # exported-sql-viewer.py.  Refer to that script for details.
 66 #
 67 # The database structure is practically the same as created by the script
 68 # export-to-postgresql.py. Refer to that script for details.  A notable
 69 # difference is  the 'transaction' column of the 'samples' table which is
 70 # renamed 'transaction_' in sqlite because 'transaction' is a reserved word.
 71 
 72 pyside_version_1 = True
 73 if not "pyside-version-1" in sys.argv:
 74         try:
 75                 from PySide2.QtSql import *
 76                 pyside_version_1 = False
 77         except:
 78                 pass
 79 
 80 if pyside_version_1:
 81         from PySide.QtSql import *
 82 
 83 sys.path.append(os.environ['PERF_EXEC_PATH'] + \
 84         '/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
 85 
 86 # These perf imports are not used at present
 87 #from perf_trace_context import *
 88 #from Core import *
 89 
 90 perf_db_export_mode = True
 91 perf_db_export_calls = False
 92 perf_db_export_callchains = False
 93 
 94 def printerr(*args, **keyword_args):
 95         print(*args, file=sys.stderr, **keyword_args)
 96 
 97 def printdate(*args, **kw_args):
 98         print(datetime.datetime.today(), *args, sep=' ', **kw_args)
 99 
100 def usage():
101         printerr("Usage is: export-to-sqlite.py <database name> [<columns>] [<calls>] [<callchains>] [<pyside-version-1>]");
102         printerr("where:  columns            'all' or 'branches'");
103         printerr("        calls              'calls' => create calls and call_paths table");
104         printerr("        callchains         'callchains' => create call_paths table");
105         printerr("        pyside-version-1   'pyside-version-1' => use pyside version 1");
106         raise Exception("Too few or bad arguments")
107 
108 if (len(sys.argv) < 2):
109         usage()
110 
111 dbname = sys.argv[1]
112 
113 if (len(sys.argv) >= 3):
114         columns = sys.argv[2]
115 else:
116         columns = "all"
117 
118 if columns not in ("all", "branches"):
119         usage()
120 
121 branches = (columns == "branches")
122 
123 for i in range(3,len(sys.argv)):
124         if (sys.argv[i] == "calls"):
125                 perf_db_export_calls = True
126         elif (sys.argv[i] == "callchains"):
127                 perf_db_export_callchains = True
128         elif (sys.argv[i] == "pyside-version-1"):
129                 pass
130         else:
131                 usage()
132 
133 def do_query(q, s):
134         if (q.exec_(s)):
135                 return
136         raise Exception("Query failed: " + q.lastError().text())
137 
138 def do_query_(q):
139         if (q.exec_()):
140                 return
141         raise Exception("Query failed: " + q.lastError().text())
142 
143 printdate("Creating database ...")
144 
145 db_exists = False
146 try:
147         f = open(dbname)
148         f.close()
149         db_exists = True
150 except:
151         pass
152 
153 if db_exists:
154         raise Exception(dbname + " already exists")
155 
156 db = QSqlDatabase.addDatabase('QSQLITE')
157 db.setDatabaseName(dbname)
158 db.open()
159 
160 query = QSqlQuery(db)
161 
162 do_query(query, 'PRAGMA journal_mode = OFF')
163 do_query(query, 'BEGIN TRANSACTION')
164 
165 do_query(query, 'CREATE TABLE selected_events ('
166                 'id             integer         NOT NULL        PRIMARY KEY,'
167                 'name           varchar(80))')
168 do_query(query, 'CREATE TABLE machines ('
169                 'id             integer         NOT NULL        PRIMARY KEY,'
170                 'pid            integer,'
171                 'root_dir       varchar(4096))')
172 do_query(query, 'CREATE TABLE threads ('
173                 'id             integer         NOT NULL        PRIMARY KEY,'
174                 'machine_id     bigint,'
175                 'process_id     bigint,'
176                 'pid            integer,'
177                 'tid            integer)')
178 do_query(query, 'CREATE TABLE comms ('
179                 'id             integer         NOT NULL        PRIMARY KEY,'
180                 'comm           varchar(16),'
181                 'c_thread_id    bigint,'
182                 'c_time         bigint,'
183                 'exec_flag      boolean)')
184 do_query(query, 'CREATE TABLE comm_threads ('
185                 'id             integer         NOT NULL        PRIMARY KEY,'
186                 'comm_id        bigint,'
187                 'thread_id      bigint)')
188 do_query(query, 'CREATE TABLE dsos ('
189                 'id             integer         NOT NULL        PRIMARY KEY,'
190                 'machine_id     bigint,'
191                 'short_name     varchar(256),'
192                 'long_name      varchar(4096),'
193                 'build_id       varchar(64))')
194 do_query(query, 'CREATE TABLE symbols ('
195                 'id             integer         NOT NULL        PRIMARY KEY,'
196                 'dso_id         bigint,'
197                 'sym_start      bigint,'
198                 'sym_end        bigint,'
199                 'binding        integer,'
200                 'name           varchar(2048))')
201 do_query(query, 'CREATE TABLE branch_types ('
202                 'id             integer         NOT NULL        PRIMARY KEY,'
203                 'name           varchar(80))')
204 
205 if branches:
206         do_query(query, 'CREATE TABLE samples ('
207                 'id             integer         NOT NULL        PRIMARY KEY,'
208                 'evsel_id       bigint,'
209                 'machine_id     bigint,'
210                 'thread_id      bigint,'
211                 'comm_id        bigint,'
212                 'dso_id         bigint,'
213                 'symbol_id      bigint,'
214                 'sym_offset     bigint,'
215                 'ip             bigint,'
216                 'time           bigint,'
217                 'cpu            integer,'
218                 'to_dso_id      bigint,'
219                 'to_symbol_id   bigint,'
220                 'to_sym_offset  bigint,'
221                 'to_ip          bigint,'
222                 'branch_type    integer,'
223                 'in_tx          boolean,'
224                 'call_path_id   bigint,'
225                 'insn_count     bigint,'
226                 'cyc_count      bigint,'
227                 'flags          integer)')
228 else:
229         do_query(query, 'CREATE TABLE samples ('
230                 'id             integer         NOT NULL        PRIMARY KEY,'
231                 'evsel_id       bigint,'
232                 'machine_id     bigint,'
233                 'thread_id      bigint,'
234                 'comm_id        bigint,'
235                 'dso_id         bigint,'
236                 'symbol_id      bigint,'
237                 'sym_offset     bigint,'
238                 'ip             bigint,'
239                 'time           bigint,'
240                 'cpu            integer,'
241                 'to_dso_id      bigint,'
242                 'to_symbol_id   bigint,'
243                 'to_sym_offset  bigint,'
244                 'to_ip          bigint,'
245                 'period         bigint,'
246                 'weight         bigint,'
247                 'transaction_   bigint,'
248                 'data_src       bigint,'
249                 'branch_type    integer,'
250                 'in_tx          boolean,'
251                 'call_path_id   bigint,'
252                 'insn_count     bigint,'
253                 'cyc_count      bigint,'
254                 'flags          integer)')
255 
256 if perf_db_export_calls or perf_db_export_callchains:
257         do_query(query, 'CREATE TABLE call_paths ('
258                 'id             integer         NOT NULL        PRIMARY KEY,'
259                 'parent_id      bigint,'
260                 'symbol_id      bigint,'
261                 'ip             bigint)')
262 if perf_db_export_calls:
263         do_query(query, 'CREATE TABLE calls ('
264                 'id             integer         NOT NULL        PRIMARY KEY,'
265                 'thread_id      bigint,'
266                 'comm_id        bigint,'
267                 'call_path_id   bigint,'
268                 'call_time      bigint,'
269                 'return_time    bigint,'
270                 'branch_count   bigint,'
271                 'call_id        bigint,'
272                 'return_id      bigint,'
273                 'parent_call_path_id    bigint,'
274                 'flags          integer,'
275                 'parent_id      bigint,'
276                 'insn_count     bigint,'
277                 'cyc_count      bigint)')
278 
279 do_query(query, 'CREATE TABLE ptwrite ('
280                 'id             integer         NOT NULL        PRIMARY KEY,'
281                 'payload        bigint,'
282                 'exact_ip       integer)')
283 
284 do_query(query, 'CREATE TABLE cbr ('
285                 'id             integer         NOT NULL        PRIMARY KEY,'
286                 'cbr            integer,'
287                 'mhz            integer,'
288                 'percent        integer)')
289 
290 do_query(query, 'CREATE TABLE mwait ('
291                 'id             integer         NOT NULL        PRIMARY KEY,'
292                 'hints          integer,'
293                 'extensions     integer)')
294 
295 do_query(query, 'CREATE TABLE pwre ('
296                 'id             integer         NOT NULL        PRIMARY KEY,'
297                 'cstate         integer,'
298                 'subcstate      integer,'
299                 'hw             integer)')
300 
301 do_query(query, 'CREATE TABLE exstop ('
302                 'id             integer         NOT NULL        PRIMARY KEY,'
303                 'exact_ip       integer)')
304 
305 do_query(query, 'CREATE TABLE pwrx ('
306                 'id             integer         NOT NULL        PRIMARY KEY,'
307                 'deepest_cstate integer,'
308                 'last_cstate    integer,'
309                 'wake_reason    integer)')
310 
311 do_query(query, 'CREATE TABLE context_switches ('
312                 'id             integer         NOT NULL        PRIMARY KEY,'
313                 'machine_id     bigint,'
314                 'time           bigint,'
315                 'cpu            integer,'
316                 'thread_out_id  bigint,'
317                 'comm_out_id    bigint,'
318                 'thread_in_id   bigint,'
319                 'comm_in_id     bigint,'
320                 'flags          integer)')
321 
322 # printf was added to sqlite in version 3.8.3
323 sqlite_has_printf = False
324 try:
325         do_query(query, 'SELECT printf("") FROM machines')
326         sqlite_has_printf = True
327 except:
328         pass
329 
330 def emit_to_hex(x):
331         if sqlite_has_printf:
332                 return 'printf("%x", ' + x + ')'
333         else:
334                 return x
335 
336 do_query(query, 'CREATE VIEW machines_view AS '
337         'SELECT '
338                 'id,'
339                 'pid,'
340                 'root_dir,'
341                 'CASE WHEN id=0 THEN \'unknown\' WHEN pid=-1 THEN \'host\' ELSE \'guest\' END AS host_or_guest'
342         ' FROM machines')
343 
344 do_query(query, 'CREATE VIEW dsos_view AS '
345         'SELECT '
346                 'id,'
347                 'machine_id,'
348                 '(SELECT host_or_guest FROM machines_view WHERE id = machine_id) AS host_or_guest,'
349                 'short_name,'
350                 'long_name,'
351                 'build_id'
352         ' FROM dsos')
353 
354 do_query(query, 'CREATE VIEW symbols_view AS '
355         'SELECT '
356                 'id,'
357                 'name,'
358                 '(SELECT short_name FROM dsos WHERE id=dso_id) AS dso,'
359                 'dso_id,'
360                 'sym_start,'
361                 'sym_end,'
362                 'CASE WHEN binding=0 THEN \'local\' WHEN binding=1 THEN \'global\' ELSE \'weak\' END AS binding'
363         ' FROM symbols')
364 
365 do_query(query, 'CREATE VIEW threads_view AS '
366         'SELECT '
367                 'id,'
368                 'machine_id,'
369                 '(SELECT host_or_guest FROM machines_view WHERE id = machine_id) AS host_or_guest,'
370                 'process_id,'
371                 'pid,'
372                 'tid'
373         ' FROM threads')
374 
375 do_query(query, 'CREATE VIEW comm_threads_view AS '
376         'SELECT '
377                 'comm_id,'
378                 '(SELECT comm FROM comms WHERE id = comm_id) AS command,'
379                 'thread_id,'
380                 '(SELECT pid FROM threads WHERE id = thread_id) AS pid,'
381                 '(SELECT tid FROM threads WHERE id = thread_id) AS tid'
382         ' FROM comm_threads')
383 
384 if perf_db_export_calls or perf_db_export_callchains:
385         do_query(query, 'CREATE VIEW call_paths_view AS '
386                 'SELECT '
387                         'c.id,'
388                         + emit_to_hex('c.ip') + ' AS ip,'
389                         'c.symbol_id,'
390                         '(SELECT name FROM symbols WHERE id = c.symbol_id) AS symbol,'
391                         '(SELECT dso_id FROM symbols WHERE id = c.symbol_id) AS dso_id,'
392                         '(SELECT dso FROM symbols_view  WHERE id = c.symbol_id) AS dso_short_name,'
393                         'c.parent_id,'
394                         + emit_to_hex('p.ip') + ' AS parent_ip,'
395                         'p.symbol_id AS parent_symbol_id,'
396                         '(SELECT name FROM symbols WHERE id = p.symbol_id) AS parent_symbol,'
397                         '(SELECT dso_id FROM symbols WHERE id = p.symbol_id) AS parent_dso_id,'
398                         '(SELECT dso FROM symbols_view  WHERE id = p.symbol_id) AS parent_dso_short_name'
399                 ' FROM call_paths c INNER JOIN call_paths p ON p.id = c.parent_id')
400 if perf_db_export_calls:
401         do_query(query, 'CREATE VIEW calls_view AS '
402                 'SELECT '
403                         'calls.id,'
404                         'thread_id,'
405                         '(SELECT pid FROM threads WHERE id = thread_id) AS pid,'
406                         '(SELECT tid FROM threads WHERE id = thread_id) AS tid,'
407                         '(SELECT comm FROM comms WHERE id = comm_id) AS command,'
408                         'call_path_id,'
409                         + emit_to_hex('ip') + ' AS ip,'
410                         'symbol_id,'
411                         '(SELECT name FROM symbols WHERE id = symbol_id) AS symbol,'
412                         'call_time,'
413                         'return_time,'
414                         'return_time - call_time AS elapsed_time,'
415                         'branch_count,'
416                         'insn_count,'
417                         'cyc_count,'
418                         'CASE WHEN cyc_count=0 THEN CAST(0 AS FLOAT) ELSE ROUND(CAST(insn_count AS FLOAT) / cyc_count, 2) END AS IPC,'
419                         'call_id,'
420                         'return_id,'
421                         'CASE WHEN flags=0 THEN \'\' WHEN flags=1 THEN \'no call\' WHEN flags=2 THEN \'no return\' WHEN flags=3 THEN \'no call/return\' WHEN flags=6 THEN \'jump\' ELSE flags END AS flags,'
422                         'parent_call_path_id,'
423                         'calls.parent_id'
424                 ' FROM calls INNER JOIN call_paths ON call_paths.id = call_path_id')
425 
426 do_query(query, 'CREATE VIEW samples_view AS '
427         'SELECT '
428                 'id,'
429                 'time,'
430                 'cpu,'
431                 '(SELECT pid FROM threads WHERE id = thread_id) AS pid,'
432                 '(SELECT tid FROM threads WHERE id = thread_id) AS tid,'
433                 '(SELECT comm FROM comms WHERE id = comm_id) AS command,'
434                 '(SELECT name FROM selected_events WHERE id = evsel_id) AS event,'
435                 + emit_to_hex('ip') + ' AS ip_hex,'
436                 '(SELECT name FROM symbols WHERE id = symbol_id) AS symbol,'
437                 'sym_offset,'
438                 '(SELECT short_name FROM dsos WHERE id = dso_id) AS dso_short_name,'
439                 + emit_to_hex('to_ip') + ' AS to_ip_hex,'
440                 '(SELECT name FROM symbols WHERE id = to_symbol_id) AS to_symbol,'
441                 'to_sym_offset,'
442                 '(SELECT short_name FROM dsos WHERE id = to_dso_id) AS to_dso_short_name,'
443                 '(SELECT name FROM branch_types WHERE id = branch_type) AS branch_type_name,'
444                 'in_tx,'
445                 'insn_count,'
446                 'cyc_count,'
447                 'CASE WHEN cyc_count=0 THEN CAST(0 AS FLOAT) ELSE ROUND(CAST(insn_count AS FLOAT) / cyc_count, 2) END AS IPC,'
448                 'flags'
449         ' FROM samples')
450 
451 do_query(query, 'CREATE VIEW ptwrite_view AS '
452         'SELECT '
453                 'ptwrite.id,'
454                 'time,'
455                 'cpu,'
456                 + emit_to_hex('payload') + ' AS payload_hex,'
457                 'CASE WHEN exact_ip=0 THEN \'False\' ELSE \'True\' END AS exact_ip'
458         ' FROM ptwrite'
459         ' INNER JOIN samples ON samples.id = ptwrite.id')
460 
461 do_query(query, 'CREATE VIEW cbr_view AS '
462         'SELECT '
463                 'cbr.id,'
464                 'time,'
465                 'cpu,'
466                 'cbr,'
467                 'mhz,'
468                 'percent'
469         ' FROM cbr'
470         ' INNER JOIN samples ON samples.id = cbr.id')
471 
472 do_query(query, 'CREATE VIEW mwait_view AS '
473         'SELECT '
474                 'mwait.id,'
475                 'time,'
476                 'cpu,'
477                 + emit_to_hex('hints') + ' AS hints_hex,'
478                 + emit_to_hex('extensions') + ' AS extensions_hex'
479         ' FROM mwait'
480         ' INNER JOIN samples ON samples.id = mwait.id')
481 
482 do_query(query, 'CREATE VIEW pwre_view AS '
483         'SELECT '
484                 'pwre.id,'
485                 'time,'
486                 'cpu,'
487                 'cstate,'
488                 'subcstate,'
489                 'CASE WHEN hw=0 THEN \'False\' ELSE \'True\' END AS hw'
490         ' FROM pwre'
491         ' INNER JOIN samples ON samples.id = pwre.id')
492 
493 do_query(query, 'CREATE VIEW exstop_view AS '
494         'SELECT '
495                 'exstop.id,'
496                 'time,'
497                 'cpu,'
498                 'CASE WHEN exact_ip=0 THEN \'False\' ELSE \'True\' END AS exact_ip'
499         ' FROM exstop'
500         ' INNER JOIN samples ON samples.id = exstop.id')
501 
502 do_query(query, 'CREATE VIEW pwrx_view AS '
503         'SELECT '
504                 'pwrx.id,'
505                 'time,'
506                 'cpu,'
507                 'deepest_cstate,'
508                 'last_cstate,'
509                 'CASE     WHEN wake_reason=1 THEN \'Interrupt\''
510                         ' WHEN wake_reason=2 THEN \'Timer Deadline\''
511                         ' WHEN wake_reason=4 THEN \'Monitored Address\''
512                         ' WHEN wake_reason=8 THEN \'HW\''
513                         ' ELSE wake_reason '
514                 'END AS wake_reason'
515         ' FROM pwrx'
516         ' INNER JOIN samples ON samples.id = pwrx.id')
517 
518 do_query(query, 'CREATE VIEW power_events_view AS '
519         'SELECT '
520                 'samples.id,'
521                 'time,'
522                 'cpu,'
523                 'selected_events.name AS event,'
524                 'CASE WHEN selected_events.name=\'cbr\' THEN (SELECT cbr FROM cbr WHERE cbr.id = samples.id) ELSE "" END AS cbr,'
525                 'CASE WHEN selected_events.name=\'cbr\' THEN (SELECT mhz FROM cbr WHERE cbr.id = samples.id) ELSE "" END AS mhz,'
526                 'CASE WHEN selected_events.name=\'cbr\' THEN (SELECT percent FROM cbr WHERE cbr.id = samples.id) ELSE "" END AS percent,'
527                 'CASE WHEN selected_events.name=\'mwait\' THEN (SELECT ' + emit_to_hex('hints') + ' FROM mwait WHERE mwait.id = samples.id) ELSE "" END AS hints_hex,'
528                 'CASE WHEN selected_events.name=\'mwait\' THEN (SELECT ' + emit_to_hex('extensions') + ' FROM mwait WHERE mwait.id = samples.id) ELSE "" END AS extensions_hex,'
529                 'CASE WHEN selected_events.name=\'pwre\' THEN (SELECT cstate FROM pwre WHERE pwre.id = samples.id) ELSE "" END AS cstate,'
530                 'CASE WHEN selected_events.name=\'pwre\' THEN (SELECT subcstate FROM pwre WHERE pwre.id = samples.id) ELSE "" END AS subcstate,'
531                 'CASE WHEN selected_events.name=\'pwre\' THEN (SELECT hw FROM pwre WHERE pwre.id = samples.id) ELSE "" END AS hw,'
532                 'CASE WHEN selected_events.name=\'exstop\' THEN (SELECT exact_ip FROM exstop WHERE exstop.id = samples.id) ELSE "" END AS exact_ip,'
533                 'CASE WHEN selected_events.name=\'pwrx\' THEN (SELECT deepest_cstate FROM pwrx WHERE pwrx.id = samples.id) ELSE "" END AS deepest_cstate,'
534                 'CASE WHEN selected_events.name=\'pwrx\' THEN (SELECT last_cstate FROM pwrx WHERE pwrx.id = samples.id) ELSE "" END AS last_cstate,'
535                 'CASE WHEN selected_events.name=\'pwrx\' THEN (SELECT '
536                         'CASE     WHEN wake_reason=1 THEN \'Interrupt\''
537                                 ' WHEN wake_reason=2 THEN \'Timer Deadline\''
538                                 ' WHEN wake_reason=4 THEN \'Monitored Address\''
539                                 ' WHEN wake_reason=8 THEN \'HW\''
540                                 ' ELSE wake_reason '
541                         'END'
542                 ' FROM pwrx WHERE pwrx.id = samples.id) ELSE "" END AS wake_reason'
543         ' FROM samples'
544         ' INNER JOIN selected_events ON selected_events.id = evsel_id'
545         ' WHERE selected_events.name IN (\'cbr\',\'mwait\',\'exstop\',\'pwre\',\'pwrx\')')
546 
547 do_query(query, 'CREATE VIEW context_switches_view AS '
548         'SELECT '
549                 'context_switches.id,'
550                 'context_switches.machine_id,'
551                 'context_switches.time,'
552                 'context_switches.cpu,'
553                 'th_out.pid AS pid_out,'
554                 'th_out.tid AS tid_out,'
555                 'comm_out.comm AS comm_out,'
556                 'th_in.pid AS pid_in,'
557                 'th_in.tid AS tid_in,'
558                 'comm_in.comm AS comm_in,'
559                 'CASE     WHEN context_switches.flags = 0 THEN \'in\''
560                         ' WHEN context_switches.flags = 1 THEN \'out\''
561                         ' WHEN context_switches.flags = 3 THEN \'out preempt\''
562                         ' ELSE context_switches.flags '
563                 'END AS flags'
564         ' FROM context_switches'
565         ' INNER JOIN threads AS th_out ON th_out.id   = context_switches.thread_out_id'
566         ' INNER JOIN threads AS th_in  ON th_in.id    = context_switches.thread_in_id'
567         ' INNER JOIN comms AS comm_out ON comm_out.id = context_switches.comm_out_id'
568         ' INNER JOIN comms AS comm_in  ON comm_in.id  = context_switches.comm_in_id')
569 
570 do_query(query, 'END TRANSACTION')
571 
572 evsel_query = QSqlQuery(db)
573 evsel_query.prepare("INSERT INTO selected_events VALUES (?, ?)")
574 machine_query = QSqlQuery(db)
575 machine_query.prepare("INSERT INTO machines VALUES (?, ?, ?)")
576 thread_query = QSqlQuery(db)
577 thread_query.prepare("INSERT INTO threads VALUES (?, ?, ?, ?, ?)")
578 comm_query = QSqlQuery(db)
579 comm_query.prepare("INSERT INTO comms VALUES (?, ?, ?, ?, ?)")
580 comm_thread_query = QSqlQuery(db)
581 comm_thread_query.prepare("INSERT INTO comm_threads VALUES (?, ?, ?)")
582 dso_query = QSqlQuery(db)
583 dso_query.prepare("INSERT INTO dsos VALUES (?, ?, ?, ?, ?)")
584 symbol_query = QSqlQuery(db)
585 symbol_query.prepare("INSERT INTO symbols VALUES (?, ?, ?, ?, ?, ?)")
586 branch_type_query = QSqlQuery(db)
587 branch_type_query.prepare("INSERT INTO branch_types VALUES (?, ?)")
588 sample_query = QSqlQuery(db)
589 if branches:
590         sample_query.prepare("INSERT INTO samples VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
591 else:
592         sample_query.prepare("INSERT INTO samples VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
593 if perf_db_export_calls or perf_db_export_callchains:
594         call_path_query = QSqlQuery(db)
595         call_path_query.prepare("INSERT INTO call_paths VALUES (?, ?, ?, ?)")
596 if perf_db_export_calls:
597         call_query = QSqlQuery(db)
598         call_query.prepare("INSERT INTO calls VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
599 ptwrite_query = QSqlQuery(db)
600 ptwrite_query.prepare("INSERT INTO ptwrite VALUES (?, ?, ?)")
601 cbr_query = QSqlQuery(db)
602 cbr_query.prepare("INSERT INTO cbr VALUES (?, ?, ?, ?)")
603 mwait_query = QSqlQuery(db)
604 mwait_query.prepare("INSERT INTO mwait VALUES (?, ?, ?)")
605 pwre_query = QSqlQuery(db)
606 pwre_query.prepare("INSERT INTO pwre VALUES (?, ?, ?, ?)")
607 exstop_query = QSqlQuery(db)
608 exstop_query.prepare("INSERT INTO exstop VALUES (?, ?)")
609 pwrx_query = QSqlQuery(db)
610 pwrx_query.prepare("INSERT INTO pwrx VALUES (?, ?, ?, ?)")
611 context_switch_query = QSqlQuery(db)
612 context_switch_query.prepare("INSERT INTO context_switches VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)")
613 
614 def trace_begin():
615         printdate("Writing records...")
616         do_query(query, 'BEGIN TRANSACTION')
617         # id == 0 means unknown.  It is easier to create records for them than replace the zeroes with NULLs
618         evsel_table(0, "unknown")
619         machine_table(0, 0, "unknown")
620         thread_table(0, 0, 0, -1, -1)
621         comm_table(0, "unknown", 0, 0, 0)
622         dso_table(0, 0, "unknown", "unknown", "")
623         symbol_table(0, 0, 0, 0, 0, "unknown")
624         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, 0)
625         if perf_db_export_calls or perf_db_export_callchains:
626                 call_path_table(0, 0, 0, 0)
627                 call_return_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
628 
629 unhandled_count = 0
630 
631 def is_table_empty(table_name):
632         do_query(query, 'SELECT * FROM ' + table_name + ' LIMIT 1');
633         if query.next():
634                 return False
635         return True
636 
637 def drop(table_name):
638         do_query(query, 'DROP VIEW ' + table_name + '_view');
639         do_query(query, 'DROP TABLE ' + table_name);
640 
641 def trace_end():
642         do_query(query, 'END TRANSACTION')
643 
644         printdate("Adding indexes")
645         if perf_db_export_calls:
646                 do_query(query, 'CREATE INDEX pcpid_idx ON calls (parent_call_path_id)')
647                 do_query(query, 'CREATE INDEX pid_idx ON calls (parent_id)')
648                 do_query(query, 'ALTER TABLE comms ADD has_calls boolean')
649                 do_query(query, 'UPDATE comms SET has_calls = 1 WHERE comms.id IN (SELECT DISTINCT comm_id FROM calls)')
650 
651         printdate("Dropping unused tables")
652         if is_table_empty("ptwrite"):
653                 drop("ptwrite")
654         if is_table_empty("mwait") and is_table_empty("pwre") and is_table_empty("exstop") and is_table_empty("pwrx"):
655                 do_query(query, 'DROP VIEW power_events_view');
656                 drop("mwait")
657                 drop("pwre")
658                 drop("exstop")
659                 drop("pwrx")
660                 if is_table_empty("cbr"):
661                         drop("cbr")
662         if is_table_empty("context_switches"):
663                 drop("context_switches")
664 
665         if (unhandled_count):
666                 printdate("Warning: ", unhandled_count, " unhandled events")
667         printdate("Done")
668 
669 def trace_unhandled(event_name, context, event_fields_dict):
670         global unhandled_count
671         unhandled_count += 1
672 
673 def sched__sched_switch(*x):
674         pass
675 
676 def bind_exec(q, n, x):
677         for xx in x[0:n]:
678                 q.addBindValue(str(xx))
679         do_query_(q)
680 
681 def evsel_table(*x):
682         bind_exec(evsel_query, 2, x)
683 
684 def machine_table(*x):
685         bind_exec(machine_query, 3, x)
686 
687 def thread_table(*x):
688         bind_exec(thread_query, 5, x)
689 
690 def comm_table(*x):
691         bind_exec(comm_query, 5, x)
692 
693 def comm_thread_table(*x):
694         bind_exec(comm_thread_query, 3, x)
695 
696 def dso_table(*x):
697         bind_exec(dso_query, 5, x)
698 
699 def symbol_table(*x):
700         bind_exec(symbol_query, 6, x)
701 
702 def branch_type_table(*x):
703         bind_exec(branch_type_query, 2, x)
704 
705 def sample_table(*x):
706         if branches:
707                 for xx in x[0:15]:
708                         sample_query.addBindValue(str(xx))
709                 for xx in x[19:25]:
710                         sample_query.addBindValue(str(xx))
711                 do_query_(sample_query)
712         else:
713                 bind_exec(sample_query, 25, x)
714 
715 def call_path_table(*x):
716         bind_exec(call_path_query, 4, x)
717 
718 def call_return_table(*x):
719         bind_exec(call_query, 14, x)
720 
721 def ptwrite(id, raw_buf):
722         data = struct.unpack_from("<IQ", raw_buf)
723         flags = data[0]
724         payload = data[1]
725         exact_ip = flags & 1
726         ptwrite_query.addBindValue(str(id))
727         ptwrite_query.addBindValue(str(payload))
728         ptwrite_query.addBindValue(str(exact_ip))
729         do_query_(ptwrite_query)
730 
731 def cbr(id, raw_buf):
732         data = struct.unpack_from("<BBBBII", raw_buf)
733         cbr = data[0]
734         MHz = (data[4] + 500) / 1000
735         percent = ((cbr * 1000 / data[2]) + 5) / 10
736         cbr_query.addBindValue(str(id))
737         cbr_query.addBindValue(str(cbr))
738         cbr_query.addBindValue(str(MHz))
739         cbr_query.addBindValue(str(percent))
740         do_query_(cbr_query)
741 
742 def mwait(id, raw_buf):
743         data = struct.unpack_from("<IQ", raw_buf)
744         payload = data[1]
745         hints = payload & 0xff
746         extensions = (payload >> 32) & 0x3
747         mwait_query.addBindValue(str(id))
748         mwait_query.addBindValue(str(hints))
749         mwait_query.addBindValue(str(extensions))
750         do_query_(mwait_query)
751 
752 def pwre(id, raw_buf):
753         data = struct.unpack_from("<IQ", raw_buf)
754         payload = data[1]
755         hw = (payload >> 7) & 1
756         cstate = (payload >> 12) & 0xf
757         subcstate = (payload >> 8) & 0xf
758         pwre_query.addBindValue(str(id))
759         pwre_query.addBindValue(str(cstate))
760         pwre_query.addBindValue(str(subcstate))
761         pwre_query.addBindValue(str(hw))
762         do_query_(pwre_query)
763 
764 def exstop(id, raw_buf):
765         data = struct.unpack_from("<I", raw_buf)
766         flags = data[0]
767         exact_ip = flags & 1
768         exstop_query.addBindValue(str(id))
769         exstop_query.addBindValue(str(exact_ip))
770         do_query_(exstop_query)
771 
772 def pwrx(id, raw_buf):
773         data = struct.unpack_from("<IQ", raw_buf)
774         payload = data[1]
775         deepest_cstate = payload & 0xf
776         last_cstate = (payload >> 4) & 0xf
777         wake_reason = (payload >> 8) & 0xf
778         pwrx_query.addBindValue(str(id))
779         pwrx_query.addBindValue(str(deepest_cstate))
780         pwrx_query.addBindValue(str(last_cstate))
781         pwrx_query.addBindValue(str(wake_reason))
782         do_query_(pwrx_query)
783 
784 def synth_data(id, config, raw_buf, *x):
785         if config == 0:
786                 ptwrite(id, raw_buf)
787         elif config == 1:
788                 mwait(id, raw_buf)
789         elif config == 2:
790                 pwre(id, raw_buf)
791         elif config == 3:
792                 exstop(id, raw_buf)
793         elif config == 4:
794                 pwrx(id, raw_buf)
795         elif config == 5:
796                 cbr(id, raw_buf)
797 
798 def context_switch_table(*x):
799         bind_exec(context_switch_query, 9, x)

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php