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 a793739f8..a1cdc01b7 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 0e48770ed..26fe45317 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 4c079c44a..b154ab4a7 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 ba5beab01..042c4ec84 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 c327a0168..0975ba446 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 f06af3306..446e44e46 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 457563293..f84c03a4c 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 52d9b11ab..c9698cf63 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 e8ece152e..e09b7a318 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 d299dad42..11f017a21 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 3bf048972..91a0da7a9 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 af4dbf412..17aa54a78 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 fc75c9ebe..de8d4e98a 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 c9ca57778..fba069674 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; }