dev: Add 'simLength' parameter in EthPacketData
authormlebeane <michael.lebeane@amd.com>
Thu, 27 Oct 2016 02:48:33 +0000 (22:48 -0400)
committermlebeane <michael.lebeane@amd.com>
Thu, 27 Oct 2016 02:48:33 +0000 (22:48 -0400)
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.

14 files changed:
src/dev/net/dist_etherlink.cc
src/dev/net/dist_iface.cc
src/dev/net/dist_packet.hh
src/dev/net/etherbus.cc
src/dev/net/etherlink.cc
src/dev/net/etherpkt.cc
src/dev/net/etherpkt.hh
src/dev/net/etherswitch.cc
src/dev/net/ethertap.cc
src/dev/net/i8254xGBe.cc
src/dev/net/ns_gige.cc
src/dev/net/pktfifo.cc
src/dev/net/sinic.cc
src/dev/net/tcp_iface.cc

index a793739f8ef3f7f6352622b6dd1dcb4da7ea2ff9..a1cdc01b747a5aa903d9d8253ddd3d6d45b4e62c 100644 (file)
@@ -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<Tick>(0, delayVar);
 
@@ -233,7 +233,7 @@ DistEtherLink::Link::unserialize(CheckpointIn &cp)
     bool packet_exists;
     UNSERIALIZE_SCALAR(packet_exists);
     if (packet_exists) {
-        packet = make_shared<EthPacketData>(16384);
+        packet = make_shared<EthPacketData>();
         packet->unserialize("packet", cp);
     }
 
index 0e48770ed2ea774cf3b0947d061c5ccd8b902971..26fe45317b0873796e38ce66ccd4a146ca053c14 100644 (file)
@@ -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<EthPacketData>(16384);
+        packet = std::make_shared<EthPacketData>();
         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
index 4c079c44a203aa89fa72ca330f4c8325ed3eb425..b154ab4a77bbe70fbe3d54f135d3759fce3736ae 100644 (file)
@@ -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 {
index ba5beab01bba7ad711df57422177827b4ff3475d..042c4ec84fb549eeed5ad4be432a17037dfba12a 100644 (file)
@@ -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);
index c327a01687f0186e9c5d4db559e9e187b05852d7..0975ba4461ba8e978c660a0aebed5fe446bd8ed9 100644 (file)
@@ -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<Tick>(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<EthPacketData>(16384);
+        packet = make_shared<EthPacketData>();
         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<EthPacketData>(16384);
+            EthPacketPtr delayed_packet = make_shared<EthPacketData>();
 
             paramIn(cp, csprintf("%s.txQueue[%i].tick", base, idx), tick);
             delayed_packet->unserialize(
index f06af33060a1ec1ccb941a9695090083645e645d..446e44e468efb3dbeb6124e13c003eeba6429900 100644 (file)
@@ -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;
 }
 
index 457563293f28a63606766fc2e7d55b5da3a5f329..f84c03a4c28c02d32c16c0737777a61136700734 100644 (file)
 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<EthPacketData> EthPacketPtr;
index 52d9b11abe66ccf10df9b224676e89332507a291..c9698cf636ca849b30d17081533e48454adc5115 100644 (file)
@@ -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<Tick>(0, delayVar);
index e8ece152eaca29d30efdd344db9f65ae7d1decc4..e09b7a318d9a6db93223e3be3121e99d45d5c63e 100644 (file)
@@ -239,6 +239,7 @@ EtherTap::process(int revent)
         EthPacketPtr packet;
         packet = make_shared<EthPacketData>(data_len);
         packet->length = data_len;
+        packet->simLength = data_len;
         memcpy(packet->data, data, data_len);
 
         assert(buffer_offset >= data_len + sizeof(uint32_t));
index d299dad4219b2136e63013330c9552bd74f60f85..11f017a21b2cbcab61c88752f7c906dd47a1703e 100644 (file)
@@ -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<EthPacketData>(16384);
+        txPacket = std::make_shared<EthPacketData>();
         txPacket->unserialize("txpacket", cp);
     }
 
index 3bf0489725b708bf703d3d546f8279bf546c54da..91a0da7a9fdb37abb129890b09ec2aa506bc36a4 100644 (file)
@@ -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<EthPacketData>(16384);
+        txPacket = make_shared<EthPacketData>();
         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<EthPacketData>(16384);
+        rxPacket = make_shared<EthPacketData>();
         rxPacket->unserialize("rxPacket", cp);
         uint32_t rxPktBufPtr;
         UNSERIALIZE_SCALAR(rxPktBufPtr);
index af4dbf4128b05ea4e52ef75a66162dfbd03e60db..17aa54a787eead97b529bf44e28b064ebe6a4065 100644 (file)
@@ -77,7 +77,7 @@ PacketFifoEntry::serialize(const string &base, CheckpointOut &cp) const
 void
 PacketFifoEntry::unserialize(const string &base, CheckpointIn &cp)
 {
-    packet = make_shared<EthPacketData>(16384);
+    packet = make_shared<EthPacketData>();
     packet->unserialize(base + ".packet", cp);
     paramIn(cp, base + ".slack", slack);
     paramIn(cp, base + ".number", number);
index fc75c9ebeed6735ae3a47de273ce43d6317c8137..de8d4e98ae2a2da67a6abd6d775c94f3b3b2215e 100644 (file)
@@ -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<EthPacketData>(16384);
+        txPacket = make_shared<EthPacketData>();
         txPacket->unserialize("txPacket", cp);
         UNSERIALIZE_SCALAR(txPacketOffset);
         UNSERIALIZE_SCALAR(txPacketBytes);
index c9ca577786362609e62a4c8fe9fd580453b6c9dc..fba0696746d7e27b5b537e52ef66b33c1feb5f54 100644 (file)
@@ -329,6 +329,7 @@ TCPIface::recvPacket(const Header &header, EthPacketPtr &packet)
     packet = make_shared<EthPacketData>(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;
 }