fix: stats with 0 requests
[deliverable/lttng-analyses.git] / linuxautomaton / linuxautomaton / block.py
1 #!/usr/bin/env python3
2 #
3 # The MIT License (MIT)
4 #
5 # Copyright (C) 2015 - Julien Desfossez <jdesfossez@efficios.com>
6 # 2015 - Antoine Busque <abusque@efficios.com>
7 #
8 # Permission is hereby granted, free of charge, to any person obtaining a copy
9 # of this software and associated documentation files (the "Software"), to deal
10 # in the Software without restriction, including without limitation the rights
11 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 # copies of the Software, and to permit persons to whom the Software is
13 # furnished to do so, subject to the following conditions:
14 #
15 # The above copyright notice and this permission notice shall be included in
16 # all copies or substantial portions of the Software.
17 #
18 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 # SOFTWARE.
25
26 from linuxautomaton import sp, sv
27
28
29 class BlockStateProvider(sp.StateProvider):
30 def __init__(self, state):
31 cbs = {
32 'block_rq_complete': self._process_block_rq_complete,
33 'block_rq_issue': self._process_block_rq_issue,
34 'block_bio_remap': self._process_block_bio_remap,
35 'block_bio_backmerge': self._process_block_bio_backmerge,
36 }
37
38 self._state = state
39 self._remap_requests = []
40 self._register_cbs(cbs)
41
42 def process_event(self, ev):
43 self._process_event_cb(ev)
44
45 def _process_block_bio_remap(self, event):
46 dev = event['dev']
47 sector = event['sector']
48 old_dev = event['old_dev']
49 old_sector = event['old_sector']
50
51 for req in self._remap_requests:
52 if req.dev == old_dev and req.sector == old_sector:
53 req.dev = dev
54 req.sector = sector
55 return
56
57 req = sv.BlockRemapRequest(dev, sector, old_dev, old_sector)
58 self._remap_requests.append(req)
59
60 # For backmerge requests, just remove the request from the
61 # _remap_requests queue, because we rely later on the nr_sector
62 # which has all the info we need
63 def _process_block_bio_backmerge(self, event):
64 dev = event['dev']
65 sector = event['sector']
66 for remap_req in self._remap_requests:
67 if remap_req.dev == dev and remap_req.sector == sector:
68 self._remap_requests.remove(remap_req)
69
70 def _process_block_rq_issue(self, event):
71 dev = event['dev']
72 sector = event['sector']
73 nr_sector = event['nr_sector']
74
75 if nr_sector == 0:
76 return
77
78 req = sv.BlockIORequest.new_from_rq_issue(event)
79
80 for remap_req in self._remap_requests:
81 if remap_req.dev == dev and remap_req.sector == sector:
82 dev = remap_req.old_dev
83 break
84
85 if dev not in self._state.disks:
86 self._state.disks[dev] = sv.Disk()
87
88 self._state.disks[dev].pending_requests[sector] = req
89
90 def _process_block_rq_complete(self, event):
91 dev = event['dev']
92 sector = event['sector']
93 nr_sector = event['nr_sector']
94
95 if nr_sector == 0:
96 return
97
98 for remap_req in self._remap_requests:
99 if remap_req.dev == dev and remap_req.sector == sector:
100 dev = remap_req.old_dev
101 self._remap_requests.remove(remap_req)
102 break
103
104 if dev not in self._state.disks:
105 self._state.disks[dev] = sv.Disk()
106
107 disk = self._state.disks[dev]
108
109 # Ignore rq_complete without matching rq_issue
110 if sector not in disk.pending_requests:
111 return
112
113 req = disk.pending_requests[sector]
114 # Ignore rq_complete if nr_sector does not match rq_issue's
115 if req.nr_sector != nr_sector:
116 return
117
118 req.update_from_rq_complete(event)
119 proc = self._state.tids[req.tid]
120 self._state.send_notification_cb('block_rq_complete', req=req,
121 proc=proc)
122 del disk.pending_requests[sector]
This page took 0.038566 seconds and 5 git commands to generate.