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.
This commit is contained in:
parent
de72e36619
commit
96905971f2
14 changed files with 53 additions and 28 deletions
|
@ -197,7 +197,7 @@ DistEtherLink::TxLink::transmit(EthPacketPtr pkt)
|
||||||
}
|
}
|
||||||
|
|
||||||
packet = 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)
|
if (delayVar != 0)
|
||||||
delay += random_mt.random<Tick>(0, delayVar);
|
delay += random_mt.random<Tick>(0, delayVar);
|
||||||
|
|
||||||
|
@ -233,7 +233,7 @@ DistEtherLink::Link::unserialize(CheckpointIn &cp)
|
||||||
bool packet_exists;
|
bool packet_exists;
|
||||||
UNSERIALIZE_SCALAR(packet_exists);
|
UNSERIALIZE_SCALAR(packet_exists);
|
||||||
if (packet_exists) {
|
if (packet_exists) {
|
||||||
packet = make_shared<EthPacketData>(16384);
|
packet = make_shared<EthPacketData>();
|
||||||
packet->unserialize("packet", cp);
|
packet->unserialize("packet", cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -407,7 +407,7 @@ DistIface::RecvScheduler::resumeRecvTicks()
|
||||||
Desc d = descQueue.front();
|
Desc d = descQueue.front();
|
||||||
descQueue.pop();
|
descQueue.pop();
|
||||||
d.sendTick = curTick();
|
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);
|
v.push_back(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -493,7 +493,7 @@ DistIface::RecvScheduler::Desc::unserialize(CheckpointIn &cp)
|
||||||
{
|
{
|
||||||
UNSERIALIZE_SCALAR(sendTick);
|
UNSERIALIZE_SCALAR(sendTick);
|
||||||
UNSERIALIZE_SCALAR(sendDelay);
|
UNSERIALIZE_SCALAR(sendDelay);
|
||||||
packet = std::make_shared<EthPacketData>(16384);
|
packet = std::make_shared<EthPacketData>();
|
||||||
packet->unserialize("rxPacket", cp);
|
packet->unserialize("rxPacket", cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -583,14 +583,15 @@ DistIface::packetOut(EthPacketPtr pkt, Tick send_delay)
|
||||||
header.sendTick = curTick();
|
header.sendTick = curTick();
|
||||||
header.sendDelay = send_delay;
|
header.sendDelay = send_delay;
|
||||||
|
|
||||||
header.dataPacketLength = pkt->size();
|
header.dataPacketLength = pkt->length;
|
||||||
|
header.simLength = pkt->simLength;
|
||||||
|
|
||||||
// Send out the packet and the meta info.
|
// Send out the packet and the meta info.
|
||||||
sendPacket(header, pkt);
|
sendPacket(header, pkt);
|
||||||
|
|
||||||
DPRINTF(DistEthernetPkt,
|
DPRINTF(DistEthernetPkt,
|
||||||
"DistIface::sendDataPacket() done size:%d send_delay:%llu\n",
|
"DistIface::sendDataPacket() done size:%d send_delay:%llu\n",
|
||||||
pkt->size(), send_delay);
|
pkt->length, send_delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -86,6 +86,11 @@ class DistHeaderPkt
|
||||||
*/
|
*/
|
||||||
MsgType msgType;
|
MsgType msgType;
|
||||||
Tick sendTick;
|
Tick sendTick;
|
||||||
|
/**
|
||||||
|
* Length used for modeling timing in the simulator.
|
||||||
|
* (from EthPacketData::simLength).
|
||||||
|
*/
|
||||||
|
unsigned simLength;
|
||||||
union {
|
union {
|
||||||
Tick sendDelay;
|
Tick sendDelay;
|
||||||
Tick syncRepeat;
|
Tick syncRepeat;
|
||||||
|
@ -93,6 +98,7 @@ class DistHeaderPkt
|
||||||
union {
|
union {
|
||||||
/**
|
/**
|
||||||
* Actual length of the simulated Ethernet packet.
|
* Actual length of the simulated Ethernet packet.
|
||||||
|
* (from EthPacketData::length).
|
||||||
*/
|
*/
|
||||||
unsigned dataPacketLength;
|
unsigned dataPacketLength;
|
||||||
struct {
|
struct {
|
||||||
|
|
|
@ -98,7 +98,7 @@ EtherBus::send(EtherInt *sndr, EthPacketPtr &pkt)
|
||||||
|
|
||||||
packet = pkt;
|
packet = pkt;
|
||||||
sender = sndr;
|
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",
|
DPRINTF(Ethernet, "scheduling packet: delay=%d, (rate=%f)\n",
|
||||||
delay, ticksPerByte);
|
delay, ticksPerByte);
|
||||||
schedule(event, curTick() + delay);
|
schedule(event, curTick() + delay);
|
||||||
|
|
|
@ -192,7 +192,7 @@ EtherLink::Link::transmit(EthPacketPtr pkt)
|
||||||
DDUMP(EthernetData, pkt->data, pkt->length);
|
DDUMP(EthernetData, pkt->data, pkt->length);
|
||||||
|
|
||||||
packet = 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)
|
if (delayVar != 0)
|
||||||
delay += random_mt.random<Tick>(0, delayVar);
|
delay += random_mt.random<Tick>(0, delayVar);
|
||||||
|
|
||||||
|
@ -235,7 +235,7 @@ EtherLink::Link::unserialize(const string &base, CheckpointIn &cp)
|
||||||
bool packet_exists;
|
bool packet_exists;
|
||||||
paramIn(cp, base + ".packet_exists", packet_exists);
|
paramIn(cp, base + ".packet_exists", packet_exists);
|
||||||
if (packet_exists) {
|
if (packet_exists) {
|
||||||
packet = make_shared<EthPacketData>(16384);
|
packet = make_shared<EthPacketData>();
|
||||||
packet->unserialize(base + ".packet", cp);
|
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)) {
|
if (optParamIn(cp, base + ".tx_queue_size", tx_queue_size)) {
|
||||||
for (size_t idx = 0; idx < tx_queue_size; ++idx) {
|
for (size_t idx = 0; idx < tx_queue_size; ++idx) {
|
||||||
Tick tick;
|
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);
|
paramIn(cp, csprintf("%s.txQueue[%i].tick", base, idx), tick);
|
||||||
delayed_packet->unserialize(
|
delayed_packet->unserialize(
|
||||||
|
|
|
@ -41,6 +41,7 @@ using namespace std;
|
||||||
void
|
void
|
||||||
EthPacketData::serialize(const string &base, CheckpointOut &cp) const
|
EthPacketData::serialize(const string &base, CheckpointOut &cp) const
|
||||||
{
|
{
|
||||||
|
paramOut(cp, base + ".simLength", simLength);
|
||||||
paramOut(cp, base + ".length", length);
|
paramOut(cp, base + ".length", length);
|
||||||
arrayParamOut(cp, base + ".data", data, length);
|
arrayParamOut(cp, base + ".data", data, length);
|
||||||
}
|
}
|
||||||
|
@ -49,7 +50,12 @@ void
|
||||||
EthPacketData::unserialize(const string &base, CheckpointIn &cp)
|
EthPacketData::unserialize(const string &base, CheckpointIn &cp)
|
||||||
{
|
{
|
||||||
paramIn(cp, base + ".length", length);
|
paramIn(cp, base + ".length", length);
|
||||||
if (length)
|
if (length) {
|
||||||
|
assert(data == nullptr);
|
||||||
|
data = new uint8_t[length];
|
||||||
arrayParamIn(cp, base + ".data", data, length);
|
arrayParamIn(cp, base + ".data", data, length);
|
||||||
|
}
|
||||||
|
if (!optParamIn(cp, base + ".simLength", simLength))
|
||||||
|
simLength = length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,33 +49,37 @@
|
||||||
class EthPacketData
|
class EthPacketData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/*
|
/**
|
||||||
* Pointer to packet data will be deleted
|
* Pointer to packet data will be deleted
|
||||||
*/
|
*/
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Length of the current packet
|
* Amount of space occupied by the payload in the data buffer
|
||||||
*/
|
*/
|
||||||
unsigned length;
|
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()
|
EthPacketData()
|
||||||
: data(NULL), length(0)
|
: data(nullptr), length(0), simLength(0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
explicit EthPacketData(unsigned size)
|
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; }
|
~EthPacketData() { if (data) delete [] data; }
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
void serialize(const std::string &base, CheckpointOut &cp) const;
|
void serialize(const std::string &base, CheckpointOut &cp) const;
|
||||||
void unserialize(const std::string &base, CheckpointIn &cp);
|
void unserialize(const std::string &base, CheckpointIn &cp);
|
||||||
|
|
||||||
unsigned size() const { return length; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::shared_ptr<EthPacketData> EthPacketPtr;
|
typedef std::shared_ptr<EthPacketData> EthPacketPtr;
|
||||||
|
|
|
@ -200,7 +200,7 @@ EtherSwitch::Interface::transmit()
|
||||||
Tick
|
Tick
|
||||||
EtherSwitch::Interface::switchingDelay()
|
EtherSwitch::Interface::switchingDelay()
|
||||||
{
|
{
|
||||||
Tick delay = (Tick)ceil(((double)outputFifo.front()->length
|
Tick delay = (Tick)ceil(((double)outputFifo.front()->simLength
|
||||||
* ticksPerByte) + 1.0);
|
* ticksPerByte) + 1.0);
|
||||||
if (delayVar != 0)
|
if (delayVar != 0)
|
||||||
delay += random_mt.random<Tick>(0, delayVar);
|
delay += random_mt.random<Tick>(0, delayVar);
|
||||||
|
|
|
@ -239,6 +239,7 @@ EtherTap::process(int revent)
|
||||||
EthPacketPtr packet;
|
EthPacketPtr packet;
|
||||||
packet = make_shared<EthPacketData>(data_len);
|
packet = make_shared<EthPacketData>(data_len);
|
||||||
packet->length = data_len;
|
packet->length = data_len;
|
||||||
|
packet->simLength = data_len;
|
||||||
memcpy(packet->data, data, data_len);
|
memcpy(packet->data, data, data_len);
|
||||||
|
|
||||||
assert(buffer_offset >= data_len + sizeof(uint32_t));
|
assert(buffer_offset >= data_len + sizeof(uint32_t));
|
||||||
|
|
|
@ -1771,12 +1771,15 @@ IGbE::TxDescCache::pktComplete()
|
||||||
DPRINTF(EthernetDesc, "TSO: use: %d hdrlen: %d mss: %d total: %d "
|
DPRINTF(EthernetDesc, "TSO: use: %d hdrlen: %d mss: %d total: %d "
|
||||||
"used: %d loaded hdr: %d\n", useTso, tsoHeaderLen, tsoMss,
|
"used: %d loaded hdr: %d\n", useTso, tsoHeaderLen, tsoMss,
|
||||||
tsoTotalLen, tsoUsedLen, tsoLoadedHeader);
|
tsoTotalLen, tsoUsedLen, tsoLoadedHeader);
|
||||||
|
pktPtr->simLength += tsoCopyBytes;
|
||||||
pktPtr->length += tsoCopyBytes;
|
pktPtr->length += tsoCopyBytes;
|
||||||
tsoUsedLen += tsoCopyBytes;
|
tsoUsedLen += tsoCopyBytes;
|
||||||
DPRINTF(EthernetDesc, "TSO: descBytesUsed: %d copyBytes: %d\n",
|
DPRINTF(EthernetDesc, "TSO: descBytesUsed: %d copyBytes: %d\n",
|
||||||
tsoDescBytesUsed, tsoCopyBytes);
|
tsoDescBytesUsed, tsoCopyBytes);
|
||||||
} else
|
} else {
|
||||||
|
pktPtr->simLength += TxdOp::getLen(desc);
|
||||||
pktPtr->length += TxdOp::getLen(desc);
|
pktPtr->length += TxdOp::getLen(desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -2519,7 +2522,7 @@ IGbE::unserialize(CheckpointIn &cp)
|
||||||
bool txPktExists;
|
bool txPktExists;
|
||||||
UNSERIALIZE_SCALAR(txPktExists);
|
UNSERIALIZE_SCALAR(txPktExists);
|
||||||
if (txPktExists) {
|
if (txPktExists) {
|
||||||
txPacket = std::make_shared<EthPacketData>(16384);
|
txPacket = std::make_shared<EthPacketData>();
|
||||||
txPacket->unserialize("txpacket", cp);
|
txPacket->unserialize("txpacket", cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1738,6 +1738,7 @@ NSGigE::txKick()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
txPacket->simLength = txPacketBufPtr - txPacket->data;
|
||||||
txPacket->length = txPacketBufPtr - txPacket->data;
|
txPacket->length = txPacketBufPtr - txPacket->data;
|
||||||
// this is just because the receive can't handle a
|
// this is just because the receive can't handle a
|
||||||
// packet bigger want to make sure
|
// packet bigger want to make sure
|
||||||
|
@ -2186,6 +2187,7 @@ NSGigE::serialize(CheckpointOut &cp) const
|
||||||
bool txPacketExists = txPacket != nullptr;
|
bool txPacketExists = txPacket != nullptr;
|
||||||
SERIALIZE_SCALAR(txPacketExists);
|
SERIALIZE_SCALAR(txPacketExists);
|
||||||
if (txPacketExists) {
|
if (txPacketExists) {
|
||||||
|
txPacket->simLength = txPacketBufPtr - txPacket->data;
|
||||||
txPacket->length = txPacketBufPtr - txPacket->data;
|
txPacket->length = txPacketBufPtr - txPacket->data;
|
||||||
txPacket->serialize("txPacket", cp);
|
txPacket->serialize("txPacket", cp);
|
||||||
uint32_t txPktBufPtr = (uint32_t) (txPacketBufPtr - txPacket->data);
|
uint32_t txPktBufPtr = (uint32_t) (txPacketBufPtr - txPacket->data);
|
||||||
|
@ -2350,7 +2352,7 @@ NSGigE::unserialize(CheckpointIn &cp)
|
||||||
bool txPacketExists;
|
bool txPacketExists;
|
||||||
UNSERIALIZE_SCALAR(txPacketExists);
|
UNSERIALIZE_SCALAR(txPacketExists);
|
||||||
if (txPacketExists) {
|
if (txPacketExists) {
|
||||||
txPacket = make_shared<EthPacketData>(16384);
|
txPacket = make_shared<EthPacketData>();
|
||||||
txPacket->unserialize("txPacket", cp);
|
txPacket->unserialize("txPacket", cp);
|
||||||
uint32_t txPktBufPtr;
|
uint32_t txPktBufPtr;
|
||||||
UNSERIALIZE_SCALAR(txPktBufPtr);
|
UNSERIALIZE_SCALAR(txPktBufPtr);
|
||||||
|
@ -2362,7 +2364,7 @@ NSGigE::unserialize(CheckpointIn &cp)
|
||||||
UNSERIALIZE_SCALAR(rxPacketExists);
|
UNSERIALIZE_SCALAR(rxPacketExists);
|
||||||
rxPacket = 0;
|
rxPacket = 0;
|
||||||
if (rxPacketExists) {
|
if (rxPacketExists) {
|
||||||
rxPacket = make_shared<EthPacketData>(16384);
|
rxPacket = make_shared<EthPacketData>();
|
||||||
rxPacket->unserialize("rxPacket", cp);
|
rxPacket->unserialize("rxPacket", cp);
|
||||||
uint32_t rxPktBufPtr;
|
uint32_t rxPktBufPtr;
|
||||||
UNSERIALIZE_SCALAR(rxPktBufPtr);
|
UNSERIALIZE_SCALAR(rxPktBufPtr);
|
||||||
|
|
|
@ -77,7 +77,7 @@ PacketFifoEntry::serialize(const string &base, CheckpointOut &cp) const
|
||||||
void
|
void
|
||||||
PacketFifoEntry::unserialize(const string &base, CheckpointIn &cp)
|
PacketFifoEntry::unserialize(const string &base, CheckpointIn &cp)
|
||||||
{
|
{
|
||||||
packet = make_shared<EthPacketData>(16384);
|
packet = make_shared<EthPacketData>();
|
||||||
packet->unserialize(base + ".packet", cp);
|
packet->unserialize(base + ".packet", cp);
|
||||||
paramIn(cp, base + ".slack", slack);
|
paramIn(cp, base + ".slack", slack);
|
||||||
paramIn(cp, base + ".number", number);
|
paramIn(cp, base + ".number", number);
|
||||||
|
|
|
@ -1085,6 +1085,7 @@ Device::txKick()
|
||||||
|
|
||||||
case txCopyDone:
|
case txCopyDone:
|
||||||
vnic->TxDone = txDmaLen | Regs::TxDone_Complete;
|
vnic->TxDone = txDmaLen | Regs::TxDone_Complete;
|
||||||
|
txPacket->simLength += txDmaLen;
|
||||||
txPacket->length += txDmaLen;
|
txPacket->length += txDmaLen;
|
||||||
if ((vnic->TxData & Regs::TxData_More)) {
|
if ((vnic->TxData & Regs::TxData_More)) {
|
||||||
txPacketOffset += txDmaLen;
|
txPacketOffset += txDmaLen;
|
||||||
|
@ -1495,7 +1496,7 @@ Device::unserialize(CheckpointIn &cp)
|
||||||
UNSERIALIZE_SCALAR(txPacketExists);
|
UNSERIALIZE_SCALAR(txPacketExists);
|
||||||
txPacket = 0;
|
txPacket = 0;
|
||||||
if (txPacketExists) {
|
if (txPacketExists) {
|
||||||
txPacket = make_shared<EthPacketData>(16384);
|
txPacket = make_shared<EthPacketData>();
|
||||||
txPacket->unserialize("txPacket", cp);
|
txPacket->unserialize("txPacket", cp);
|
||||||
UNSERIALIZE_SCALAR(txPacketOffset);
|
UNSERIALIZE_SCALAR(txPacketOffset);
|
||||||
UNSERIALIZE_SCALAR(txPacketBytes);
|
UNSERIALIZE_SCALAR(txPacketBytes);
|
||||||
|
|
|
@ -329,6 +329,7 @@ TCPIface::recvPacket(const Header &header, EthPacketPtr &packet)
|
||||||
packet = make_shared<EthPacketData>(header.dataPacketLength);
|
packet = make_shared<EthPacketData>(header.dataPacketLength);
|
||||||
bool ret = recvTCP(sock, packet->data, header.dataPacketLength);
|
bool ret = recvTCP(sock, packet->data, header.dataPacketLength);
|
||||||
panic_if(!ret, "Error while reading socket");
|
panic_if(!ret, "Error while reading socket");
|
||||||
|
packet->simLength = header.simLength;
|
||||||
packet->length = header.dataPacketLength;
|
packet->length = header.dataPacketLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue