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
|
||||
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"
|
||||
|
||||
|
||||
|
|
|
@ -247,8 +247,6 @@ Bridge::BridgePort::trySend()
|
|||
{
|
||||
assert(!sendQueue.empty());
|
||||
|
||||
int pbs = peerBlockSize();
|
||||
|
||||
PacketBuffer *buf = sendQueue.front();
|
||||
|
||||
assert(buf->ready <= curTick);
|
||||
|
@ -257,11 +255,15 @@ Bridge::BridgePort::trySend()
|
|||
|
||||
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 &&
|
||||
pkt->result != Packet::Nacked && pkt->getOffset(pbs) &&
|
||||
pkt->getSize() != pbs) {
|
||||
buf->partialWriteFix(this);
|
||||
pkt = buf->pkt;
|
||||
pkt->result != Packet::Nacked) {
|
||||
PacketPtr funcPkt = new Packet(pkt->req, MemCmd::WriteReq,
|
||||
Packet::Broadcast);
|
||||
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",
|
||||
|
@ -300,7 +302,6 @@ Bridge::BridgePort::trySend()
|
|||
}
|
||||
} else {
|
||||
DPRINTF(BusBridge, " unsuccessful\n");
|
||||
buf->undoPartialWriteFix();
|
||||
inRetry = true;
|
||||
}
|
||||
DPRINTF(BusBridge, "trySend: queue size: %d outreq: %d outstanding resp: %d\n",
|
||||
|
@ -324,32 +325,18 @@ Bridge::BridgePort::recvRetry()
|
|||
Tick
|
||||
Bridge::BridgePort::recvAtomic(PacketPtr pkt)
|
||||
{
|
||||
int pbs = otherPort->peerBlockSize();
|
||||
Tick atomic_delay;
|
||||
// fix partial atomic writes... similar to the timing code that does the
|
||||
// same
|
||||
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);
|
||||
// same... will be removed once our code gets this right
|
||||
if (pkt->cmd == MemCmd::WriteInvalidateReq && fixPartialWrite) {
|
||||
|
||||
funcPkt->dataStatic(data);
|
||||
PacketPtr funcPkt = new Packet(pkt->req, MemCmd::WriteReq,
|
||||
Packet::Broadcast);
|
||||
funcPkt->dataStatic(pkt->getPtr<uint8_t>());
|
||||
otherPort->sendFunctional(funcPkt);
|
||||
assert(funcPkt->result == Packet::Success);
|
||||
delete funcPkt;
|
||||
memcpy(data + pkt->getOffset(pbs), pkt->getPtr<uint8_t>(),
|
||||
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);
|
||||
pkt->cmd = MemCmd::WriteReq;
|
||||
}
|
||||
return atomic_delay + delay;
|
||||
return delay + otherPort->sendAtomic(pkt);
|
||||
}
|
||||
|
||||
/** 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)
|
||||
|
||||
|
||||
|
|
|
@ -80,14 +80,10 @@ class Bridge : public MemObject
|
|||
short origSrc;
|
||||
bool expectResponse;
|
||||
|
||||
bool partialWriteFixed;
|
||||
PacketPtr oldPkt;
|
||||
|
||||
PacketBuffer(PacketPtr _pkt, Tick t, bool nack = false)
|
||||
: ready(t), pkt(_pkt),
|
||||
origSenderState(_pkt->senderState), origSrc(_pkt->getSrc()),
|
||||
expectResponse(_pkt->needsResponse() && !nack),
|
||||
partialWriteFixed(false)
|
||||
expectResponse(_pkt->needsResponse() && !nack)
|
||||
|
||||
{
|
||||
if (!pkt->isResponse() && !nack && pkt->result != Packet::Nacked)
|
||||
|
@ -99,52 +95,7 @@ class Bridge : public MemObject
|
|||
assert(pkt->senderState == this);
|
||||
pkt->setDest(origSrc);
|
||||
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