def _process_lttng_statedump_process_state(self, event): tid = event["tid"] pid = event["pid"] name = event["name"] if tid not in self.tids: p = sv.Process() p.tid = tid self.tids[tid] = p else: p = self.tids[tid] # Even if the process got created earlier, some info might be # missing, add it now. p.pid = pid p.comm = name if pid != tid: # create the parent if pid not in self.tids: parent = sv.Process() parent.tid = pid parent.pid = pid parent.comm = name self.tids[pid] = parent else: parent = self.tids[pid] # If the thread had opened sv.FDs, they need to be assigned # to the parent. self.merge_fd_dict(p, parent)
def fix_process(self, name, tid, pid): if tid not in self.tids: p = sv.Process() p.tid = tid self.tids[tid] = p else: p = self.tids[tid] p.pid = pid p.comm = name if pid not in self.tids: p = sv.Process() p.tid = pid self.tids[pid] = p else: p = self.tids[pid] p.pid = pid p.comm = name
def _process_sched_migrate_task(self, event): tid = event["tid"] if tid not in self.tids: p = sv.Process() p.tid = tid p.comm = event["comm"] self.tids[tid] = p else: p = self.tids[tid] p.migrate_count += 1
def _process_sched_process_exec(self, event): tid = event["tid"] if tid not in self.tids: p = sv.Process() p.tid = tid self.tids[tid] = p else: p = self.tids[tid] if "procname" in event.keys(): p.comm = event["procname"] toremove = [] for fd in p.fds.keys(): if p.fds[fd].cloexec == 1: toremove.append(fd) for fd in toremove: p.fds.pop(fd, None)
def sched_switch_per_tid(self, ts, prev_tid, next_tid, next_comm, cpu_id, event, ret): """Compute per-tid usage""" # if we don't know yet the sv.CPU, skip this if cpu_id not in self.cpus.keys(): self.add_cpu(cpu_id, ts, next_tid) c = self.cpus[cpu_id] # per-tid usage if prev_tid in self.tids: p = self.tids[prev_tid] if p.last_sched is not None: p.cpu_ns += (ts - p.last_sched) # perf PMU counters checks for context in event.field_list_with_scope( CTFScope.STREAM_EVENT_CONTEXT): if context.startswith("perf_"): if context not in c.perf.keys(): c.perf[context] = event[context] # add the difference between the last known value # for this counter on the current sv.CPU diff = event[context] - c.perf[context] if context not in p.perf.keys(): p.perf[context] = diff else: p.perf[context] += diff if diff > 0: ret[context] = diff # exclude swapper process if next_tid == 0: return ret if next_tid not in self.tids: p = sv.Process() p.tid = next_tid p.comm = next_comm self.tids[next_tid] = p else: p = self.tids[next_tid] p.comm = next_comm p.last_sched = ts for q in c.wakeup_queue: if q["task"] == p: ret["sched_latency"] = ts - q["ts"] ret["next_tid"] = next_tid c.wakeup_queue.remove(q) return ret
def _process_block_rq_issue(self, event): dev = event["dev"] sector = event["sector"] nr_sector = event["nr_sector"] # Note: since we don't know, we assume a sector is 512 bytes block_size = 512 if nr_sector == 0: return rq = {} rq["nr_sector"] = nr_sector rq["rq_time"] = event.timestamp rq["iorequest"] = sv.IORequest() rq["iorequest"].iotype = sv.IORequest.IO_BLOCK rq["iorequest"].begin = event.timestamp rq["iorequest"].size = nr_sector * block_size d = None for req in self.remap_requests: if req["dev"] == dev and req["sector"] == sector: d = common.get_disk(req["orig_dev"], self.disks) if not d: d = common.get_disk(dev, self.disks) d.nr_requests += 1 d.nr_sector += nr_sector d.pending_requests[sector] = rq if "tid" in event.keys(): tid = event["tid"] if tid not in self.tids: p = sv.Process() p.tid = tid self.tids[tid] = p else: p = self.tids[tid] if p.pid != -1 and p.tid != p.pid: p = self.tids[p.pid] rq["pid"] = p # even rwbs means read, odd means write if event["rwbs"] % 2 == 0: p.block_read += nr_sector * block_size rq["iorequest"].operation = sv.IORequest.OP_READ else: p.block_write += nr_sector * block_size rq["iorequest"].operation = sv.IORequest.OP_WRITE
def _process_sched_wakeup(self, event): """Stores the sched_wakeup infos to compute scheduling latencies""" target_cpu = event["target_cpu"] tid = event["tid"] if target_cpu not in self.cpus.keys(): c = sv.CPU() c.cpu_id = target_cpu self.cpus[target_cpu] = c else: c = self.cpus[target_cpu] if tid not in self.tids: p = sv.Process() p.tid = tid self.tids[tid] = p else: p = self.tids[tid] c.wakeup_queue.append({"ts": event.timestamp, "task": p})
def _fix_context_pid(self, event, t): for context in event.field_list_with_scope( CTFScope.STREAM_EVENT_CONTEXT): if context != "pid": continue # make sure the "pid" field is not also in the event # payload, otherwise we might clash for context in event.field_list_with_scope(CTFScope.EVENT_FIELDS): if context == "pid": return if t.pid == -1: t.pid == event["pid"] if event["pid"] != t.tid: t.pid = event["pid"] p = sv.Process() p.tid = t.pid p.pid = t.pid p.comm = t.comm self.tids[p.pid] = p
def _process_sched_process_fork(self, event): child_tid = event["child_tid"] child_pid = event["child_pid"] child_comm = event["child_comm"] parent_pid = event["parent_pid"] parent_tid = event["parent_pid"] parent_comm = event["parent_comm"] f = sv.Process() f.tid = child_tid f.pid = child_pid f.comm = child_comm # make sure the parent exists self.fix_process(parent_comm, parent_tid, parent_pid) p = self.tids[parent_pid] for fd in p.fds.keys(): f.fds[fd] = self.dup_fd(p.fds[fd]) f.fds[fd].parent = parent_pid self.tids[child_tid] = f
def _process_lttng_statedump_file_descriptor(self, event): pid = event["pid"] fd = event["fd"] filename = event["filename"] if pid not in self.tids: p = sv.Process() p.pid = pid p.tid = pid self.tids[pid] = p else: p = self.tids[pid] if fd not in p.fds.keys(): newfile = sv.FD() newfile.filename = filename newfile.fd = fd # FIXME: we don't have the info, just assume for now newfile.cloexec = 1 p.fds[fd] = newfile else: # just fix the filename p.fds[fd].filename = filename