From 96905971f26e5218baebf8f953f05a9b341f9cc6 Mon Sep 17 00:00:00 2001 From: mlebeane Date: Wed, 26 Oct 2016 22:48:33 -0400 Subject: [PATCH] dev: Add 'simLength' parameter in EthPacketData Currently, all the network devices create a 16K buffer for the 'data' field in EthPacketData, and use 'length' to keep track of the size of the packet in the buffer. This patch introduces the 'simLength' parameter to EthPacketData, which is used to hold the effective length of the packet used for all timing calulations in the simulator. Serialization is performed using only the useful data in the packet ('length') and not necessarily the entire original buffer. --- src/dev/net/dist_etherlink.cc | 4 ++-- src/dev/net/dist_iface.cc | 9 +++++---- src/dev/net/dist_packet.hh | 6 ++++++ src/dev/net/etherbus.cc | 2 +- src/dev/net/etherlink.cc | 6 +++--- src/dev/net/etherpkt.cc | 8 +++++++- src/dev/net/etherpkt.hh | 24 ++++++++++++++---------- src/dev/net/etherswitch.cc | 2 +- src/dev/net/ethertap.cc | 1 + src/dev/net/i8254xGBe.cc | 7 +++++-- src/dev/net/ns_gige.cc | 6 ++++-- src/dev/net/pktfifo.cc | 2 +- src/dev/net/sinic.cc | 3 ++- src/dev/net/tcp_iface.cc | 1 + 14 files changed, 53 insertions(+), 28 deletions(-) diff --git a/src/dev/net/dist_etherlink.cc b/src/dev/net/dist_etherlink.cc index a793739f8e..a1cdc01b74 100644 --- a/src/dev/net/dist_etherlink.cc +++ b/src/dev/net/dist_etherlink.cc @@ -197,7 +197,7 @@ DistEtherLink::TxLink::transmit(EthPacketPtr pkt) } packet = pkt; - Tick delay = (Tick)ceil(((double)pkt->length * ticksPerByte) + 1.0); + Tick delay = (Tick)ceil(((double)pkt->simLength * ticksPerByte) + 1.0); if (delayVar != 0) delay += random_mt.random(0, delayVar); @@ -233,7 +233,7 @@ DistEtherLink::Link::unserialize(CheckpointIn &cp) bool packet_exists; UNSERIALIZE_SCALAR(packet_exists); if (packet_exists) { - packet = make_shared(16384); + packet = make_shared(); packet->unserialize("packet", cp); } diff --git a/src/dev/net/dist_iface.cc b/src/dev/net/dist_iface.cc index 0e48770ed2..26fe45317b 100644 --- a/src/dev/net/dist_iface.cc +++ b/src/dev/net/dist_iface.cc @@ -407,7 +407,7 @@ DistIface::RecvScheduler::resumeRecvTicks() Desc d = descQueue.front(); descQueue.pop(); d.sendTick = curTick(); - d.sendDelay = d.packet->size(); // assume 1 tick/byte max link speed + d.sendDelay = d.packet->simLength; // assume 1 tick/byte max link speed v.push_back(d); } @@ -493,7 +493,7 @@ DistIface::RecvScheduler::Desc::unserialize(CheckpointIn &cp) { UNSERIALIZE_SCALAR(sendTick); UNSERIALIZE_SCALAR(sendDelay); - packet = std::make_shared(16384); + packet = std::make_shared(); packet->unserialize("rxPacket", cp); } @@ -583,14 +583,15 @@ DistIface::packetOut(EthPacketPtr pkt, Tick send_delay) header.sendTick = curTick(); header.sendDelay = send_delay; - header.dataPacketLength = pkt->size(); + header.dataPacketLength = pkt->length; + header.simLength = pkt->simLength; // Send out the packet and the meta info. sendPacket(header, pkt); DPRINTF(DistEthernetPkt, "DistIface::sendDataPacket() done size:%d send_delay:%llu\n", - pkt->size(), send_delay); + pkt->length, send_delay); } void diff --git a/src/dev/net/dist_packet.hh b/src/dev/net/dist_packet.hh index 4c079c44a2..b154ab4a77 100644 --- a/src/dev/net/dist_packet.hh +++ b/src/dev/net/dist_packet.hh @@ -86,6 +86,11 @@ class DistHeaderPkt */ MsgType msgType; Tick sendTick; + /** + * Length used for modeling timing in the simulator. + * (from EthPacketData::simLength). + */ + unsigned simLength; union { Tick sendDelay; Tick syncRepeat; @@ -93,6 +98,7 @@ class DistHeaderPkt union { /** * Actual length of the simulated Ethernet packet. + * (from EthPacketData::length). */ unsigned dataPacketLength; struct { diff --git a/src/dev/net/etherbus.cc b/src/dev/net/etherbus.cc index ba5beab01b..042c4ec84f 100644 --- a/src/dev/net/etherbus.cc +++ b/src/dev/net/etherbus.cc @@ -98,7 +98,7 @@ EtherBus::send(EtherInt *sndr, EthPacketPtr &pkt) packet = pkt; sender = sndr; - int delay = (int)ceil(((double)pkt->length * ticksPerByte) + 1.0); + int delay = (int)ceil(((double)pkt->simLength * ticksPerByte) + 1.0); DPRINTF(Ethernet, "scheduling packet: delay=%d, (rate=%f)\n", delay, ticksPerByte); schedule(event, curTick() + delay); diff --git a/src/dev/net/etherlink.cc b/src/dev/net/etherlink.cc index c327a01687..0975ba4461 100644 --- a/src/dev/net/etherlink.cc +++ b/src/dev/net/etherlink.cc @@ -192,7 +192,7 @@ EtherLink::Link::transmit(EthPacketPtr pkt) DDUMP(EthernetData, pkt->data, pkt->length); packet = pkt; - Tick delay = (Tick)ceil(((double)pkt->length * ticksPerByte) + 1.0); + Tick delay = (Tick)ceil(((double)pkt->simLength * ticksPerByte) + 1.0); if (delayVar != 0) delay += random_mt.random(0, delayVar); @@ -235,7 +235,7 @@ EtherLink::Link::unserialize(const string &base, CheckpointIn &cp) bool packet_exists; paramIn(cp, base + ".packet_exists", packet_exists); if (packet_exists) { - packet = make_shared(16384); + packet = make_shared(); packet->unserialize(base + ".packet", cp); } @@ -251,7 +251,7 @@ EtherLink::Link::unserialize(const string &base, CheckpointIn &cp) if (optParamIn(cp, base + ".tx_queue_size", tx_queue_size)) { for (size_t idx = 0; idx < tx_queue_size; ++idx) { Tick tick; - EthPacketPtr delayed_packet = make_shared(16384); + EthPacketPtr delayed_packet = make_shared(); paramIn(cp, csprintf("%s.txQueue[%i].tick", base, idx), tick); delayed_packet->unserialize( diff --git a/src/dev/net/etherpkt.cc b/src/dev/net/etherpkt.cc index f06af33060..446e44e468 100644 --- a/src/dev/net/etherpkt.cc +++ b/src/dev/net/etherpkt.cc @@ -41,6 +41,7 @@ using namespace std; void EthPacketData::serialize(const string &base, CheckpointOut &cp) const { + paramOut(cp, base + ".simLength", simLength); paramOut(cp, base + ".length", length); arrayParamOut(cp, base + ".data", data, length); } @@ -49,7 +50,12 @@ void EthPacketData::unserialize(const string &base, CheckpointIn &cp) { paramIn(cp, base + ".length", length); - if (length) + if (length) { + assert(data == nullptr); + data = new uint8_t[length]; arrayParamIn(cp, base + ".data", data, length); + } + if (!optParamIn(cp, base + ".simLength", simLength)) + simLength = length; } diff --git a/src/dev/net/etherpkt.hh b/src/dev/net/etherpkt.hh index 457563293f..f84c03a4c2 100644 --- a/src/dev/net/etherpkt.hh +++ b/src/dev/net/etherpkt.hh @@ -49,33 +49,37 @@ class EthPacketData { public: - /* + /** * Pointer to packet data will be deleted */ uint8_t *data; - /* - * Length of the current packet + /** + * Amount of space occupied by the payload in the data buffer */ unsigned length; - public: + /** + * Effective length, used for modeling timing in the simulator. + * This could be different from length if the packets are assumed + * to use a tightly packed or compressed format, but it's not worth + * the performance/complexity hit to perform that packing or compression + * in the simulation. + */ + unsigned simLength; + EthPacketData() - : data(NULL), length(0) + : data(nullptr), length(0), simLength(0) { } explicit EthPacketData(unsigned size) - : data(new uint8_t[size]), length(0) + : data(new uint8_t[size]), length(0), simLength(0) { } ~EthPacketData() { if (data) delete [] data; } - public: - void serialize(const std::string &base, CheckpointOut &cp) const; void unserialize(const std::string &base, CheckpointIn &cp); - - unsigned size() const { return length; } }; typedef std::shared_ptr EthPacketPtr; diff --git a/src/dev/net/etherswitch.cc b/src/dev/net/etherswitch.cc index 52d9b11abe..c9698cf636 100644 --- a/src/dev/net/etherswitch.cc +++ b/src/dev/net/etherswitch.cc @@ -200,7 +200,7 @@ EtherSwitch::Interface::transmit() Tick EtherSwitch::Interface::switchingDelay() { - Tick delay = (Tick)ceil(((double)outputFifo.front()->length + Tick delay = (Tick)ceil(((double)outputFifo.front()->simLength * ticksPerByte) + 1.0); if (delayVar != 0) delay += random_mt.random(0, delayVar); diff --git a/src/dev/net/ethertap.cc b/src/dev/net/ethertap.cc index e8ece152ea..e09b7a318d 100644 --- a/src/dev/net/ethertap.cc +++ b/src/dev/net/ethertap.cc @@ -239,6 +239,7 @@ EtherTap::process(int revent) EthPacketPtr packet; packet = make_shared(data_len); packet->length = data_len; + packet->simLength = data_len; memcpy(packet->data, data, data_len); assert(buffer_offset >= data_len + sizeof(uint32_t)); diff --git a/src/dev/net/i8254xGBe.cc b/src/dev/net/i8254xGBe.cc index d299dad421..11f017a21b 100644 --- a/src/dev/net/i8254xGBe.cc +++ b/src/dev/net/i8254xGBe.cc @@ -1771,12 +1771,15 @@ IGbE::TxDescCache::pktComplete() DPRINTF(EthernetDesc, "TSO: use: %d hdrlen: %d mss: %d total: %d " "used: %d loaded hdr: %d\n", useTso, tsoHeaderLen, tsoMss, tsoTotalLen, tsoUsedLen, tsoLoadedHeader); + pktPtr->simLength += tsoCopyBytes; pktPtr->length += tsoCopyBytes; tsoUsedLen += tsoCopyBytes; DPRINTF(EthernetDesc, "TSO: descBytesUsed: %d copyBytes: %d\n", tsoDescBytesUsed, tsoCopyBytes); - } else + } else { + pktPtr->simLength += TxdOp::getLen(desc); pktPtr->length += TxdOp::getLen(desc); + } @@ -2519,7 +2522,7 @@ IGbE::unserialize(CheckpointIn &cp) bool txPktExists; UNSERIALIZE_SCALAR(txPktExists); if (txPktExists) { - txPacket = std::make_shared(16384); + txPacket = std::make_shared(); txPacket->unserialize("txpacket", cp); } diff --git a/src/dev/net/ns_gige.cc b/src/dev/net/ns_gige.cc index 3bf0489725..91a0da7a9f 100644 --- a/src/dev/net/ns_gige.cc +++ b/src/dev/net/ns_gige.cc @@ -1738,6 +1738,7 @@ NSGigE::txKick() } } + txPacket->simLength = txPacketBufPtr - txPacket->data; txPacket->length = txPacketBufPtr - txPacket->data; // this is just because the receive can't handle a // packet bigger want to make sure @@ -2186,6 +2187,7 @@ NSGigE::serialize(CheckpointOut &cp) const bool txPacketExists = txPacket != nullptr; SERIALIZE_SCALAR(txPacketExists); if (txPacketExists) { + txPacket->simLength = txPacketBufPtr - txPacket->data; txPacket->length = txPacketBufPtr - txPacket->data; txPacket->serialize("txPacket", cp); uint32_t txPktBufPtr = (uint32_t) (txPacketBufPtr - txPacket->data); @@ -2350,7 +2352,7 @@ NSGigE::unserialize(CheckpointIn &cp) bool txPacketExists; UNSERIALIZE_SCALAR(txPacketExists); if (txPacketExists) { - txPacket = make_shared(16384); + txPacket = make_shared(); txPacket->unserialize("txPacket", cp); uint32_t txPktBufPtr; UNSERIALIZE_SCALAR(txPktBufPtr); @@ -2362,7 +2364,7 @@ NSGigE::unserialize(CheckpointIn &cp) UNSERIALIZE_SCALAR(rxPacketExists); rxPacket = 0; if (rxPacketExists) { - rxPacket = make_shared(16384); + rxPacket = make_shared(); rxPacket->unserialize("rxPacket", cp); uint32_t rxPktBufPtr; UNSERIALIZE_SCALAR(rxPktBufPtr); diff --git a/src/dev/net/pktfifo.cc b/src/dev/net/pktfifo.cc index af4dbf4128..17aa54a787 100644 --- a/src/dev/net/pktfifo.cc +++ b/src/dev/net/pktfifo.cc @@ -77,7 +77,7 @@ PacketFifoEntry::serialize(const string &base, CheckpointOut &cp) const void PacketFifoEntry::unserialize(const string &base, CheckpointIn &cp) { - packet = make_shared(16384); + packet = make_shared(); packet->unserialize(base + ".packet", cp); paramIn(cp, base + ".slack", slack); paramIn(cp, base + ".number", number); diff --git a/src/dev/net/sinic.cc b/src/dev/net/sinic.cc index fc75c9ebee..de8d4e98ae 100644 --- a/src/dev/net/sinic.cc +++ b/src/dev/net/sinic.cc @@ -1085,6 +1085,7 @@ Device::txKick() case txCopyDone: vnic->TxDone = txDmaLen | Regs::TxDone_Complete; + txPacket->simLength += txDmaLen; txPacket->length += txDmaLen; if ((vnic->TxData & Regs::TxData_More)) { txPacketOffset += txDmaLen; @@ -1495,7 +1496,7 @@ Device::unserialize(CheckpointIn &cp) UNSERIALIZE_SCALAR(txPacketExists); txPacket = 0; if (txPacketExists) { - txPacket = make_shared(16384); + txPacket = make_shared(); txPacket->unserialize("txPacket", cp); UNSERIALIZE_SCALAR(txPacketOffset); UNSERIALIZE_SCALAR(txPacketBytes); diff --git a/src/dev/net/tcp_iface.cc b/src/dev/net/tcp_iface.cc index c9ca577786..fba0696746 100644 --- a/src/dev/net/tcp_iface.cc +++ b/src/dev/net/tcp_iface.cc @@ -329,6 +329,7 @@ TCPIface::recvPacket(const Header &header, EthPacketPtr &packet) packet = make_shared(header.dataPacketLength); bool ret = recvTCP(sock, packet->data, header.dataPacketLength); panic_if(!ret, "Error while reading socket"); + packet->simLength = header.simLength; packet->length = header.dataPacketLength; }