disk_parser.js revision 4849cead45edf85cf2a61526c0b716eb637f74ba
14849cead45edf85cf2a61526c0b716eb637f74baJeff Brown// Copyright (c) 2013 The Chromium Authors. All rights reserved. 24849cead45edf85cf2a61526c0b716eb637f74baJeff Brown// Use of this source code is governed by a BSD-style license that can be 34849cead45edf85cf2a61526c0b716eb637f74baJeff Brown// found in the LICENSE file. 44849cead45edf85cf2a61526c0b716eb637f74baJeff Brown 54849cead45edf85cf2a61526c0b716eb637f74baJeff Brown/** 64849cead45edf85cf2a61526c0b716eb637f74baJeff Brown * @fileoverview Parses filesystem and block device events in the Linux event 74849cead45edf85cf2a61526c0b716eb637f74baJeff Brown * trace format. 84849cead45edf85cf2a61526c0b716eb637f74baJeff Brown */ 94849cead45edf85cf2a61526c0b716eb637f74baJeff Brownbase.require('importer.linux_perf.parser'); 104849cead45edf85cf2a61526c0b716eb637f74baJeff Brownbase.exportTo('tracing.importer.linux_perf', function() { 114849cead45edf85cf2a61526c0b716eb637f74baJeff Brown 124849cead45edf85cf2a61526c0b716eb637f74baJeff Brown var Parser = tracing.importer.linux_perf.Parser; 134849cead45edf85cf2a61526c0b716eb637f74baJeff Brown 144849cead45edf85cf2a61526c0b716eb637f74baJeff Brown /** 154849cead45edf85cf2a61526c0b716eb637f74baJeff Brown * Parses linux filesystem and block device trace events. 164849cead45edf85cf2a61526c0b716eb637f74baJeff Brown * @constructor 174849cead45edf85cf2a61526c0b716eb637f74baJeff Brown */ 184849cead45edf85cf2a61526c0b716eb637f74baJeff Brown function DiskParser(importer) { 194849cead45edf85cf2a61526c0b716eb637f74baJeff Brown Parser.call(this, importer); 204849cead45edf85cf2a61526c0b716eb637f74baJeff Brown 214849cead45edf85cf2a61526c0b716eb637f74baJeff Brown importer.registerEventHandler('ext4_sync_file_enter', 224849cead45edf85cf2a61526c0b716eb637f74baJeff Brown DiskParser.prototype.ext4SyncFileEnterEvent.bind(this)); 234849cead45edf85cf2a61526c0b716eb637f74baJeff Brown importer.registerEventHandler('ext4_sync_file_exit', 244849cead45edf85cf2a61526c0b716eb637f74baJeff Brown DiskParser.prototype.ext4SyncFileExitEvent.bind(this)); 254849cead45edf85cf2a61526c0b716eb637f74baJeff Brown importer.registerEventHandler('block_rq_issue', 264849cead45edf85cf2a61526c0b716eb637f74baJeff Brown DiskParser.prototype.blockRqIssueEvent.bind(this)); 274849cead45edf85cf2a61526c0b716eb637f74baJeff Brown importer.registerEventHandler('block_rq_complete', 284849cead45edf85cf2a61526c0b716eb637f74baJeff Brown DiskParser.prototype.blockRqCompleteEvent.bind(this)); 294849cead45edf85cf2a61526c0b716eb637f74baJeff Brown } 304849cead45edf85cf2a61526c0b716eb637f74baJeff Brown 314849cead45edf85cf2a61526c0b716eb637f74baJeff Brown DiskParser.prototype = { 324849cead45edf85cf2a61526c0b716eb637f74baJeff Brown __proto__: Parser.prototype, 334849cead45edf85cf2a61526c0b716eb637f74baJeff Brown 344849cead45edf85cf2a61526c0b716eb637f74baJeff Brown openAsyncSlice: function(ts, category, threadName, pid, key, name) { 354849cead45edf85cf2a61526c0b716eb637f74baJeff Brown var kthread = this.importer.getOrCreateKernelThread( 364849cead45edf85cf2a61526c0b716eb637f74baJeff Brown category + ':' + threadName, pid); 374849cead45edf85cf2a61526c0b716eb637f74baJeff Brown var slice = new tracing.AsyncSlice( 384849cead45edf85cf2a61526c0b716eb637f74baJeff Brown category, name, tracing.getStringColorId(name), ts); 394849cead45edf85cf2a61526c0b716eb637f74baJeff Brown slice.startThread = kthread.thread; 404849cead45edf85cf2a61526c0b716eb637f74baJeff Brown 414849cead45edf85cf2a61526c0b716eb637f74baJeff Brown if (!kthread.openAsyncSlices) { 424849cead45edf85cf2a61526c0b716eb637f74baJeff Brown kthread.openAsyncSlices = { }; 434849cead45edf85cf2a61526c0b716eb637f74baJeff Brown } 444849cead45edf85cf2a61526c0b716eb637f74baJeff Brown kthread.openAsyncSlices[key] = slice; 454849cead45edf85cf2a61526c0b716eb637f74baJeff Brown }, 464849cead45edf85cf2a61526c0b716eb637f74baJeff Brown 474849cead45edf85cf2a61526c0b716eb637f74baJeff Brown closeAsyncSlice: function(ts, category, threadName, pid, key, args) { 484849cead45edf85cf2a61526c0b716eb637f74baJeff Brown var kthread = this.importer.getOrCreateKernelThread( 494849cead45edf85cf2a61526c0b716eb637f74baJeff Brown category + ':' + threadName, pid); 504849cead45edf85cf2a61526c0b716eb637f74baJeff Brown if (kthread.openAsyncSlices) { 514849cead45edf85cf2a61526c0b716eb637f74baJeff Brown var slice = kthread.openAsyncSlices[key]; 524849cead45edf85cf2a61526c0b716eb637f74baJeff Brown if (slice) { 534849cead45edf85cf2a61526c0b716eb637f74baJeff Brown slice.duration = ts - slice.start; 544849cead45edf85cf2a61526c0b716eb637f74baJeff Brown slice.args = args; 554849cead45edf85cf2a61526c0b716eb637f74baJeff Brown slice.endThread = kthread.thread; 564849cead45edf85cf2a61526c0b716eb637f74baJeff Brown slice.subSlices = [new tracing.Slice(category, slice.title, 574849cead45edf85cf2a61526c0b716eb637f74baJeff Brown slice.colorId, slice.start, slice.args, slice.duration)]; 584849cead45edf85cf2a61526c0b716eb637f74baJeff Brown kthread.thread.asyncSlices.push(slice); 594849cead45edf85cf2a61526c0b716eb637f74baJeff Brown delete kthread.openAsyncSlices[key]; 604849cead45edf85cf2a61526c0b716eb637f74baJeff Brown } 614849cead45edf85cf2a61526c0b716eb637f74baJeff Brown } 624849cead45edf85cf2a61526c0b716eb637f74baJeff Brown }, 634849cead45edf85cf2a61526c0b716eb637f74baJeff Brown 644849cead45edf85cf2a61526c0b716eb637f74baJeff Brown /** 654849cead45edf85cf2a61526c0b716eb637f74baJeff Brown * Parses events and sets up state in the importer. 664849cead45edf85cf2a61526c0b716eb637f74baJeff Brown */ 674849cead45edf85cf2a61526c0b716eb637f74baJeff Brown ext4SyncFileEnterEvent: function(eventName, cpuNumber, pid, ts, eventBase) { 684849cead45edf85cf2a61526c0b716eb637f74baJeff Brown var event = /dev (\d+,\d+) ino (\d+) parent (\d+) datasync (\d+)/. 694849cead45edf85cf2a61526c0b716eb637f74baJeff Brown exec(eventBase.details); 704849cead45edf85cf2a61526c0b716eb637f74baJeff Brown if (!event) 714849cead45edf85cf2a61526c0b716eb637f74baJeff Brown return false; 724849cead45edf85cf2a61526c0b716eb637f74baJeff Brown 734849cead45edf85cf2a61526c0b716eb637f74baJeff Brown var device = event[1]; 744849cead45edf85cf2a61526c0b716eb637f74baJeff Brown var inode = parseInt(event[2]); 754849cead45edf85cf2a61526c0b716eb637f74baJeff Brown var datasync = event[4] == 1; 764849cead45edf85cf2a61526c0b716eb637f74baJeff Brown var key = device + '-' + inode; 774849cead45edf85cf2a61526c0b716eb637f74baJeff Brown var action = datasync ? 'fdatasync' : 'fsync'; 784849cead45edf85cf2a61526c0b716eb637f74baJeff Brown this.openAsyncSlice(ts, 'ext4', eventBase.threadName, eventBase.pid, 794849cead45edf85cf2a61526c0b716eb637f74baJeff Brown key, action); 804849cead45edf85cf2a61526c0b716eb637f74baJeff Brown return true; 814849cead45edf85cf2a61526c0b716eb637f74baJeff Brown }, 824849cead45edf85cf2a61526c0b716eb637f74baJeff Brown 834849cead45edf85cf2a61526c0b716eb637f74baJeff Brown ext4SyncFileExitEvent: function(eventName, cpuNumber, pid, ts, eventBase) { 844849cead45edf85cf2a61526c0b716eb637f74baJeff Brown var event = /dev (\d+,\d+) ino (\d+) ret (\d+)/.exec(eventBase.details); 854849cead45edf85cf2a61526c0b716eb637f74baJeff Brown if (!event) 864849cead45edf85cf2a61526c0b716eb637f74baJeff Brown return false; 874849cead45edf85cf2a61526c0b716eb637f74baJeff Brown 884849cead45edf85cf2a61526c0b716eb637f74baJeff Brown var device = event[1]; 894849cead45edf85cf2a61526c0b716eb637f74baJeff Brown var inode = parseInt(event[2]); 904849cead45edf85cf2a61526c0b716eb637f74baJeff Brown var error = parseInt(event[3]); 914849cead45edf85cf2a61526c0b716eb637f74baJeff Brown var key = device + '-' + inode; 924849cead45edf85cf2a61526c0b716eb637f74baJeff Brown this.closeAsyncSlice(ts, 'ext4', eventBase.threadName, eventBase.pid, 934849cead45edf85cf2a61526c0b716eb637f74baJeff Brown key, { 944849cead45edf85cf2a61526c0b716eb637f74baJeff Brown device: device, 954849cead45edf85cf2a61526c0b716eb637f74baJeff Brown inode: inode, 964849cead45edf85cf2a61526c0b716eb637f74baJeff Brown error: error 974849cead45edf85cf2a61526c0b716eb637f74baJeff Brown }); 984849cead45edf85cf2a61526c0b716eb637f74baJeff Brown return true; 994849cead45edf85cf2a61526c0b716eb637f74baJeff Brown }, 1004849cead45edf85cf2a61526c0b716eb637f74baJeff Brown 1014849cead45edf85cf2a61526c0b716eb637f74baJeff Brown blockRqIssueEvent: function(eventName, cpuNumber, pid, ts, eventBase) { 1024849cead45edf85cf2a61526c0b716eb637f74baJeff Brown var event = new RegExp('(\\d+,\\d+) (F)?([DWRN])(F)?(A)?(S)?(M)? ' + 1034849cead45edf85cf2a61526c0b716eb637f74baJeff Brown '\\d+ \\(.*\\) (\\d+) \\+ (\\d+) \\[.*\\]').exec(eventBase.details); 1044849cead45edf85cf2a61526c0b716eb637f74baJeff Brown if (!event) 1054849cead45edf85cf2a61526c0b716eb637f74baJeff Brown return false; 1064849cead45edf85cf2a61526c0b716eb637f74baJeff Brown 1074849cead45edf85cf2a61526c0b716eb637f74baJeff Brown var action; 1084849cead45edf85cf2a61526c0b716eb637f74baJeff Brown switch (event[3]) { 1094849cead45edf85cf2a61526c0b716eb637f74baJeff Brown case 'D': 1104849cead45edf85cf2a61526c0b716eb637f74baJeff Brown action = 'discard'; 1114849cead45edf85cf2a61526c0b716eb637f74baJeff Brown break; 1124849cead45edf85cf2a61526c0b716eb637f74baJeff Brown case 'W': 1134849cead45edf85cf2a61526c0b716eb637f74baJeff Brown action = 'write'; 1144849cead45edf85cf2a61526c0b716eb637f74baJeff Brown break; 1154849cead45edf85cf2a61526c0b716eb637f74baJeff Brown case 'R': 1164849cead45edf85cf2a61526c0b716eb637f74baJeff Brown action = 'read'; 1174849cead45edf85cf2a61526c0b716eb637f74baJeff Brown break; 1184849cead45edf85cf2a61526c0b716eb637f74baJeff Brown case 'N': 1194849cead45edf85cf2a61526c0b716eb637f74baJeff Brown action = 'none'; 1204849cead45edf85cf2a61526c0b716eb637f74baJeff Brown break; 1214849cead45edf85cf2a61526c0b716eb637f74baJeff Brown default: 1224849cead45edf85cf2a61526c0b716eb637f74baJeff Brown action = 'unknown'; 1234849cead45edf85cf2a61526c0b716eb637f74baJeff Brown break; 1244849cead45edf85cf2a61526c0b716eb637f74baJeff Brown } 1254849cead45edf85cf2a61526c0b716eb637f74baJeff Brown 1264849cead45edf85cf2a61526c0b716eb637f74baJeff Brown if (event[2]) { 1274849cead45edf85cf2a61526c0b716eb637f74baJeff Brown action += ' flush'; 1284849cead45edf85cf2a61526c0b716eb637f74baJeff Brown } 1294849cead45edf85cf2a61526c0b716eb637f74baJeff Brown if (event[4] == 'F') { 1304849cead45edf85cf2a61526c0b716eb637f74baJeff Brown action += ' fua'; 1314849cead45edf85cf2a61526c0b716eb637f74baJeff Brown } 1324849cead45edf85cf2a61526c0b716eb637f74baJeff Brown if (event[5] == 'A') { 1334849cead45edf85cf2a61526c0b716eb637f74baJeff Brown action += ' ahead'; 1344849cead45edf85cf2a61526c0b716eb637f74baJeff Brown } 1354849cead45edf85cf2a61526c0b716eb637f74baJeff Brown if (event[6] == 'S') { 1364849cead45edf85cf2a61526c0b716eb637f74baJeff Brown action += ' sync'; 1374849cead45edf85cf2a61526c0b716eb637f74baJeff Brown } 1384849cead45edf85cf2a61526c0b716eb637f74baJeff Brown if (event[7] == 'M') { 1394849cead45edf85cf2a61526c0b716eb637f74baJeff Brown action += ' meta'; 1404849cead45edf85cf2a61526c0b716eb637f74baJeff Brown } 1414849cead45edf85cf2a61526c0b716eb637f74baJeff Brown var device = event[1]; 1424849cead45edf85cf2a61526c0b716eb637f74baJeff Brown var sector = parseInt(event[8]); 1434849cead45edf85cf2a61526c0b716eb637f74baJeff Brown var numSectors = parseInt(event[9]); 1444849cead45edf85cf2a61526c0b716eb637f74baJeff Brown var key = device + '-' + sector + '-' + numSectors; 1454849cead45edf85cf2a61526c0b716eb637f74baJeff Brown this.openAsyncSlice(ts, 'block', eventBase.threadName, eventBase.pid, 1464849cead45edf85cf2a61526c0b716eb637f74baJeff Brown key, action); 1474849cead45edf85cf2a61526c0b716eb637f74baJeff Brown return true; 1484849cead45edf85cf2a61526c0b716eb637f74baJeff Brown }, 1494849cead45edf85cf2a61526c0b716eb637f74baJeff Brown 1504849cead45edf85cf2a61526c0b716eb637f74baJeff Brown blockRqCompleteEvent: function(eventName, cpuNumber, pid, ts, eventBase) { 1514849cead45edf85cf2a61526c0b716eb637f74baJeff Brown var event = new RegExp('(\\d+,\\d+) (F)?([DWRN])(F)?(A)?(S)?(M)? ' + 1524849cead45edf85cf2a61526c0b716eb637f74baJeff Brown '\\(.*\\) (\\d+) \\+ (\\d+) \\[(.*)\\]').exec(eventBase.details); 1534849cead45edf85cf2a61526c0b716eb637f74baJeff Brown if (!event) 1544849cead45edf85cf2a61526c0b716eb637f74baJeff Brown return false; 1554849cead45edf85cf2a61526c0b716eb637f74baJeff Brown 1564849cead45edf85cf2a61526c0b716eb637f74baJeff Brown var device = event[1]; 1574849cead45edf85cf2a61526c0b716eb637f74baJeff Brown var sector = parseInt(event[8]); 1584849cead45edf85cf2a61526c0b716eb637f74baJeff Brown var numSectors = parseInt(event[9]); 1594849cead45edf85cf2a61526c0b716eb637f74baJeff Brown var error = parseInt(event[10]); 1604849cead45edf85cf2a61526c0b716eb637f74baJeff Brown var key = device + '-' + sector + '-' + numSectors; 1614849cead45edf85cf2a61526c0b716eb637f74baJeff Brown this.closeAsyncSlice(ts, 'block', eventBase.threadName, eventBase.pid, 1624849cead45edf85cf2a61526c0b716eb637f74baJeff Brown key, { 1634849cead45edf85cf2a61526c0b716eb637f74baJeff Brown device: device, 1644849cead45edf85cf2a61526c0b716eb637f74baJeff Brown sector: sector, 1654849cead45edf85cf2a61526c0b716eb637f74baJeff Brown numSectors: numSectors, 1664849cead45edf85cf2a61526c0b716eb637f74baJeff Brown error: error 1674849cead45edf85cf2a61526c0b716eb637f74baJeff Brown }); 1684849cead45edf85cf2a61526c0b716eb637f74baJeff Brown return true; 1694849cead45edf85cf2a61526c0b716eb637f74baJeff Brown }, 1704849cead45edf85cf2a61526c0b716eb637f74baJeff Brown }; 1714849cead45edf85cf2a61526c0b716eb637f74baJeff Brown 1724849cead45edf85cf2a61526c0b716eb637f74baJeff Brown Parser.registerSubtype(DiskParser); 1734849cead45edf85cf2a61526c0b716eb637f74baJeff Brown 1744849cead45edf85cf2a61526c0b716eb637f74baJeff Brown return { 1754849cead45edf85cf2a61526c0b716eb637f74baJeff Brown DiskParser: DiskParser 1764849cead45edf85cf2a61526c0b716eb637f74baJeff Brown }; 1774849cead45edf85cf2a61526c0b716eb637f74baJeff Brown}); 178