hopefully the final hacky change to make the bus bridge work ok
cache blocks that get dmaed ARE NOT marked invalid in the caches so it's a performance issue here src/mem/bridge.cc: src/mem/bridge.hh: hopefully the final hacky change to make the bus bridge work ok --HG-- extra : convert_revision : 62cbc65c74d1a84199f0a376546ec19994c5899c
This commit is contained in:
parent
fcf85725b5
commit
f317227b4e
3 changed files with 18 additions and 79 deletions
|
@ -23,7 +23,7 @@ netcat -c -l -p 8000
|
||||||
|
|
||||||
BINARY=/benchmarks/netperf-bin/netperf
|
BINARY=/benchmarks/netperf-bin/netperf
|
||||||
TEST="UDP_STREAM"
|
TEST="UDP_STREAM"
|
||||||
SHORT_ARGS="-l 2 -- -m 4096"
|
SHORT_ARGS="-l 2 -- -m 16384 -M 16384 -s 262144 -S 262144"
|
||||||
#LONG_ARGS="-k16384,0 -K16384,0 -- -m 65536 -M 65536 -s 262144 -S 262144"
|
#LONG_ARGS="-k16384,0 -K16384,0 -- -m 65536 -M 65536 -s 262144 -S 262144"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -247,8 +247,6 @@ Bridge::BridgePort::trySend()
|
||||||
{
|
{
|
||||||
assert(!sendQueue.empty());
|
assert(!sendQueue.empty());
|
||||||
|
|
||||||
int pbs = peerBlockSize();
|
|
||||||
|
|
||||||
PacketBuffer *buf = sendQueue.front();
|
PacketBuffer *buf = sendQueue.front();
|
||||||
|
|
||||||
assert(buf->ready <= curTick);
|
assert(buf->ready <= curTick);
|
||||||
|
@ -257,11 +255,15 @@ Bridge::BridgePort::trySend()
|
||||||
|
|
||||||
pkt->flags &= ~SNOOP_COMMIT; //CLear it if it was set
|
pkt->flags &= ~SNOOP_COMMIT; //CLear it if it was set
|
||||||
|
|
||||||
|
// Ugly! @todo When multilevel coherence works this will be removed
|
||||||
if (pkt->cmd == MemCmd::WriteInvalidateReq && fixPartialWrite &&
|
if (pkt->cmd == MemCmd::WriteInvalidateReq && fixPartialWrite &&
|
||||||
pkt->result != Packet::Nacked && pkt->getOffset(pbs) &&
|
pkt->result != Packet::Nacked) {
|
||||||
pkt->getSize() != pbs) {
|
PacketPtr funcPkt = new Packet(pkt->req, MemCmd::WriteReq,
|
||||||
buf->partialWriteFix(this);
|
Packet::Broadcast);
|
||||||
pkt = buf->pkt;
|
funcPkt->dataStatic(pkt->getPtr<uint8_t>());
|
||||||
|
sendFunctional(funcPkt);
|
||||||
|
pkt->cmd = MemCmd::WriteReq;
|
||||||
|
delete funcPkt;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINTF(BusBridge, "trySend: origSrc %d dest %d addr 0x%x\n",
|
DPRINTF(BusBridge, "trySend: origSrc %d dest %d addr 0x%x\n",
|
||||||
|
@ -300,7 +302,6 @@ Bridge::BridgePort::trySend()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DPRINTF(BusBridge, " unsuccessful\n");
|
DPRINTF(BusBridge, " unsuccessful\n");
|
||||||
buf->undoPartialWriteFix();
|
|
||||||
inRetry = true;
|
inRetry = true;
|
||||||
}
|
}
|
||||||
DPRINTF(BusBridge, "trySend: queue size: %d outreq: %d outstanding resp: %d\n",
|
DPRINTF(BusBridge, "trySend: queue size: %d outreq: %d outstanding resp: %d\n",
|
||||||
|
@ -324,32 +325,18 @@ Bridge::BridgePort::recvRetry()
|
||||||
Tick
|
Tick
|
||||||
Bridge::BridgePort::recvAtomic(PacketPtr pkt)
|
Bridge::BridgePort::recvAtomic(PacketPtr pkt)
|
||||||
{
|
{
|
||||||
int pbs = otherPort->peerBlockSize();
|
|
||||||
Tick atomic_delay;
|
|
||||||
// fix partial atomic writes... similar to the timing code that does the
|
// fix partial atomic writes... similar to the timing code that does the
|
||||||
// same
|
// same... will be removed once our code gets this right
|
||||||
if (pkt->cmd == MemCmd::WriteInvalidateReq && fixPartialWrite &&
|
if (pkt->cmd == MemCmd::WriteInvalidateReq && fixPartialWrite) {
|
||||||
pkt->getOffset(pbs) && pkt->getSize() != pbs) {
|
|
||||||
PacketDataPtr data;
|
|
||||||
data = new uint8_t[pbs];
|
|
||||||
PacketPtr funcPkt = new Packet(pkt->req, MemCmd::ReadReq,
|
|
||||||
Packet::Broadcast, pbs);
|
|
||||||
|
|
||||||
funcPkt->dataStatic(data);
|
PacketPtr funcPkt = new Packet(pkt->req, MemCmd::WriteReq,
|
||||||
|
Packet::Broadcast);
|
||||||
|
funcPkt->dataStatic(pkt->getPtr<uint8_t>());
|
||||||
otherPort->sendFunctional(funcPkt);
|
otherPort->sendFunctional(funcPkt);
|
||||||
assert(funcPkt->result == Packet::Success);
|
|
||||||
delete funcPkt;
|
delete funcPkt;
|
||||||
memcpy(data + pkt->getOffset(pbs), pkt->getPtr<uint8_t>(),
|
pkt->cmd = MemCmd::WriteReq;
|
||||||
pkt->getSize());
|
|
||||||
PacketPtr newPkt = new Packet(pkt->req, MemCmd::WriteInvalidateReq,
|
|
||||||
Packet::Broadcast, pbs);
|
|
||||||
pkt->dataDynamicArray(data);
|
|
||||||
atomic_delay = otherPort->sendAtomic(newPkt);
|
|
||||||
delete newPkt;
|
|
||||||
} else {
|
|
||||||
atomic_delay = otherPort->sendAtomic(pkt);
|
|
||||||
}
|
}
|
||||||
return atomic_delay + delay;
|
return delay + otherPort->sendAtomic(pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Function called by the port when the bus is receiving a Functional
|
/** Function called by the port when the bus is receiving a Functional
|
||||||
|
@ -431,3 +418,4 @@ CREATE_SIM_OBJECT(Bridge)
|
||||||
|
|
||||||
REGISTER_SIM_OBJECT("Bridge", Bridge)
|
REGISTER_SIM_OBJECT("Bridge", Bridge)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -80,14 +80,10 @@ class Bridge : public MemObject
|
||||||
short origSrc;
|
short origSrc;
|
||||||
bool expectResponse;
|
bool expectResponse;
|
||||||
|
|
||||||
bool partialWriteFixed;
|
|
||||||
PacketPtr oldPkt;
|
|
||||||
|
|
||||||
PacketBuffer(PacketPtr _pkt, Tick t, bool nack = false)
|
PacketBuffer(PacketPtr _pkt, Tick t, bool nack = false)
|
||||||
: ready(t), pkt(_pkt),
|
: ready(t), pkt(_pkt),
|
||||||
origSenderState(_pkt->senderState), origSrc(_pkt->getSrc()),
|
origSenderState(_pkt->senderState), origSrc(_pkt->getSrc()),
|
||||||
expectResponse(_pkt->needsResponse() && !nack),
|
expectResponse(_pkt->needsResponse() && !nack)
|
||||||
partialWriteFixed(false)
|
|
||||||
|
|
||||||
{
|
{
|
||||||
if (!pkt->isResponse() && !nack && pkt->result != Packet::Nacked)
|
if (!pkt->isResponse() && !nack && pkt->result != Packet::Nacked)
|
||||||
|
@ -99,52 +95,7 @@ class Bridge : public MemObject
|
||||||
assert(pkt->senderState == this);
|
assert(pkt->senderState == this);
|
||||||
pkt->setDest(origSrc);
|
pkt->setDest(origSrc);
|
||||||
pkt->senderState = origSenderState;
|
pkt->senderState = origSenderState;
|
||||||
if (partialWriteFixed)
|
|
||||||
delete oldPkt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void partialWriteFix(Port *port)
|
|
||||||
{
|
|
||||||
assert(!partialWriteFixed);
|
|
||||||
assert(expectResponse);
|
|
||||||
|
|
||||||
Addr pbs = port->peerBlockSize();
|
|
||||||
Addr blockAddr = pkt->getAddr() & ~(pbs-1);
|
|
||||||
partialWriteFixed = true;
|
|
||||||
PacketDataPtr data;
|
|
||||||
|
|
||||||
data = new uint8_t[pbs];
|
|
||||||
RequestPtr funcReq = new Request(blockAddr, 4, 0);
|
|
||||||
PacketPtr funcPkt = new Packet(funcReq, MemCmd::ReadReq,
|
|
||||||
Packet::Broadcast);
|
|
||||||
for (int x = 0; x < pbs; x+=4) {
|
|
||||||
funcReq->setPhys(blockAddr + x, 4, 0);
|
|
||||||
funcPkt->reinitFromRequest();
|
|
||||||
funcPkt->dataStatic(data + x);
|
|
||||||
port->sendFunctional(funcPkt);
|
|
||||||
assert(funcPkt->result == Packet::Success);
|
|
||||||
}
|
|
||||||
delete funcPkt;
|
|
||||||
delete funcReq;
|
|
||||||
|
|
||||||
oldPkt = pkt;
|
|
||||||
memcpy(data + oldPkt->getOffset(pbs), pkt->getPtr<uint8_t>(),
|
|
||||||
pkt->getSize());
|
|
||||||
pkt = new Packet(oldPkt->req, MemCmd::WriteInvalidateReq,
|
|
||||||
Packet::Broadcast, pbs);
|
|
||||||
pkt->dataDynamicArray(data);
|
|
||||||
pkt->senderState = oldPkt->senderState;
|
|
||||||
}
|
|
||||||
|
|
||||||
void undoPartialWriteFix()
|
|
||||||
{
|
|
||||||
if (!partialWriteFixed)
|
|
||||||
return;
|
|
||||||
delete pkt;
|
|
||||||
pkt = oldPkt;
|
|
||||||
partialWriteFixed = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue