blob: bb64b529d31c6980601da5c2cc0f22cd6c6a4603 [file] [log] [blame]
#!/usr/bin/env ruby
RESULT_ROOT = ENV['RESULT_ROOT']
LKP_SRC = ENV['LKP_SRC'] || File.dirname(File.dirname(File.realpath($PROGRAM_NAME)))
require "#{LKP_SRC}/lib/ftrace"
require "#{LKP_SRC}/lib/common"
# Analyze these samples to get how many times irq/softirq happened
# and how long they take
class IrqAnalysis
def initialize(sample_array)
@sample_array = sample_array
@last = nil
@irq = {}
@softirq = {}
@irq_nr = @irq_time = @softirq_nr = @softirq_time = 0
end
attr_reader :irq_nr, :irq_time, :softirq_nr, :softirq_time
def produce_result
@irq.each do |_, array|
@irq_nr += array.length
@irq_time += array.inject(0, :+)
end
@softirq.each do |_, array|
@softirq_nr += array.length
@softirq_time += array.inject(0, :+)
end
puts "irq_nr: #{@irq_nr}"
puts "softirq_nr: #{@softirq_nr}"
puts "irq_time: #{@irq_time}us"
puts "softirq_time: #{@softirq_time}us"
end
def mismatch(s1, s2)
return true if s1.pid != s2.pid
key = 'irq'
key = 'vec' if s1.type == :softirq_entry
return true if s1.data[key] != s2.data[key]
false
end
def process(s1, s2)
return if mismatch(s1, s2)
t = (s2.timestamp * 1_000_000).to_i - (s1.timestamp * 1_000_000).to_i
if s1.type == :softirq_entry
vec_nr = s1.data['vec']
@softirq[vec_nr] ||= []
@softirq[vec_nr] << t
else
irq_nr = s1.data['irq']
@irq[irq_nr] ||= []
@irq[irq_nr] << t
end
end
def analyze
@sample_array.each do |sample|
if @last
if sample.type == :softirq_exit || sample.type == :irq_handler_exit
process @last, sample
end
@last = nil
elsif sample.type == :softirq_entry || sample.type == :irq_handler_entry
@last = sample
end
end
produce_result
end
end
def extract_ftrace
fn = "#{RESULT_ROOT}/ftrace.data.xz"
fmts_dir = "#{RESULT_ROOT}/ftrace_events"
file = zopen(fn)
trace = TPTrace.new file, fmts_dir
samples = {}
# interrupt handler will not be migrated so to simply entry/exit
# pair match, sort these samples according to CPU number
trace.each do |sample|
samples[sample.cpu] ||= []
samples[sample.cpu] << sample
end
samples_array = []
# then we put these sorted lines into a global array
samples.each do |_, array|
array.each do |sample|
samples_array << sample
end
end
samples_array
end
irq_analysis = IrqAnalysis.new extract_ftrace
irq_analysis.analyze