diff --git a/configs/boot/netperf-stream-nt-client.rcS b/configs/boot/netperf-stream-nt-client.rcS new file mode 100644 index 000000000..96b6b38c3 --- /dev/null +++ b/configs/boot/netperf-stream-nt-client.rcS @@ -0,0 +1,45 @@ +#!/bin/sh +SERVER=10.0.0.1 +CLIENT=10.0.0.2 + +echo "setting up network..." +ifconfig lo 127.0.0.1 +ifconfig eth0 $CLIENT txqueuelen 1000 + +echo "0" > /proc/sys/net/ipv4/tcp_timestamps +echo "0" > /proc/sys/net/ipv4/tcp_sack +echo "5000000 5000000 5000000" > /proc/sys/net/ipv4/tcp_rmem +echo "5000000 5000000 5000000" > /proc/sys/net/ipv4/tcp_wmem +echo "5000000 5000000 5000000" > /proc/sys/net/ipv4/tcp_mem +echo "262143" > /proc/sys/net/core/rmem_max +echo "262143" > /proc/sys/net/core/wmem_max +echo "262143" > /proc/sys/net/core/rmem_default +echo "262143" > /proc/sys/net/core/wmem_default +echo "262143" > /proc/sys/net/core/optmem_max +echo "100000" > /proc/sys/net/core/netdev_max_backlog + +echo -n "waiting for server..." +/usr/bin/netcat -c -l -p 8000 + +BINARY=/benchmarks/netperf/netperf +TEST="TCP_STREAM" +SHORT_ARGS="-l -100k" +LONG_ARGS="-- -m 65536 -M 65536 -s 262144 -S 262144" + + +SHORT="$BINARY -H $SERVER -t $TEST $SHORT_ARGS" +LONG="$BINARY -H $SERVER -t $TEST $LONG_ARGS" + +echo "starting test..." +echo "netperf warmup" +echo $SHORT +eval $SHORT + +echo "netperf benchmark" +echo $LONG +/sbin/m5 ivlb 1 +/sbin/m5 resetstats +/sbin/m5 dumpresetstats 200000000 2000000000 +/sbin/m5 checkpoint 200000000 2000000000 +eval $LONG +/sbin/m5 exit diff --git a/dev/etherlink.cc b/dev/etherlink.cc index 1e2be41fe..d637e152a 100644 --- a/dev/etherlink.cc +++ b/dev/etherlink.cc @@ -195,7 +195,7 @@ EtherLink::Link::unserialize(Checkpoint *cp, const string §ion) bool packet_exists; UNSERIALIZE_SCALAR(packet_exists); if (packet_exists) { - packet = new PacketData; + packet = new PacketData(16384); packet->unserialize("packet", cp, section); } @@ -244,7 +244,7 @@ void LinkDelayEvent::unserialize(Checkpoint *cp, const string §ion) { Event::unserialize(cp, section); - packet = new PacketData; + packet = new PacketData(16384); packet->unserialize("packet", cp, section); } diff --git a/dev/ethertap.cc b/dev/ethertap.cc index 03f2724b1..1603a9bd3 100644 --- a/dev/ethertap.cc +++ b/dev/ethertap.cc @@ -219,8 +219,7 @@ EtherTap::process(int revent) while (data_len != 0 && buffer_offset >= data_len + sizeof(u_int32_t)) { PacketPtr packet; - packet = new PacketData; - packet->data = new uint8_t[data_len]; + packet = new PacketData(data_len); packet->length = data_len; memcpy(packet->data, data, data_len); diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc index c650c7943..eee8fbbce 100644 --- a/dev/ns_gige.cc +++ b/dev/ns_gige.cc @@ -274,6 +274,180 @@ NSGigE::regStats() .prereq(rxBytes) ; + postedSwi + .name(name() + ".postedSwi") + .desc("number of software interrupts posted to CPU") + .precision(0) + ; + + totalSwi + .name(name() + ".totalSwi") + .desc("number of total Swi written to ISR") + .precision(0) + ; + + coalescedSwi + .name(name() + ".coalescedSwi") + .desc("average number of Swi's coalesced into each post") + .precision(0) + ; + + postedRxIdle + .name(name() + ".postedRxIdle") + .desc("number of rxIdle interrupts posted to CPU") + .precision(0) + ; + + totalRxIdle + .name(name() + ".totalRxIdle") + .desc("number of total RxIdle written to ISR") + .precision(0) + ; + + coalescedRxIdle + .name(name() + ".coalescedRxIdle") + .desc("average number of RxIdle's coalesced into each post") + .precision(0) + ; + + postedRxOk + .name(name() + ".postedRxOk") + .desc("number of RxOk interrupts posted to CPU") + .precision(0) + ; + + totalRxOk + .name(name() + ".totalRxOk") + .desc("number of total RxOk written to ISR") + .precision(0) + ; + + coalescedRxOk + .name(name() + ".coalescedRxOk") + .desc("average number of RxOk's coalesced into each post") + .precision(0) + ; + + postedRxDesc + .name(name() + ".postedRxDesc") + .desc("number of RxDesc interrupts posted to CPU") + .precision(0) + ; + + totalRxDesc + .name(name() + ".totalRxDesc") + .desc("number of total RxDesc written to ISR") + .precision(0) + ; + + coalescedRxDesc + .name(name() + ".coalescedRxDesc") + .desc("average number of RxDesc's coalesced into each post") + .precision(0) + ; + + postedTxOk + .name(name() + ".postedTxOk") + .desc("number of TxOk interrupts posted to CPU") + .precision(0) + ; + + totalTxOk + .name(name() + ".totalTxOk") + .desc("number of total TxOk written to ISR") + .precision(0) + ; + + coalescedTxOk + .name(name() + ".coalescedTxOk") + .desc("average number of TxOk's coalesced into each post") + .precision(0) + ; + + postedTxIdle + .name(name() + ".postedTxIdle") + .desc("number of TxIdle interrupts posted to CPU") + .precision(0) + ; + + totalTxIdle + .name(name() + ".totalTxIdle") + .desc("number of total TxIdle written to ISR") + .precision(0) + ; + + coalescedTxIdle + .name(name() + ".coalescedTxIdle") + .desc("average number of TxIdle's coalesced into each post") + .precision(0) + ; + + postedTxDesc + .name(name() + ".postedTxDesc") + .desc("number of TxDesc interrupts posted to CPU") + .precision(0) + ; + + totalTxDesc + .name(name() + ".totalTxDesc") + .desc("number of total TxDesc written to ISR") + .precision(0) + ; + + coalescedTxDesc + .name(name() + ".coalescedTxDesc") + .desc("average number of TxDesc's coalesced into each post") + .precision(0) + ; + + postedRxOrn + .name(name() + ".postedRxOrn") + .desc("number of RxOrn posted to CPU") + .precision(0) + ; + + totalRxOrn + .name(name() + ".totalRxOrn") + .desc("number of total RxOrn written to ISR") + .precision(0) + ; + + coalescedRxOrn + .name(name() + ".coalescedRxOrn") + .desc("average number of RxOrn's coalesced into each post") + .precision(0) + ; + + coalescedTotal + .name(name() + ".coalescedTotal") + .desc("average number of interrupts coalesced into each post") + .precision(0) + ; + + postedInterrupts + .name(name() + ".postedInterrupts") + .desc("number of posts to CPU") + .precision(0) + ; + + droppedPackets + .name(name() + ".droppedPackets") + .desc("number of packets dropped") + .precision(0) + ; + + coalescedSwi = totalSwi / postedInterrupts; + coalescedRxIdle = totalRxIdle / postedInterrupts; + coalescedRxOk = totalRxOk / postedInterrupts; + coalescedRxDesc = totalRxDesc / postedInterrupts; + coalescedTxOk = totalTxOk / postedInterrupts; + coalescedTxIdle = totalTxIdle / postedInterrupts; + coalescedTxDesc = totalTxDesc / postedInterrupts; + coalescedRxOrn = totalRxOrn / postedInterrupts; + + coalescedTotal = (totalSwi + totalRxIdle + totalRxOk + totalRxDesc + totalTxOk + + totalTxIdle + totalTxDesc + totalRxOrn) / postedInterrupts; + txBandwidth = txBytes * Stats::constant(8) / simSeconds; rxBandwidth = rxBytes * Stats::constant(8) / simSeconds; txPacketRate = txPackets / simSeconds; @@ -931,6 +1105,33 @@ NSGigE::devIntrPost(uint32_t interrupts) interrupts &= ~ISR_NOIMPL; regs.isr |= interrupts; + if (interrupts & regs.imr) { + if (interrupts & ISR_SWI) { + totalSwi++; + } + if (interrupts & ISR_RXIDLE) { + totalRxIdle++; + } + if (interrupts & ISR_RXOK) { + totalRxOk++; + } + if (interrupts & ISR_RXDESC) { + totalRxDesc++; + } + if (interrupts & ISR_TXOK) { + totalTxOk++; + } + if (interrupts & ISR_TXIDLE) { + totalTxIdle++; + } + if (interrupts & ISR_TXDESC) { + totalTxDesc++; + } + if (interrupts & ISR_RXORN) { + totalRxOrn++; + } + } + DPRINTF(EthernetIntr, "interrupt written to ISR: intr=%#x isr=%#x imr=%#x\n", interrupts, regs.isr, regs.imr); @@ -943,12 +1144,46 @@ NSGigE::devIntrPost(uint32_t interrupts) } } +/* writing this interrupt counting stats inside this means that this function + is now limited to being used to clear all interrupts upon the kernel + reading isr and servicing. just telling you in case you were thinking + of expanding use. +*/ void NSGigE::devIntrClear(uint32_t interrupts) { if (interrupts & ISR_RESERVE) panic("Cannot clear a reserved interrupt"); + if (regs.isr & regs.imr & ISR_SWI) { + postedSwi++; + } + if (regs.isr & regs.imr & ISR_RXIDLE) { + postedRxIdle++; + } + if (regs.isr & regs.imr & ISR_RXOK) { + postedRxOk++; + } + if (regs.isr & regs.imr & ISR_RXDESC) { + postedRxDesc++; + } + if (regs.isr & regs.imr & ISR_TXOK) { + postedTxOk++; + } + if (regs.isr & regs.imr & ISR_TXIDLE) { + postedTxIdle++; + } + if (regs.isr & regs.imr & ISR_TXDESC) { + postedTxDesc++; + } + if (regs.isr & regs.imr & ISR_RXORN) { + postedRxOrn++; + } + + if (regs.isr & regs.imr & (ISR_SWI | ISR_RXIDLE | ISR_RXOK | ISR_RXDESC | + ISR_TXOK | ISR_TXIDLE | ISR_TXDESC | ISR_RXORN) ) + postedInterrupts++; + interrupts &= ~ISR_NOIMPL; regs.isr &= ~interrupts; @@ -1767,8 +2002,7 @@ NSGigE::txKick() case txFifoBlock: if (!txPacket) { DPRINTF(EthernetSM, "****starting the tx of a new packet****\n"); - txPacket = new PacketData; - txPacket->data = new uint8_t[16384]; + txPacket = new PacketData(16384); txPacketBufPtr = txPacket->data; } @@ -2034,6 +2268,7 @@ NSGigE::recvPacket(PacketPtr packet) if (rxFifo.avail() < packet->length) { DPRINTF(Ethernet, "packet will not fit in receive buffer...packet dropped\n"); + droppedPackets++; devIntrPost(ISR_RXORN); return false; } @@ -2257,7 +2492,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion) bool txPacketExists; UNSERIALIZE_SCALAR(txPacketExists); if (txPacketExists) { - txPacket = new PacketData; + txPacket = new PacketData(16384); txPacket->unserialize("txPacket", cp, section); uint32_t txPktBufPtr; UNSERIALIZE_SCALAR(txPktBufPtr); @@ -2269,7 +2504,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(rxPacketExists); rxPacket = 0; if (rxPacketExists) { - rxPacket = new PacketData; + rxPacket = new PacketData(16384); rxPacket->unserialize("rxPacket", cp, section); uint32_t rxPktBufPtr; UNSERIALIZE_SCALAR(rxPktBufPtr); diff --git a/dev/ns_gige.hh b/dev/ns_gige.hh index 90711d63f..8d6016126 100644 --- a/dev/ns_gige.hh +++ b/dev/ns_gige.hh @@ -385,6 +385,33 @@ class NSGigE : public PciDev Stats::Formula rxBandwidth; Stats::Formula txPacketRate; Stats::Formula rxPacketRate; + Stats::Scalar<> postedSwi; + Stats::Formula coalescedSwi; + Stats::Scalar<> totalSwi; + Stats::Scalar<> postedRxIdle; + Stats::Formula coalescedRxIdle; + Stats::Scalar<> totalRxIdle; + Stats::Scalar<> postedRxOk; + Stats::Formula coalescedRxOk; + Stats::Scalar<> totalRxOk; + Stats::Scalar<> postedRxDesc; + Stats::Formula coalescedRxDesc; + Stats::Scalar<> totalRxDesc; + Stats::Scalar<> postedTxOk; + Stats::Formula coalescedTxOk; + Stats::Scalar<> totalTxOk; + Stats::Scalar<> postedTxIdle; + Stats::Formula coalescedTxIdle; + Stats::Scalar<> totalTxIdle; + Stats::Scalar<> postedTxDesc; + Stats::Formula coalescedTxDesc; + Stats::Scalar<> totalTxDesc; + Stats::Scalar<> postedRxOrn; + Stats::Formula coalescedRxOrn; + Stats::Scalar<> totalRxOrn; + Stats::Formula coalescedTotal; + Stats::Scalar<> postedInterrupts; + Stats::Scalar<> droppedPackets; public: Tick cacheAccess(MemReqPtr &req); diff --git a/dev/pciconfigall.cc b/dev/pciconfigall.cc index d5302d9ad..609763e92 100644 --- a/dev/pciconfigall.cc +++ b/dev/pciconfigall.cc @@ -33,10 +33,12 @@ #include #include #include +#include #include "base/trace.hh" #include "dev/pciconfigall.hh" #include "dev/pcidev.hh" +#include "dev/pcireg.h" #include "mem/bus/bus.hh" #include "mem/bus/pio_interface.hh" #include "mem/bus/pio_interface_impl.hh" @@ -65,6 +67,33 @@ PciConfigAll::PciConfigAll(const string &name, Addr a, MemoryController *mmu, devices[x][y] = NULL; } +// If two interrupts share the same line largely bad things will happen. +// Since we don't track how many times an interrupt was set and correspondingly +// cleared two devices on the same interrupt line and assert and deassert each +// others interrupt "line". Interrupts will not work correctly. +void +PciConfigAll::startup() +{ + bitset<256> intLines; + PciDev *tempDev; + uint8_t intline; + + for (int x = 0; x < MAX_PCI_DEV; x++) { + for (int y = 0; y < MAX_PCI_FUNC; y++) { + if (devices[x][y] != NULL) { + tempDev = devices[x][y]; + intline = tempDev->interruptLine(); + if (intLines.test(intline)) + warn("Interrupt line %#X is used multiple times" + "(You probably want to fix this).\n", (uint32_t)intline); + else + intLines.set(intline); + } // devices != NULL + } // PCI_FUNC + } // PCI_DEV + +} + Fault PciConfigAll::read(MemReqPtr &req, uint8_t *data) { diff --git a/dev/pciconfigall.hh b/dev/pciconfigall.hh index d6b37b9b1..9cf2cf972 100644 --- a/dev/pciconfigall.hh +++ b/dev/pciconfigall.hh @@ -115,6 +115,12 @@ class PciConfigAll : public PioDevice virtual Fault write(MemReqPtr &req, const uint8_t *data); + /** + * Start up function to check if more than one person is using an interrupt line + * and print a warning if such a case exists + */ + virtual void startup(); + /** * Serialize this object to the given output stream. * @param os The stream to serialize to. @@ -134,6 +140,7 @@ class PciConfigAll : public PioDevice * @return Tick when the request is done */ Tick cacheAccess(MemReqPtr &req); + }; #endif // __PCICONFIGALL_HH__ diff --git a/dev/pcidev.hh b/dev/pcidev.hh index 73d2e3c44..4b947b560 100644 --- a/dev/pcidev.hh +++ b/dev/pcidev.hh @@ -141,6 +141,10 @@ class PciDev : public DmaDevice intrClear() { plat->clearPciInt(configData->config.hdr.pci0.interruptLine); } + uint8_t + interruptLine() + { return configData->config.hdr.pci0.interruptLine; } + public: /** * Constructor for PCI Dev. This function copies data from the diff --git a/dev/pktfifo.cc b/dev/pktfifo.cc index 00c12ce68..ae82123cf 100644 --- a/dev/pktfifo.cc +++ b/dev/pktfifo.cc @@ -63,7 +63,7 @@ PacketFifo::unserialize(const string &base, Checkpoint *cp, fifo.resize(fifosize); for (int i = 0; i < fifosize; ++i) { - PacketPtr p = new PacketData; + PacketPtr p = new PacketData(16384); p->unserialize(csprintf("%s.packet%d", base, i), cp, section); fifo.push_back(p); } diff --git a/dev/sinic.cc b/dev/sinic.cc index 4dff59a5a..56782b589 100644 --- a/dev/sinic.cc +++ b/dev/sinic.cc @@ -1225,7 +1225,7 @@ Device::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(rxPacketExists); rxPacket = 0; if (rxPacketExists) { - rxPacket = new PacketData; + rxPacket = new PacketData(16384); rxPacket->unserialize("rxPacket", cp, section); uint32_t rxPktBufPtr; UNSERIALIZE_SCALAR(rxPktBufPtr); @@ -1245,7 +1245,7 @@ Device::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(txPacketExists); txPacket = 0; if (txPacketExists) { - txPacket = new PacketData; + txPacket = new PacketData(16384); txPacket->unserialize("txPacket", cp, section); uint32_t txPktBufPtr; UNSERIALIZE_SCALAR(txPktBufPtr); diff --git a/util/stats/info.py b/util/stats/info.py index 15a4a7d73..fa318a650 100644 --- a/util/stats/info.py +++ b/util/stats/info.py @@ -47,28 +47,21 @@ def wrapop(op, lv, rv): return op(lv, rv) -def same(lv, rv): - for lrun,rrun in zip(lv.keys(),rv.keys()): - if lrun != rrun: - print 'lrun != rrun' - print lrun, rrun - print lv.keys() - print rv.keys() +def same(lrun, rrun): + for lx,rx in zip(lrun.keys(),rrun.keys()): + if lx != rx: + print 'lx != rx' + print lx, rx + print lrun.keys() + print rrun.keys() return False - for lx,rx in zip(lv[lrun].keys(),rv[rrun].keys()): - if lx != rx: - print 'lx != rx' - print lx, rx - print lv[lrun].keys() - print rv[rrun].keys() + for ly,ry in zip(lrun[lx].keys(),rrun[rx].keys()): + if ly != ry: + print 'ly != ry' + print ly, ry + print lrun[lx].keys() + print rrun[rx].keys() return False - for ly,ry in zip(lv[lrun][lx].keys(),rv[rrun][rx].keys()): - if ly != ry: - print 'ly != ry' - print ly, ry - print lv[lrun][lx].keys() - print rv[rrun][rx].keys() - return False return True @@ -79,10 +72,15 @@ def binaryop(op, lf, rf): lv = lf.value rv = rf.value - if not same(lv, rv): - raise AttributeError, "run,x,y not identical" + theruns = [] + for r in lv.keys(): + if rv.has_key(r): + if same(lv[r], rv[r]): + theruns.append(r) + else: + raise AttributeError - for run in lv.keys(): + for run in theruns: result[run] = {} for x in lv[run].keys(): result[run][x] = {} diff --git a/util/stats/stats.py b/util/stats/stats.py index 8ec889f09..68ba2b8ea 100755 --- a/util/stats/stats.py +++ b/util/stats/stats.py @@ -39,23 +39,50 @@ def unique(list): map(set.__setitem__, list, []) return set.keys() -def graphdata(runs, tag, label, value): +def graphdata(runs, options, tag, label, value): import info - configs = ['stx', 'ste', 'hte', 'htd', 'ocm', 'occ', 'ocp' ] - benchmarks = [ 'm', 's' ] - dmas = [ 'x', 'd', 'b' ] + configs = ['ste', 'hte', 'htd', 'ocm', 'occ', 'ocp' ] + #benchmarks = [ 'm', 's', 'nb1', 'nb2', 'nt1', 'nt2', 'w1', 'w2', 'w3', 'w4', 'ns', 'nm', 'nw1', 'nw2', 'nw3' ] + #benchmarks = [ 'm', 's', 'nb1', 'nb2', 'nt1', 'w1', 'w2', 'w3', 'ns', 'nm', 'w1s' ] + benchmarks = [ 'm', 's', 'nb1', 'nb2', 'w1', 'w2', 'w3', 'w4', 'ns', 'nm', 'nw1', 'snt' ] + #dmas = [ 'x', 'd', 'b' ] + dmas = [ 'x' ] caches = [ '2', '4' ] - checkpoints = [ '1' ] names = [] + + bench_system = { + 'm' : 'client', + 's' : 'client', + 'snt' : 'client', + 'nb1' : 'server', + 'nb2' : 'server', + 'nt1' : 'server', + 'nt2' : 'server', + 'w1' : 'server', + 'w2' : 'server', + 'w3' : 'server', + 'w4' : 'server', + 'w1s' : 'server', + 'w2s' : 'server', + 'w3s' : 'server', + 'ns' : 'natbox', + 'nm' : 'natbox', + 'nw1' : 'natbox', + 'nw2' : 'natbox', + 'nw3' : 'natbox' + } + for bench in benchmarks: + if bench_system[bench] != options.system: + continue + for dma in dmas: for cache in caches: - for cpt in checkpoints: - names.append([bench, dma, cache, cpt]) + names.append([bench, dma, cache]) - for bench,dma,cache,cpt in names: - base = '%s.%s.%s.%s' % (bench, dma, cache, cpt) + for bench,dma,cache in names: + base = '%s.%s.%s' % (bench, dma, cache) fname = 'data/%s.%s.dat' % (tag, base) f = open(fname, 'w') print >>f, '#set TITLE = %s' % base @@ -66,8 +93,7 @@ def graphdata(runs, tag, label, value): for speed,freq in zip(['s', 'q'],['4GHz','10GHz']): print >>f, '"%s"' % freq, for conf in configs: - name = '%s.%s.%s.%s.%s.%s' % (conf, bench, dma, speed, cache, - cpt) + name = '%s.%s.%s.%s.%s' % (conf, bench, dma, cache, speed) run = info.source.allRunNames[name] info.display_run = run.run; val = float(value) @@ -174,7 +200,7 @@ def commands(options, command, args): stats = info.source.getStat(args[0]) for stat in stats: if options.graph: - graphdata(runs, stat.name, stat.name, stat) + graphdata(runs, options, stat.name, stat.name, stat) else: if options.binned: print 'kernel ticks' @@ -200,6 +226,39 @@ def commands(options, command, args): printdata(runs, stat) return + if command == 'formula': + if len(args) != 1: + raise CommandException + + stats = eval(args[0]) + for stat in stats: + if options.graph: + graphdata(runs, options, stat.name, stat.name, stat) + else: + if options.binned: + print 'kernel ticks' + stat.bins = 'kernel' + printdata(runs, stat) + + print 'idle ticks' + stat.bins = 'idle' + printdata(runs, stat) + + print 'user ticks' + stat.bins = 'user' + printdata(runs, stat) + + print 'interrupt ticks' + stat.bins = 'user' + printdata(runs, stat) + + print 'total ticks' + + stat.bins = None + print args[0] + printdata(runs, stat) + return + if command == 'bins': if len(args) == 0: info.source.listBins() @@ -241,7 +300,7 @@ def commands(options, command, args): user.bins = 'user' if options.graph: - graphdata(runs, 'usertime', 'User Fraction', + graphdata(runs, options, 'usertime', 'User Fraction', user / system.full_cpu.numCycles) else: printdata(runs, user / system.full_cpu.numCycles) @@ -270,7 +329,7 @@ def commands(options, command, args): if command == 'packets': packets = system.tsunami.etherdev.rxPackets if options.graph: - graphdata(runs, 'packets', 'Packets', packets) + graphdata(runs, options, 'packets', 'Packets', packets) else: printdata(runs, packets) return @@ -283,7 +342,7 @@ def commands(options, command, args): if command == 'pps': pps = system.tsunami.etherdev.rxPackets / sim_seconds if options.graph: - graphdata(runs, 'pps', 'Packets/s', pps) + graphdata(runs, options, 'pps', 'Packets/s', pps) else: printdata(runs, pps) return @@ -292,7 +351,7 @@ def commands(options, command, args): bytes = system.tsunami.etherdev.rxBytes + system.tsunami.etherdev.txBytes bpt = bytes / sim_ticks * 8 if options.graph: - graphdata(runs, 'bpt', 'bps / Hz', bpt) + graphdata(runs, options, 'bpt', 'bps / Hz', bpt) else: printdata(runs, bpt, command == 'tpb') return @@ -339,7 +398,7 @@ def commands(options, command, args): if command == 'rxbps': gbps = system.tsunami.etherdev.rxBandwidth / 1e9 if options.graph: - graphdata(runs, 'rxbps', 'Bandwidth (Gbps)', gbps) + graphdata(runs, options, 'rxbps', 'Bandwidth (Gbps)', gbps) else: printdata(runs, gbps) return @@ -347,7 +406,7 @@ def commands(options, command, args): if command == 'txbps': gbps = system.tsunami.etherdev.txBandwidth / 1e9 if options.graph: - graphdata(runs, 'txbps', 'Bandwidth (Gbps)', gbps) + graphdata(runs, options, 'txbps', 'Bandwidth (Gbps)', gbps) else: printdata(runs, gbps) return @@ -357,7 +416,7 @@ def commands(options, command, args): txbps = system.tsunami.etherdev.txBandwidth gbps = (rxbps + txbps) / 1e9 if options.graph: - graphdata(runs, 'bps', 'Bandwidth (Gbps)', gbps) + graphdata(runs, options, 'bps', 'Bandwidth (Gbps)', gbps) else: printdata(runs, gbps) return @@ -381,7 +440,7 @@ def commands(options, command, args): stat.bins = None if options.graph: - graphdata(runs, 'misses', 'Overall MSHR Misses', stat) + graphdata(runs, options, 'misses', 'Overall MSHR Misses', stat) else: printdata(runs, stat) return @@ -412,11 +471,42 @@ def commands(options, command, args): mpkb = misses / ((rxbytes + txbytes) / 1024) misses.bins = None if options.graph: - graphdata(runs, 'mpkb', 'Misses / KB', mpkb) + graphdata(runs, options, 'mpkb', 'Misses / KB', mpkb) else: printdata(runs, mpkb) return + if command == 'ipkb': + interrupts = system.full_cpu.kern.faults[4] + rxbytes = system.tsunami.etherdev.rxBytes + txbytes = system.tsunami.etherdev.txBytes + + if options.binned: + print 'ipkb kernel stats' + interrupts.bins = 'kernel' + ipkb = interrupts / ((rxbytes + txbytes) / 1024) + printdata(runs, ipkb) + + print 'ipkb idle stats' + interrupts.bins = 'idle' + ipkb = interrupts / ((rxbytes + txbytes) / 1024) + printdata(runs, ipkb) + + print 'ipkb user stats' + interrupts.bins = 'user' + ipkb = interrupts / ((rxbytes + txbytes) / 1024) + printdata(runs, ipkb) + + print 'ipkb total stats' + + ipkb = interrupts / ((rxbytes + txbytes) / 1024) + interrupts.bins = None + if options.graph: + graphdata(runs, options, 'ipkb', 'Interrupts / KB', ipkb) + else: + printdata(runs, ipkb) + return + if command == 'execute': printdata(runs, system.full_cpu.ISSUE__count) return @@ -433,7 +523,7 @@ def commands(options, command, args): ed = system.tsunami.etherdev bpp = (ed.rxBytes + ed.txBytes) / (ed.rxPackets + ed.txPackets) if options.graph: - graphdata(runs, 'bpp', 'Bytes / Packet', bpp) + graphdata(runs, options, 'bpp', 'Bytes / Packet', bpp) else: printdata(runs, bpp) return @@ -441,7 +531,7 @@ def commands(options, command, args): if command == 'rxbpp': bpp = system.tsunami.etherdev.rxBytes / system.tsunami.etherdev.rxPackets if options.graph: - graphdata(runs, 'rxbpp', 'Receive Bytes / Packet', bpp) + graphdata(runs, options, 'rxbpp', 'Receive Bytes / Packet', bpp) else: printdata(runs, bpp) return @@ -449,7 +539,7 @@ def commands(options, command, args): if command == 'txbpp': bpp = system.tsunami.etherdev.txBytes / system.tsunami.etherdev.txPackets if options.graph: - graphdata(runs, 'txbpp', 'Transmit Bytes / Packet', bpp) + graphdata(runs, options, 'txbpp', 'Transmit Bytes / Packet', bpp) else: printdata(runs, bpp) return @@ -457,7 +547,7 @@ def commands(options, command, args): if command == 'rtp': rtp = system.tsunami.etherdev.rxPackets / system.tsunami.etherdev.txPackets if options.graph: - graphdata(runs, 'rtp', 'rxPackets / txPackets', rtp) + graphdata(runs, options, 'rtp', 'rxPackets / txPackets', rtp) else: printdata(runs, rtp) return @@ -465,7 +555,7 @@ def commands(options, command, args): if command == 'rtb': rtb = system.tsunami.etherdev.rxBytes / system.tsunami.etherdev.txBytes if options.graph: - graphdata(runs, 'rtb', 'rxBytes / txBytes', rtb) + graphdata(runs, options, 'rtb', 'rxBytes / txBytes', rtb) else: printdata(runs, rtb) return