Unverified Commit 474d6aa9 authored by Jakob Görgen's avatar Jakob Görgen Committed by GitHub
Browse files

Sim lib compiler warn fix (#115)

* dist/common/base: fix taking member of packed struct warning

* trace: removed outdated folder

* lib/simbricks/nicbm/multinic: fixed boost bind warning

* sims/net/pktgen/pktgen: removed forward_pkt and potential use
parent 135e7118
...@@ -15,5 +15,3 @@ sims/nic/i40e_bm/*.h ...@@ -15,5 +15,3 @@ sims/nic/i40e_bm/*.h
lib/simbricks/*/*.c lib/simbricks/*/*.c
lib/simbricks/*/*.cc lib/simbricks/*/*.cc
lib/simbricks/*/*.h lib/simbricks/*/*.h
trace/*.cc
trace/*.h
...@@ -45,7 +45,6 @@ $(eval $(call subdir,sims)) ...@@ -45,7 +45,6 @@ $(eval $(call subdir,sims))
$(eval $(call subdir,dist)) $(eval $(call subdir,dist))
$(eval $(call subdir,doc)) $(eval $(call subdir,doc))
$(eval $(call subdir,images)) $(eval $(call subdir,images))
$(eval $(call subdir,trace))
$(eval $(call subdir,experiments)) $(eval $(call subdir,experiments))
......
...@@ -177,14 +177,20 @@ int BasePeerSetupQueues(struct Peer *peer) { ...@@ -177,14 +177,20 @@ int BasePeerSetupQueues(struct Peer *peer) {
li->l2c_nentries, li->c2l_elen, li->c2l_nentries); li->l2c_nentries, li->c2l_elen, li->c2l_nentries);
#endif #endif
if (ShmAlloc(li->l2c_elen * li->l2c_nentries, &li->l2c_offset)) { uint64_t l2c_offset = 0;
if (ShmAlloc(li->l2c_elen * li->l2c_nentries, &l2c_offset)) {
fprintf(stderr, "PeerNetSetupQueues: ShmAlloc l2c failed"); fprintf(stderr, "PeerNetSetupQueues: ShmAlloc l2c failed");
return 1; return 1;
} }
if (ShmAlloc(li->c2l_elen * li->c2l_nentries, &li->c2l_offset)) { li->l2c_offset = l2c_offset;
uint64_t c2l_offset = 0;
if (ShmAlloc(li->c2l_elen * li->c2l_nentries, &c2l_offset)) {
fprintf(stderr, "PeerNetSetupQueues: ShmAlloc c2l failed"); fprintf(stderr, "PeerNetSetupQueues: ShmAlloc c2l failed");
return 1; return 1;
} }
li->c2l_offset = c2l_offset;
peer->shm_fd = shm_fd; peer->shm_fd = shm_fd;
peer->shm_base = shm_base; peer->shm_base = shm_base;
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
#include <string.h> #include <string.h>
#include <boost/bind.hpp>
#include <boost/fiber/all.hpp> #include <boost/fiber/all.hpp>
#include <thread> #include <thread>
#include <vector> #include <vector>
...@@ -73,8 +72,7 @@ int MultiNicRunner::RunMain(int argc, char *argv[]) { ...@@ -73,8 +72,7 @@ int MultiNicRunner::RunMain(int argc, char *argv[]) {
if (r->ParseArgs(end - start, argv + start)) if (r->ParseArgs(end - start, argv + start))
return -1; return -1;
auto *f = new boost::fibers::fiber( auto *f = new boost::fibers::fiber([&runner = r]() { runner->RunMain(); });
boost::bind(&CompRunner::RunMain, boost::ref(*r)));
runners.push_back(r); runners.push_back(r);
fibers.push_back(f); fibers.push_back(f);
start = end; start = end;
......
...@@ -277,46 +277,6 @@ static void sigusr2_handler(int dummy) { ...@@ -277,46 +277,6 @@ static void sigusr2_handler(int dummy) {
} }
#endif #endif
static void forward_pkt(const void *pkt_data, size_t pkt_len, size_t port_id) {
struct pcap_pkthdr ph;
Port &dest_port = *ports[port_id];
// log to pcap file if initialized
if (dumpfile) {
memset(&ph, 0, sizeof(ph));
ph.ts.tv_sec = cur_ts / 1000000000000ULL;
ph.ts.tv_usec = (cur_ts % 1000000000000ULL) / 1000ULL;
ph.caplen = pkt_len;
ph.len = pkt_len;
pcap_dump((unsigned char *)dumpfile, &ph, (unsigned char *)pkt_data);
}
// print sending tick: [packet type] source_IP -> dest_IP len:
#ifdef NETSWITCH_DEBUG
uint16_t eth_proto;
struct ethhdr *hdr;
struct iphdr *iph;
hdr = (struct ethhdr *)pkt_data;
eth_proto = ntohs(hdr->h_proto);
iph = (struct iphdr *)(hdr + 1);
fprintf(stderr, "%20lu: ", cur_ts);
if (eth_proto == ETH_P_IP) {
fprintf(stderr, "[ IP] ");
} else if (eth_proto == ETH_P_ARP) {
fprintf(stderr, "[ARP] ");
} else {
fprintf(stderr, "unkwon eth type\n");
}
fprintf(stderr, "%8X -> %8X len: %lu\n ", iph->saddr, iph->daddr,
iph->tot_len + sizeof(struct ethhdr));
#endif
if (!dest_port.TxPacket(pkt_data, pkt_len, cur_ts))
fprintf(stderr, "forward_pkt: dropping packet on port %zu\n", port_id);
}
static void pollq(Port &port, size_t iport) { static void pollq(Port &port, size_t iport) {
// poll N2D queue // poll N2D queue
// send packet // send packet
...@@ -346,27 +306,6 @@ static void pollq(Port &port, size_t iport) { ...@@ -346,27 +306,6 @@ static void pollq(Port &port, size_t iport) {
// stat received bytes // stat received bytes
pkt_recv_num++; pkt_recv_num++;
pkt_recv_byte += pkt_len; pkt_recv_byte += pkt_len;
// Get MAC addresses
// MAC dst((const uint8_t *)pkt_data), src((const uint8_t *)pkt_data + 6);
// // MAC learning
// if (!(src == bcast_addr)) {
// mac_table[src] = iport;
// }
// // L2 forwarding
// auto i = mac_table.find(dst);
// if (i != mac_table.end()) {
// size_t eport = i->second;
// forward_pkt(pkt_data, pkt_len, eport);
// } else {
// // Broadcast
// for (size_t eport = 0; eport < ports.size(); eport++) {
// if (eport != iport) {
// // Do not forward to ingress port
// forward_pkt(pkt_data, pkt_len, eport);
// }
// }
// }
} else if (poll == Port::kRxPollSync) { } else if (poll == Port::kRxPollSync) {
#ifdef NETSWITCH_STAT #ifdef NETSWITCH_STAT
d2n_poll_sync += 1; d2n_poll_sync += 1;
......
/*
* Copyright 2021 Max Planck Institute for Software Systems, and
* National University of Singapore
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#pragma once
#include <string>
class log_parser;
class event {
public:
uint64_t ts;
log_parser *source;
explicit event(uint64_t ts_) : ts(ts_) {
}
virtual ~event() {
}
virtual void dump(std::ostream &out) = 0;
};
class EHostInstr : public event {
public:
uint64_t pc;
bool fMemR;
bool fMemW;
EHostInstr(uint64_t ts_, uint64_t pc_)
: event(ts_), pc(pc_), fMemR(false), fMemW(false) {
}
virtual ~EHostInstr() {
}
virtual void dump(std::ostream &out) {
out << ts << ": H.INSTR pc=" << std::hex << pc << std::dec << std::endl;
}
};
class EHostHalt : public event {
public:
uint64_t pc;
EHostHalt(uint64_t ts_, uint64_t pc_) : event(ts_), pc(pc_) {
}
virtual ~EHostHalt() {
}
virtual void dump(std::ostream &out) {
out << ts << ": H.HALT pc=" << std::hex << pc << std::dec << std::endl;
}
};
class EHostCall : public event {
public:
const std::string &fun;
EHostCall(uint64_t ts_, const std::string &fun_) : event(ts_), fun(fun_) {
}
virtual ~EHostCall() {
}
virtual void dump(std::ostream &out) {
out << ts << ": H.CALL " << fun << std::endl;
}
};
class EHostMsiX : public event {
public:
uint16_t vec;
EHostMsiX(uint64_t ts_, uint16_t vec_) : event(ts_), vec(vec_) {
}
virtual ~EHostMsiX() {
}
virtual void dump(std::ostream &out) {
out << ts << ": H.MSIX " << vec << std::endl;
}
};
class EHostDmaR : public event {
public:
uint64_t id;
uint64_t addr;
uint64_t size;
EHostDmaR(uint64_t ts_, uint64_t id_, uint64_t addr_, uint64_t size_)
: event(ts_), id(id_), addr(addr_), size(size_) {
}
virtual ~EHostDmaR() {
}
virtual void dump(std::ostream &out) {
out << ts << ": H.DMAR id=" << id << " addr=" << addr << " size=" << size
<< std::endl;
}
};
class EHostDmaW : public event {
public:
uint64_t id;
uint64_t addr;
uint64_t size;
EHostDmaW(uint64_t ts_, uint64_t id_, uint64_t addr_, uint64_t size_)
: event(ts_), id(id_), addr(addr_), size(size_) {
}
virtual ~EHostDmaW() {
}
virtual void dump(std::ostream &out) {
out << ts << ": H.DMAW id=" << id << " addr=" << addr << " size=" << size
<< std::endl;
}
};
class EHostDmaC : public event {
public:
uint64_t id;
EHostDmaC(uint64_t ts_, uint64_t id_) : event(ts_), id(id_) {
}
virtual ~EHostDmaC() {
}
virtual void dump(std::ostream &out) {
out << ts << ": H.DMAC id=" << id << std::endl;
}
};
class EHostMmioR : public event {
public:
uint64_t id;
uint64_t addr;
uint64_t size;
EHostMmioR(uint64_t ts_, uint64_t id_, uint64_t addr_, uint64_t size_)
: event(ts_), id(id_), addr(addr_), size(size_) {
}
virtual ~EHostMmioR() {
}
virtual void dump(std::ostream &out) {
out << ts << ": H.MMIOR id=" << id << " addr=" << addr << " size=" << size
<< std::endl;
}
};
class EHostMmioW : public event {
public:
uint64_t id;
uint64_t addr;
uint64_t size;
EHostMmioW(uint64_t ts_, uint64_t id_, uint64_t addr_, uint64_t size_)
: event(ts_), id(id_), addr(addr_), size(size_) {
}
virtual ~EHostMmioW() {
}
virtual void dump(std::ostream &out) {
out << ts << ": H.MMIOW id=" << id << " addr=" << addr << " size=" << size
<< std::endl;
}
};
class EHostMmioC : public event {
public:
uint64_t id;
EHostMmioC(uint64_t ts_, uint64_t id_) : event(ts_), id(id_) {
}
virtual ~EHostMmioC() {
}
virtual void dump(std::ostream &out) {
out << ts << ": H.MMIOC id=" << id << std::endl;
}
};
class e_nic_msix : public event {
public:
uint16_t vec;
e_nic_msix(uint64_t ts_, uint16_t vec_) : event(ts_), vec(vec_) {
}
virtual ~e_nic_msix() {
}
virtual void dump(std::ostream &out) {
out << ts << ": N.MSIX " << vec << std::endl;
}
};
class e_nic_dma_i : public event {
public:
uint64_t id;
uint64_t addr;
uint64_t size;
e_nic_dma_i(uint64_t ts_, uint64_t id_, uint64_t addr_, uint64_t size_)
: event(ts_), id(id_), addr(addr_), size(size_) {
}
virtual ~e_nic_dma_i() {
}
virtual void dump(std::ostream &out) {
out << ts << ": N.DMAI id=" << id << " addr=" << addr << " size=" << size
<< std::endl;
}
};
class e_nic_dma_c : public event {
public:
uint64_t id;
e_nic_dma_c(uint64_t ts_, uint64_t id_) : event(ts_), id(id_) {
}
virtual ~e_nic_dma_c() {
}
virtual void dump(std::ostream &out) {
out << ts << ": N.DMAC id=" << id << std::endl;
}
};
class e_nic_mmio_r : public event {
public:
uint64_t addr;
uint64_t size;
uint64_t val;
e_nic_mmio_r(uint64_t ts_, uint64_t addr_, uint64_t size_, uint64_t val_)
: event(ts_), addr(addr_), size(size_), val(val_) {
}
virtual ~e_nic_mmio_r() {
}
virtual void dump(std::ostream &out) {
out << ts << ": N.MMIOR addr=" << addr << " size=" << size << " val=" << val
<< std::endl;
}
};
class e_nic_mmio_w : public event {
public:
uint64_t addr;
uint64_t size;
uint64_t val;
e_nic_mmio_w(uint64_t ts_, uint64_t addr_, uint64_t size_, uint64_t val_)
: event(ts_), addr(addr_), size(size_), val(val_) {
}
virtual ~e_nic_mmio_w() {
}
virtual void dump(std::ostream &out) {
out << ts << ": N.MMIOW addr=" << addr << " size=" << size << " val=" << val
<< std::endl;
}
};
class e_nic_tx : public event {
public:
uint16_t len;
e_nic_tx(uint64_t ts_, uint16_t len_) : event(ts_), len(len_) {
}
virtual ~e_nic_tx() {
}
virtual void dump(std::ostream &out) {
out << ts << ": N.TX " << len << std::endl;
}
};
class e_nic_rx : public event {
public:
uint16_t len;
e_nic_rx(uint64_t ts_, uint16_t len_) : event(ts_), len(len_) {
}
virtual ~e_nic_rx() {
}
virtual void dump(std::ostream &out) {
out << ts << ": N.RX " << len << std::endl;
}
};
/*
* Copyright 2021 Max Planck Institute for Software Systems, and
* National University of Singapore
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <iostream>
#include "trace/events.h"
#include "trace/parser.h"
#include "trace/process.h"
namespace bio = boost::iostreams;
gem5_parser::gem5_parser(sym_map &syms_) : syms(syms_) {
}
gem5_parser::~gem5_parser() {
}
void gem5_parser::process_msg(uint64_t ts, char *comp_name,
size_t comp_name_len, char *msg, size_t msg_len) {
parser p(msg, msg_len, 0);
/*if (ts < ts_first)
return;*/
if (comp_name_len == 18 && !memcmp(comp_name, "system.switch_cpus", 18)) {
// cpu_lines++;
if (!p.consume_str("T0 : 0x"))
return;
uint64_t addr;
if (!p.consume_hex(addr))
return;
if (!p.consume_char('.')) {
// instructions don't have a .X
/*if (prevInstr)
yield(prevInstr)*/
yield(std::make_shared<EHostInstr>(ts, addr));
if (const std::string *s = syms.lookup(addr)) {
yield(std::make_shared<EHostCall>(ts, *s));
}
} else {
// micro-op
if (!p.skip_until_after(" : ") || !p.skip_until_after(" : "))
return;
if (p.consume_str("halt")) {
yield(std::make_shared<EHostHalt>(ts, addr));
}
/*if (p.consume_str("MemRead")) {
if (prevInstr)
prevInstr->fMemR = true;
} else if (p.consume_str("MemWrite")) {
if (prevInstr)
prevInstr->fMemW = true;
}*/
}
} else if (comp_name_len == 18 &&
!memcmp(comp_name, "system.pc.ethernet", 18)) {
// eth_lines++;
/*std::cout.write(msg, msg_len);
std::cout << std::endl;*/
if (!p.consume_str("cosim: "))
return;
uint64_t id = 0;
uint64_t addr = 0;
uint64_t size = 0;
if (p.consume_str("received ")) {
if (p.consume_str("MSI-X intr vec ") && p.consume_dec(id)) {
yield(std::make_shared<EHostMsiX>(ts, id));
} else if (p.consume_str("DMA read id ") && p.consume_dec(id) &&
p.consume_str(" addr ") && p.consume_hex(addr) &&
p.consume_str(" size ") && p.consume_dec(size)) {
// cosim: received DMA read id 94113551511792 addr 23697ad60
// size 20
yield(std::make_shared<EHostDmaR>(ts, id, addr, size));
} else if (p.consume_str("DMA write id ") && p.consume_dec(id) &&
p.consume_str(" addr ") && p.consume_hex(addr) &&
p.consume_str(" size ") && p.consume_dec(size)) {
// cosim: received DMA write id 94113551528032 addr 236972000
// size 4
yield(std::make_shared<EHostDmaW>(ts, id, addr, size));
} else if (p.consume_str("read completion id ") && p.consume_dec(id)) {
// cosim: received read completion id 94583743418112
yield(std::make_shared<EHostMmioC>(ts, id));
} else if (p.consume_str("write completion id ") && p.consume_dec(id)) {
// cosim: received write completion id 94583743418736
yield(std::make_shared<EHostMmioC>(ts, id));
}
} else if (p.consume_str("sending ")) {
if (p.consume_str("read addr ") && p.consume_hex(addr) &&
p.consume_str(" size ") && p.consume_dec(size) &&
p.consume_str(" id ") && p.consume_dec(id)) {
// cosim: sending read addr c012a500 size 4 id 94583743418112
yield(std::make_shared<EHostMmioR>(ts, id, addr, size));
} else if (p.consume_str("write addr ") && p.consume_hex(addr) &&
p.consume_str(" size ") && p.consume_dec(size) &&
p.consume_str(" id ") && p.consume_dec(id)) {
// cosim: sending write addr c0108000 size 4 id 94584005188256
yield(std::make_shared<EHostMmioW>(ts, id, addr, size));
}
} else if (p.consume_str("completed DMA id ") && p.consume_dec(id)) {
yield(std::make_shared<EHostDmaC>(ts, id));
}
}
/*if (!cur_event) {
std::cout.write(msg, msg_len);
std::cout << std::endl;
}*/
}
void gem5_parser::process_line(char *line, size_t line_len) {
size_t pos = 0;
size_t line_start = pos;
size_t comp_name_start = 0;
size_t comp_name_len = 0;
bool valid = true;
// eat spaces
for (; pos < line_len && line[pos] == ' '; pos++) {
}
// parse ts
uint64_t ts = 0;
size_t ts_len = 0;
for (; pos < line_len && line[pos] >= '0' && line[pos] <= '9'; pos++) {
ts = ts * 10 + line[pos] - '0';
ts_len++;
}
if (ts_len == 0) {
valid = false;
goto out;
}
// skip colon
if (line[pos] != ':') {
valid = false;
goto out;
}
pos++;
// skip space
if (line[pos] != ' ') {
valid = false;
goto out;
}
pos++;
comp_name_start = pos;
for (; pos < line_len && line[pos] != ' ' && line[pos] != '\n';
pos++, comp_name_len++) {
}
// skip space
if (line[pos] != ' ') {
valid = false;
goto out;
}
if (line[pos - 1] != ':') {
valid = false;
goto out;
}
comp_name_len--;
pos++;
out:
size_t msg_start = pos;
size_t msg_len = line_len - msg_start;
line[line_len - 1] = 0;
if (valid) {
process_msg(ts, line + comp_name_start, comp_name_len, line + msg_start,
msg_len);
} else {
std::cout << line + line_start << std::endl;
std::cout << pos << std::endl;
}
return;
}
/*
* Copyright 2021 Max Planck Institute for Software Systems, and
* National University of Singapore
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/iostreams/filtering_streambuf.hpp>
#include <fstream>
#include <iostream>
#include "trace/events.h"
#include "trace/parser.h"
#include "trace/process.h"
namespace bio = boost::iostreams;
log_parser::log_parser()
: inf(nullptr), gz_file(nullptr), gz_in(nullptr), buf_len(0), buf_pos(0) {
buf = new char[block_size];
}
log_parser::~log_parser() {
if (inf)
delete inf;
if (gz_file) {
delete gz_in;
delete gz_file;
}
delete[] buf;
}
bool log_parser::next_block() {
if (buf_pos == buf_len) {
buf_pos = 0;
} else {
memmove(buf, buf + buf_pos, buf_len - buf_pos);
buf_pos = buf_len - buf_pos;
}
inf->read(buf + buf_pos, block_size - buf_pos);
size_t newlen = inf->gcount();
buf_len = buf_pos + newlen;
buf_pos = 0;
return newlen != 0;
}
void log_parser::open(const char *path) {
inf = new std::ifstream(path, std::ios_base::in);
}
void log_parser::open_gz(const char *path) {
gz_file = new std::ifstream(path, std::ios_base::in | std::ios_base::binary);
gz_in = new bio::filtering_streambuf<bio::input>();
gz_in->push(bio::gzip_decompressor());
gz_in->push(*gz_file);
inf = new std::istream(gz_in);
}
size_t log_parser::try_line() {
size_t pos = buf_pos;
size_t line_len = 0;
for (; pos < buf_len && buf[pos] != '\n'; pos++, line_len++) {
}
if (pos >= buf_len) {
// line is incomplete
return 0;
}
process_line(buf + buf_pos, line_len);
return pos + 1;
}
bool log_parser::next_event() {
if (buf_len == 0 && !next_block()) {
std::cerr << "escape 0" << std::endl;
return false;
}
got_event = false;
do {
size_t newpos = try_line();
if (!newpos) {
if (!next_block()) {
std::cerr << "escape 1" << std::endl;
return false;
}
newpos = try_line();
if (!newpos) {
std::cerr << "escape 2" << std::endl;
return false;
}
}
buf_pos = newpos;
} while (!got_event);
return true;
}
void log_parser::read_coro(coro_t::push_type &sink_) {
sink = &sink_;
while (next_event()) {
}
}
void log_parser::yield(std::shared_ptr<event> ev) {
got_event = true;
ev->source = this;
(*sink)(ev);
}
/*
* Copyright 2021 Max Planck Institute for Software Systems, and
* National University of Singapore
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <iostream>
#include "trace/events.h"
#include "trace/parser.h"
#include "trace/process.h"
namespace bio = boost::iostreams;
nicbm_parser::~nicbm_parser() {
}
void nicbm_parser::process_line(char *line, size_t line_len) {
parser p(line, line_len, 0);
uint64_t ts;
if (!p.consume_dec(ts))
return;
if (!p.consume_str(" nicbm: "))
return;
uint64_t id, addr, len, val;
if (p.consume_str("read(off=0x")) {
if (p.consume_hex(addr) && p.consume_str(", len=") && p.consume_dec(len) &&
p.consume_str(", val=0x") && p.consume_hex(val)) {
yield(std::make_shared<e_nic_mmio_r>(ts, addr, len, val));
}
} else if (p.consume_str("write(off=0x")) {
if (p.consume_hex(addr) && p.consume_str(", len=") && p.consume_dec(len) &&
p.consume_str(", val=0x") && p.consume_hex(val)) {
yield(std::make_shared<e_nic_mmio_w>(ts, addr, len, val));
}
} else if (p.consume_str("issuing dma op 0x")) {
if (p.consume_hex(id) && p.consume_str(" addr ") && p.consume_hex(addr) &&
p.consume_str(" len ") && p.consume_hex(len)) {
yield(std::make_shared<e_nic_dma_i>(ts, id, addr, len));
}
} else if (p.consume_str("completed dma read op 0x") ||
p.consume_str("completed dma write op 0x")) {
if (p.consume_hex(id) && p.consume_str(" addr ") && p.consume_hex(addr) &&
p.consume_str(" len ") && p.consume_hex(len)) {
yield(std::make_shared<e_nic_dma_c>(ts, id));
}
} else if (p.consume_str("issue MSI-X interrupt vec ")) {
if (p.consume_dec(id)) {
yield(std::make_shared<e_nic_msix>(ts, id));
}
} else if (p.consume_str("eth tx: len ")) {
if (p.consume_dec(len)) {
yield(std::make_shared<e_nic_tx>(ts, len));
}
} else if (p.consume_str("eth rx: port 0 len ")) {
if (p.consume_dec(len)) {
yield(std::make_shared<e_nic_rx>(ts, len));
}
#if 1
}
#else
} else {
std::cerr.write(line, line_len);
std::cerr << std::endl;
}
#endif
}
/*
* Copyright 2021 Max Planck Institute for Software Systems, and
* National University of Singapore
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#pragma once
#include <cstddef>
#include <cstring>
#include <string>
class parser {
protected:
const char *buf;
size_t buf_len;
size_t pos;
public:
parser(const char *buf_, size_t buf_len_, size_t start_pos = 0)
: buf(buf_), buf_len(buf_len_), pos(start_pos) {
}
inline size_t trim_spaces() {
size_t cnt = 0;
for (; pos < buf_len && buf[pos] == ' '; pos++, cnt++) {
}
return cnt;
}
inline bool consume_char(char c) {
if (pos == buf_len || buf[pos] != c) {
return false;
}
pos++;
return true;
}
inline bool consume_hex(uint64_t &val) {
size_t val_len = 0;
val = 0;
for (; pos < buf_len; pos++) {
char d = buf[pos];
bool is_d = d >= '0' && d <= '9';
bool is_x = d >= 'a' && d <= 'f';
if (!is_d && !is_x)
break;
val <<= 4;
if (is_d)
val |= d - '0';
else
val |= d - 'a' + 10;
val_len++;
}
return val_len > 0;
}
inline bool consume_dec(uint64_t &val) {
size_t val_len = 0;
val = 0;
for (; pos < buf_len; pos++) {
char d = buf[pos];
if (d < '0' || d > '9')
break;
val = val * 10 + (d - '0');
val_len++;
}
return val_len > 0;
}
inline bool consume_str(const char *str) {
size_t str_len = strlen(str);
if (pos + str_len > buf_len || memcmp(buf + pos, str, str_len)) {
return false;
}
pos += str_len;
return true;
}
inline bool extract_until(char end_c, std::string &str) {
size_t end = pos;
for (; end < buf_len && buf[end] != end_c; end++) {
}
if (end >= buf_len)
return false;
str.assign(buf + pos, end - pos);
pos = end + 1;
return true;
}
inline bool skip_until_after(const char *s) {
size_t s_len = strlen(s);
if (pos + s_len > buf_len)
return false;
size_t end = pos;
for (; end <= buf_len - s_len; end++) {
if (buf[end] == s[0] && !memcmp(buf + end, s, s_len)) {
pos = end + s_len;
return true;
}
}
return false;
}
};
/*
* Copyright 2021 Max Planck Institute for Software Systems, and
* National University of Singapore
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "trace/process.h"
#include <algorithm>
#include <boost/bind.hpp>
#include <boost/foreach.hpp>
#include <iostream>
#include <memory>
#include <utility>
#include <vector>
#include "trace/events.h"
#include "trace/parser.h"
template <typename T>
struct event_pair_cmp {
bool operator()(const std::pair<T, std::shared_ptr<event>> l,
const std::pair<T, std::shared_ptr<event>> r) const {
return l.second->ts < r.second->ts;
}
};
/** merge multiple event streams into one ordered by timestamp */
void MergeEvents(coro_t::push_type &sink,
std::set<coro_t::pull_type *> &all_parsers) {
typedef std::pair<coro_t::pull_type *, std::shared_ptr<event>> itpair_t;
// create set of pairs of source and next event, ordered by timestamp of next
// event.
std::set<itpair_t, event_pair_cmp<coro_t::pull_type *>> active;
// initially populate the set
for (auto p : all_parsers) {
if (*p) {
auto ev = p->get();
(*p)();
active.insert(std::make_pair(p, ev));
}
}
// iterate until there are no more active sources
while (!active.empty()) {
// grab event with lowest timestamp
auto i = active.begin();
itpair_t p = *i;
active.erase(i);
// emit event
sink(p.second);
// check if there is another event in the source, if so, re-enqueue
if (*p.first) {
auto ev = p.first->get();
(*p.first)();
active.insert(std::make_pair(p.first, ev));
}
}
}
void Printer(coro_t::pull_type &source) {
uint64_t ts_off = 0;
for (auto ev : source) {
std::shared_ptr<EHostCall> hc;
std::shared_ptr<EHostInstr> hi;
if ((hi = std::dynamic_pointer_cast<EHostInstr>(ev))) {
continue;
} else if ((hc = std::dynamic_pointer_cast<EHostCall>(ev)) &&
strcmp(ev->source->label, "C") && hc->fun == "__sys_sendto") {
std::cout << "---------- REQ START:" << ev->ts << std::endl;
ts_off = ev->ts;
}
std::cout << ev->source->label << " ";
ev->ts -= ts_off;
ev->ts /= 1000;
ev->dump(std::cout);
}
}
void Consumer(coro_t::pull_type &source) {
for (auto ev : source) {
}
}
struct InstStatsData {
const char *label;
uint64_t nInsts;
uint64_t tMin;
uint64_t tMax;
uint64_t tMean;
std::vector<uint64_t> tAll;
};
void InstStats(coro_t::push_type &sink, coro_t::pull_type &source,
struct InstStatsData &data) {
uint64_t last_ts = 0;
uint64_t first_ts = 0;
data.nInsts = 0;
for (auto ev : source) {
std::shared_ptr<EHostInstr> hi;
if ((hi = std::dynamic_pointer_cast<EHostInstr>(ev))) {
if (!last_ts) {
// first instruction
first_ts = hi->ts;
data.tMin = UINT64_MAX;
data.tMax = 0;
} else {
uint64_t lat = hi->ts - last_ts;
data.nInsts++;
data.tAll.push_back(lat);
if (lat < data.tMin)
data.tMin = lat;
if (lat > data.tMax)
data.tMax = lat;
/*if (lat > 4000)
std::cout << "ILAT: " << lat << " " << std::hex << hi->pc <<
std::dec << " " << hi->ts << std::endl;*/
}
last_ts = hi->ts;
// last_pc = hi->pc;
}
sink(ev);
}
if (data.nInsts != 0)
data.tMean = (last_ts - first_ts) / data.nInsts;
else
data.tMean = 0;
}
int main(int argc, char *argv[]) {
if (argc != 5) {
std::cerr << "Usage: process CLIENT_HLOG CLIENT_NLOG SERVER_HLOG "
"SERVER_CLOG"
<< std::endl;
return 1;
}
sym_map syms;
syms.add_filter("entry_SYSCALL_64");
syms.add_filter("__do_sys_gettimeofday");
syms.add_filter("__sys_sendto");
syms.add_filter("i40e_lan_xmit_frame");
syms.add_filter("syscall_return_via_sysret");
syms.add_filter("__sys_recvfrom");
syms.add_filter("deactivate_task");
syms.add_filter("interrupt_entry");
syms.add_filter("i40e_msix_clean_rings");
syms.add_filter("napi_schedule_prep");
syms.add_filter("__do_softirq");
syms.add_filter("trace_napi_poll");
syms.add_filter("net_rx_action");
syms.add_filter("i40e_napi_poll");
syms.add_filter("activate_task");
syms.add_filter("copyout");
syms.load_file("linux.dump", 0);
syms.load_file("i40e.dump", 0xffffffffa0000000ULL);
std::cerr << "map loaded" << std::endl;
std::set<log_parser *> all_parsers;
gem5_parser ch(syms);
ch.open(argv[1]);
ch.label = "C";
all_parsers.insert(&ch);
gem5_parser sh(syms);
sh.open(argv[3]);
sh.label = "S";
all_parsers.insert(&sh);
nicbm_parser cn;
cn.open(argv[2]);
cn.label = "C";
all_parsers.insert(&cn);
nicbm_parser sn;
sn.open(argv[4]);
sn.label = "S";
all_parsers.insert(&sn);
std::cerr << "Opened all" << std::endl;
std::set<coro_t::pull_type *> sources;
std::set<InstStatsData *> isds;
for (auto p : all_parsers) {
coro_t::pull_type *src = new coro_t::pull_type(
boost::bind(&log_parser::read_coro, boost::ref(*p), _1));
InstStatsData *isd = new InstStatsData;
isd->label = p->label;
coro_t::pull_type *istat = new coro_t::pull_type(
boost::bind(InstStats, _1, boost::ref(*src), boost::ref(*isd)));
sources.insert(istat);
isds.insert(isd);
}
coro_t::pull_type merged(boost::bind(MergeEvents, _1, boost::ref(sources)));
Consumer(merged);
std::cout << "Stats:" << std::endl;
for (auto isd : isds) {
if (!isd->nInsts)
continue;
std::sort(isd->tAll.begin(), isd->tAll.end());
std::cout << " - " << isd->label << std::endl;
std::cout << " Instrs: " << isd->nInsts << std::endl;
std::cout << " Mean instr time: " << isd->tMean << std::endl;
for (int i = 0; i <= 100; i += 1)
std::cout << " P[" << i << "] instr time: "
<< isd->tAll[isd->tAll.size() * i / 100 - (i == 100 ? 1 : 0)]
<< std::endl;
}
}
/*
* Copyright 2021 Max Planck Institute for Software Systems, and
* National University of Singapore
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#pragma once
#include <boost/coroutine2/all.hpp>
#include <boost/iostreams/filtering_streambuf.hpp>
#include <map>
#include <memory>
#include <set>
#include <string>
#include "trace/events.h"
typedef boost::coroutines2::asymmetric_coroutine<std::shared_ptr<event>> coro_t;
class sym_map {
protected:
bool filter_en;
bool insmap_en;
std::set<std::string> filter;
public:
std::map<uint64_t, std::string> map;
std::map<uint64_t, std::string> map_ins;
sym_map();
void add_filter(const std::string &sym);
void load_file(const char *path, uint64_t offset = 0);
inline const std::string *lookup(uint64_t addr) {
auto it = map.find(addr);
if (it == map.end())
return nullptr;
return &it->second;
}
};
class log_parser {
protected:
std::istream *inf;
std::ifstream *gz_file;
boost::iostreams::filtering_streambuf<boost::iostreams::input> *gz_in;
static const size_t block_size = 16 * 1024 * 1024;
char *buf;
size_t buf_len;
size_t buf_pos;
coro_t::push_type *sink;
bool got_event;
bool next_block();
size_t try_line();
virtual void process_line(char *line, size_t len) = 0;
bool next_event();
void yield(std::shared_ptr<event> ev);
public:
const char *label;
log_parser();
virtual ~log_parser();
void open(const char *path);
void open_gz(const char *path);
void read_coro(coro_t::push_type &sink_);
};
class gem5_parser : public log_parser {
protected:
sym_map &syms;
std::shared_ptr<EHostInstr> prevInstr;
virtual void process_line(char *line, size_t len);
void process_msg(uint64_t ts, char *comp_name, size_t comp_name_len,
char *msg, size_t msg_len);
public:
explicit gem5_parser(sym_map &syms_);
virtual ~gem5_parser();
};
class nicbm_parser : public log_parser {
protected:
virtual void process_line(char *line, size_t len);
public:
virtual ~nicbm_parser();
};
# Copyright 2021 Max Planck Institute for Software Systems, and
# National University of Singapore
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
include mk/subdir_pre.mk
bin_trace_process := $(d)process
OBJS := $(addprefix $(d), process.o sym_map.o log_parser.o gem5.o nicbm.o)
$(bin_trace_process): $(OBJS) -lboost_iostreams -lboost_coroutine \
-lboost_context
CLEAN := $(bin_trace_process) $(OBJS)
ALL := $(bin_trace_process)
include mk/subdir_post.mk
/*
* Copyright 2021 Max Planck Institute for Software Systems, and
* National University of Singapore
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <fstream>
#include "trace/parser.h"
#include "trace/process.h"
sym_map::sym_map() : filter_en(false), insmap_en(false) {
}
void sym_map::add_filter(const std::string &sym) {
filter_en = true;
filter.insert(sym);
}
void sym_map::load_file(const char *path, uint64_t offset) {
std::ifstream file(path, std::ios_base::in | std::ios_base::binary);
std::string line;
std::string label = "";
while (std::getline(file, line)) {
parser p(line.c_str(), line.size());
uint64_t addr;
p.trim_spaces();
p.consume_hex(addr);
if (p.consume_char(':')) {
if (insmap_en && !label.empty()) {
map_ins[addr + offset] = label;
}
} else if (p.consume_str(" <")) {
p.extract_until('>', label);
if (!filter_en || filter.find(label) != filter.end())
map[addr + offset] = label;
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment