Fix: correct typo in author email address
[deliverable/lttng-analyses.git] / linuxautomaton / linuxautomaton / irq.py
CommitLineData
4ed24f86
JD
1#!/usr/bin/env python3
2#
3# The MIT License (MIT)
4#
a3fa57c0 5# Copyright (C) 2015 - Julien Desfossez <jdesfossez@efficios.com>
4ed24f86
JD
6#
7# Permission is hereby granted, free of charge, to any person obtaining a copy
8# of this software and associated documentation files (the "Software"), to deal
9# in the Software without restriction, including without limitation the rights
10# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11# copies of the Software, and to permit persons to whom the Software is
12# furnished to do so, subject to the following conditions:
13#
14# The above copyright notice and this permission notice shall be included in
15# all copies or substantial portions of the Software.
16#
17# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23# SOFTWARE.
24
47ba125c
JD
25from linuxautomaton import sp, sv
26
27
28class IrqStateProvider(sp.StateProvider):
29 def __init__(self, state):
30 self.state = state
31 self.irq = state.interrupts
32 self.cpus = state.cpus
33 self.tids = state.tids
34 self.irq["hard_count"] = 0
35 self.irq["soft_count"] = 0
36 self.irq["hard-per-cpu"] = {}
37 self.irq["soft-per-cpu"] = {}
38 self.irq["raise-per-cpu"] = {}
39 self.irq["names"] = {}
40 self.irq["hard-irqs"] = {}
41 self.irq["soft-irqs"] = {}
42 self.irq["raise-latency"] = {}
43 self.irq["irq-list"] = []
44 cbs = {
45 'irq_handler_entry': self._process_irq_handler_entry,
46 'irq_handler_exit': self._process_irq_handler_exit,
47 'softirq_entry': self._process_softirq_entry,
48 'softirq_exit': self._process_softirq_exit,
49 'softirq_raise': self._process_softirq_raise,
50 }
51 self._register_cbs(cbs)
52
53 def process_event(self, ev):
54 self._process_event_cb(ev)
55
47ba125c
JD
56 def entry(self, event, irqclass, idfield):
57 cpu_id = event["cpu_id"]
58 i = sv.IRQ()
59 i.irqclass = irqclass
60 i.start_ts = event.timestamp
61 i.cpu_id = cpu_id
62 i.nr = event[idfield]
63 return i
64
65 def _process_irq_handler_entry(self, event):
66 cpu_id = event["cpu_id"]
67 self.irq["names"][event["irq"]] = event["name"]
68 self.irq["hard_count"] += 1
69 i = self.entry(event, sv.IRQ.HARD_IRQ, "irq")
70 self.irq["hard-per-cpu"][cpu_id] = i
71
72 def _process_softirq_entry(self, event):
73 cpu_id = event["cpu_id"]
74 self.irq["soft_count"] += 1
75 i = self.entry(event, sv.IRQ.SOFT_IRQ, "vec")
76 self.irq["soft-per-cpu"][cpu_id] = i
77 if cpu_id in self.irq["raise-per-cpu"].keys() and \
78 self.irq["raise-per-cpu"][cpu_id] is not None and \
79 self.irq["raise-per-cpu"][cpu_id][1] == event["vec"]:
80 i.raise_ts = self.irq["raise-per-cpu"][cpu_id][0]
81 self.irq["raise-per-cpu"][cpu_id] = None
82
83 def compute_stats(self, irq_entry, i):
84 duration = i.stop_ts - i.start_ts
85 if duration > irq_entry["max"]:
86 irq_entry["max"] = duration
87 if irq_entry["min"] == -1 or duration < irq_entry["min"]:
88 irq_entry["min"] = duration
89 irq_entry["count"] += 1
90 irq_entry["total"] += duration
91 # compute raise latency if applicable
92 if i.raise_ts == -1:
93 return True
94 latency = i.start_ts - i.raise_ts
95 if latency > irq_entry["raise_max"]:
96 irq_entry["raise_max"] = latency
97 if irq_entry["raise_min"] == -1 or latency < irq_entry["raise_min"]:
98 irq_entry["raise_min"] = latency
99 irq_entry["raise_count"] += 1
100 irq_entry["raise_total"] += latency
101 return True
102
103 def exit(self, event, idfield, per_cpu_key, irq_type):
104 cpu_id = event["cpu_id"]
105 if cpu_id not in self.irq[per_cpu_key].keys() or \
106 self.irq[per_cpu_key][cpu_id] is None:
107 return
108 i = self.irq[per_cpu_key][cpu_id]
109 if i.nr != event[idfield]:
110 self.irq[per_cpu_key][cpu_id] = None
111 return
112 i.stop_ts = event.timestamp
113 if not i.nr in self.irq[irq_type].keys():
ca95b1c3 114 self.irq[irq_type][i.nr] = sv.IRQ.init_irq_instance()
47ba125c
JD
115
116 # filter out max/min
117 duration = i.stop_ts - i.start_ts
f89605f0
JD
118 if hasattr(self.state, "max") and self.state.max is not None and \
119 duration > self.state.max * 1000:
47ba125c 120 return False
f89605f0
JD
121 if hasattr(self.state, "min") and self.state.min is not None and \
122 duration < self.state.min * 1000:
47ba125c
JD
123 return False
124 self.irq[irq_type][i.nr]["list"].append(i)
125 self.compute_stats(self.irq[irq_type][i.nr], i)
126 self.irq["irq-list"].append(i)
127 return i
128
129 def _process_irq_handler_exit(self, event):
130 i = self.exit(event, "irq", "hard-per-cpu", "hard-irqs")
131 if not i:
132 return
133 i.ret = event["ret"]
134
135 def _process_softirq_exit(self, event):
136 self.exit(event, "vec", "soft-per-cpu", "soft-irqs")
137
138 def _process_softirq_raise(self, event):
139 cpu_id = event["cpu_id"]
140 self.irq["raise-per-cpu"][cpu_id] = ((event.timestamp, event["vec"]))
This page took 0.031207 seconds and 5 git commands to generate.