changeset f0a0c8f23c06 in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=f0a0c8f23c06
description:
SINIC: Commit old code from ASPLOS 2006 studies.
NOTE: This code was written by Nathan Binkert in 2006 and is properly
copyright
"The Regents of the University of Michigan"
diffstat:
3 files changed, 5 insertions(+), 27 deletions(-)
src/dev/Ethernet.py | 1 +
src/dev/sinic.hh | 15 ++-------------
src/dev/sinicreg.hh | 16 ++--------------
diffs (truncated from 710 to 300 lines):
diff -r 9abcc140f346 -r f0a0c8f23c06 src/dev/Ethernet.py
--- a/src/dev/Ethernet.py Thu Oct 09 04:58:23 2008 -0700
+++ b/src/dev/Ethernet.py Thu Oct 09 04:58:23 2008 -0700
@@ -171,6 +171,9 @@
tx_fifo_high_mark = Param.MemorySize('384kB', "tx fifo high threshold")
tx_fifo_threshold = Param.MemorySize('128kB', "tx fifo low threshold")
virtual_count = Param.UInt32(1, "Virtualized SINIC")
+ zero_copy_size = Param.UInt32(64, "Bytes to copy if below threshold")
+ zero_copy_threshold = Param.UInt32(256,
+ "Only zero copy above this threshold")
zero_copy = Param.Bool(False, "Zero copy receive")
delay_copy = Param.Bool(False, "Delayed copy transmit")
virtual_addr = Param.Bool(False, "Virtual addressing")
diff -r 9abcc140f346 -r f0a0c8f23c06 src/dev/sinic.cc
--- a/src/dev/sinic.cc Thu Oct 09 04:58:23 2008 -0700
+++ b/src/dev/sinic.cc Thu Oct 09 04:58:23 2008 -0700
@@ -45,6 +45,7 @@
#include "sim/host.hh"
#include "sim/stats.hh"
+using namespace std;
using namespace Net;
using namespace TheISA;
@@ -265,6 +266,35 @@
totPackets = txPackets + rxPackets;
txPacketRate = txPackets / simSeconds;
rxPacketRate = rxPackets / simSeconds;
+
+ _maxVnicDistance = 0;
+
+ maxVnicDistance
+ .name(name() + ".maxVnicDistance")
+ .desc("maximum vnic distance")
+ ;
+
+ totalVnicDistance
+ .name(name() + ".totalVnicDistance")
+ .desc("total vnic distance")
+ ;
+ numVnicDistance
+ .name(name() + ".numVnicDistance")
+ .desc("number of vnic distance measurements")
+ ;
+
+ avgVnicDistance
+ .name(name() + ".avgVnicDistance")
+ .desc("average vnic distance")
+ ;
+
+ avgVnicDistance = totalVnicDistance / numVnicDistance;
+}
+
+void
+Device::resetStats()
+{
+ _maxVnicDistance = 0;
}
EtherInt*
@@ -289,6 +319,10 @@
index, size);
}
+//add stats for head of line blocking
+//add stats for average fifo length
+//add stats for average number of vnics busy
+
void
Device::prepareRead(int cpu, int index)
{
@@ -301,7 +335,7 @@
uint64_t rxdone = vnic.RxDone;
rxdone = set_RxDone_Packets(rxdone, rxFifo.countPacketsAfter(rxFifoPtr));
rxdone = set_RxDone_Empty(rxdone, rxFifo.empty());
- rxdone = set_RxDone_High(rxdone, rxFifo.size() > regs.RxFifoMark);
+ rxdone = set_RxDone_High(rxdone, rxFifo.size() > regs.RxFifoHigh);
rxdone = set_RxDone_NotHigh(rxdone, rxLow);
regs.RxData = vnic.RxData;
regs.RxDone = rxdone;
@@ -311,10 +345,23 @@
uint64_t txdone = vnic.TxDone;
txdone = set_TxDone_Packets(txdone, txFifo.packets());
txdone = set_TxDone_Full(txdone, txFifo.avail() < regs.TxMaxCopy);
- txdone = set_TxDone_Low(txdone, txFifo.size() < regs.TxFifoMark);
+ txdone = set_TxDone_Low(txdone, txFifo.size() < regs.TxFifoLow);
regs.TxData = vnic.TxData;
regs.TxDone = txdone;
regs.TxWait = txdone;
+
+ int head = 0xffff;
+
+ if (!rxFifo.empty()) {
+ int vnic = rxFifo.begin()->priv;
+ if (vnic != -1 && virtualRegs[vnic].rxPacketOffset > 0)
+ head = vnic;
+ }
+
+ regs.RxStatus = set_RxStatus_Head(regs.RxStatus, head);
+ regs.RxStatus = set_RxStatus_Busy(regs.RxStatus, rxBusyCount);
+ regs.RxStatus = set_RxStatus_Mapped(regs.RxStatus, rxMappedCount);
+ regs.RxStatus = set_RxStatus_Dirty(regs.RxStatus, rxDirtyCount);
}
void
@@ -473,22 +520,25 @@
vnic.rxUnique = rxUnique++;
vnic.RxDone = Regs::RxDone_Busy;
vnic.RxData = pkt->get<uint64_t>();
+ rxBusyCount++;
if (Regs::get_RxData_Vaddr(pkt->get<uint64_t>())) {
panic("vtophys not implemented in newmem");
-/* Addr vaddr = Regs::get_RxData_Addr(reg64);
+#ifdef SINIC_VTOPHYS
+ Addr vaddr = Regs::get_RxData_Addr(reg64);
Addr paddr = vtophys(req->xc, vaddr);
DPRINTF(EthernetPIO, "write RxData vnic %d (rxunique %d): "
"vaddr=%#x, paddr=%#x\n",
index, vnic.rxUnique, vaddr, paddr);
- vnic.RxData = Regs::set_RxData_Addr(vnic.RxData, paddr);*/
+ vnic.RxData = Regs::set_RxData_Addr(vnic.RxData, paddr);
+#endif
} else {
DPRINTF(EthernetPIO, "write RxData vnic %d (rxunique %d)\n",
index, vnic.rxUnique);
}
- if (vnic.rxPacket == rxFifo.end()) {
+ if (vnic.rxIndex == rxFifo.end()) {
DPRINTF(EthernetPIO, "request new packet...appending to rxList\n");
rxList.push_back(index);
} else {
@@ -512,15 +562,17 @@
if (Regs::get_TxData_Vaddr(pkt->get<uint64_t>())) {
panic("vtophys won't work here in newmem.\n");
- /*Addr vaddr = Regs::get_TxData_Addr(reg64);
+#ifdef SINIC_VTOPHYS
+ Addr vaddr = Regs::get_TxData_Addr(reg64);
Addr paddr = vtophys(req->xc, vaddr);
- DPRINTF(EthernetPIO, "write TxData vnic %d (rxunique %d): "
+ DPRINTF(EthernetPIO, "write TxData vnic %d (txunique %d): "
"vaddr=%#x, paddr=%#x\n",
index, vnic.txUnique, vaddr, paddr);
- vnic.TxData = Regs::set_TxData_Addr(vnic.TxData, paddr);*/
+ vnic.TxData = Regs::set_TxData_Addr(vnic.TxData, paddr);
+#endif
} else {
- DPRINTF(EthernetPIO, "write TxData vnic %d (rxunique %d)\n",
+ DPRINTF(EthernetPIO, "write TxData vnic %d (txunique %d)\n",
index, vnic.txUnique);
}
@@ -761,18 +813,31 @@
regs.IntrMask = Intr_Soft | Intr_RxHigh | Intr_RxPacket | Intr_TxLow;
regs.RxMaxCopy = params()->rx_max_copy;
regs.TxMaxCopy = params()->tx_max_copy;
+ regs.ZeroCopySize = params()->zero_copy_size;
+ regs.ZeroCopyMark = params()->zero_copy_threshold;
+ regs.VirtualCount = params()->virtual_count;
regs.RxMaxIntr = params()->rx_max_intr;
- regs.VirtualCount = params()->virtual_count;
regs.RxFifoSize = params()->rx_fifo_size;
regs.TxFifoSize = params()->tx_fifo_size;
- regs.RxFifoMark = params()->rx_fifo_threshold;
- regs.TxFifoMark = params()->tx_fifo_threshold;
+ regs.RxFifoLow = params()->rx_fifo_low_mark;
+ regs.TxFifoLow = params()->tx_fifo_threshold;
+ regs.RxFifoHigh = params()->rx_fifo_threshold;
+ regs.TxFifoHigh = params()->tx_fifo_high_mark;
regs.HwAddr = params()->hardware_address;
+
+ if (regs.RxMaxCopy < regs.ZeroCopyMark)
+ panic("Must be able to copy at least as many bytes as the threshold");
+
+ if (regs.ZeroCopySize >= regs.ZeroCopyMark)
+ panic("The number of bytes to copy must be less than the threshold");
rxList.clear();
rxBusy.clear();
rxActive = -1;
txList.clear();
+ rxBusyCount = 0;
+ rxDirtyCount = 0;
+ rxMappedCount = 0;
rxState = rxIdle;
txState = txIdle;
@@ -788,7 +853,7 @@
virtualRegs.clear();
virtualRegs.resize(size);
for (int i = 0; i < size; ++i)
- virtualRegs[i].rxPacket = rxFifo.end();
+ virtualRegs[i].rxIndex = rxFifo.end();
}
void
@@ -822,6 +887,7 @@
}
next:
+ rxFifo.check();
if (rxState == rxIdle)
goto exit;
@@ -845,12 +911,28 @@
int size = virtualRegs.size();
for (int i = 0; i < size; ++i) {
VirtualReg *vn = &virtualRegs[i];
- if (vn->rxPacket != end &&
- !Regs::get_RxDone_Busy(vn->RxDone)) {
+ bool busy = Regs::get_RxDone_Busy(vn->RxDone);
+ if (vn->rxIndex != end) {
+ bool dirty = vn->rxPacketOffset > 0;
+ const char *status;
+
+ if (busy && dirty)
+ status = "busy,dirty";
+ else if (busy)
+ status = "busy";
+ else if (dirty)
+ status = "dirty";
+ else
+ status = "mapped";
+
DPRINTF(EthernetSM,
- "vnic %d (rxunique %d), has outstanding packet
%d\n",
- i, vn->rxUnique,
- rxFifo.countPacketsBefore(vn->rxPacket));
+ "vnic %d %s (rxunique %d), packet %d, slack %d\n",
+ i, status, vn->rxUnique,
+ rxFifo.countPacketsBefore(vn->rxIndex),
+ vn->rxIndex->slack);
+ } else if (busy) {
+ DPRINTF(EthernetSM, "vnic %d unmapped (rxunique %d)\n",
+ i, vn->rxUnique);
}
}
}
@@ -860,7 +942,7 @@
rxBusy.pop_front();
vnic = &virtualRegs[rxActive];
- if (vnic->rxPacket == rxFifo.end())
+ if (vnic->rxIndex == rxFifo.end())
panic("continuing vnic without packet\n");
DPRINTF(EthernetSM,
@@ -868,6 +950,14 @@
rxActive, vnic->rxUnique);
rxState = rxBeginCopy;
+
+ int vnic_distance = rxFifo.countPacketsBefore(vnic->rxIndex);
+ totalVnicDistance += vnic_distance;
+ numVnicDistance += 1;
+ if (vnic_distance > _maxVnicDistance) {
+ maxVnicDistance = vnic_distance;
+ _maxVnicDistance = vnic_distance;
+ }
break;
}
@@ -891,14 +981,16 @@
rxActive, vnic->rxUnique);
// Grab a new packet from the fifo.
- vnic->rxPacket = rxFifoPtr++;
+ vnic->rxIndex = rxFifoPtr++;
+ vnic->rxIndex->priv = rxActive;
vnic->rxPacketOffset = 0;
- vnic->rxPacketBytes = vnic->rxPacket->packet->length;
+ vnic->rxPacketBytes = vnic->rxIndex->packet->length;
assert(vnic->rxPacketBytes);
+ rxMappedCount++;
vnic->rxDoneData = 0;
/* scope for variables */ {
- IpPtr ip(vnic->rxPacket->packet);
+ IpPtr ip(vnic->rxIndex->packet);
if (ip) {
DPRINTF(Ethernet, "ID is %d\n", ip->id());
vnic->rxDoneData |= Regs::RxDone_IpPacket;
@@ -939,15 +1031,25 @@
rxDmaAddr = params()->platform->pciToDma(
Regs::get_RxData_Addr(vnic->RxData));
- rxDmaLen = std::min<int>(Regs::get_RxData_Len(vnic->RxData),
+ rxDmaLen = min<int>(Regs::get_RxData_Len(vnic->RxData),
vnic->rxPacketBytes);
- rxDmaData = vnic->rxPacket->packet->data + vnic->rxPacketOffset;
+
+ /*
+ * if we're doing zero/delay copy and we're below the fifo
+ * threshold, see if we should try to do the zero/defer copy
+ */
+ if ((Regs::get_Config_ZeroCopy(regs.Config) ||
_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev