Seems like only part of the message came through the first time... let
me try again...
This message is primarily directed at Steve, but anyone else who
happens to know the answer, feel free to jump in. I've recently run gem5
through valgrind in timing mode with caches enabled and an error pops up
that I've been unable to come up with a solution to.
==4912== Invalid read of size 4
==4912== at 0x4AFE14: MemCmd::testCmdAttrib(MemCmd::Attribute) const
(packet.hh:164)
==4912== by 0x4AFE4D: MemCmd::needsResponse() const (packet.hh:175)
==4912== by 0x4AFE68: Packet::needsResponse() const (packet.hh:415)
==4912== by 0x9857A1: MSHR::isForwardNoResponse() const
(mshr.hh:266)
==4912== by 0x9C2F87: MSHR::markInService(Packet*) (mshr.cc:215)
==4912== by 0x9C7466: MSHRQueue::markInService(MSHR*, Packet*)
(mshr_queue.cc:202)
==4912== by 0x988796: BaseCache::markInServiceInternal(MSHR*,
Packet*) (base.hh:179)
==4912== by 0x988800: Cache<LRU>::markInService(MSHR*, Packet*)
(cache_impl.hh:262)
==4912== by 0x999939: Cache<LRU>::MemSidePort::sendPacket()
(cache_impl.hh:1711)
==4912== by 0x99A146: Cache<LRU>::MemSidePort::recvRetry()
(cache_impl.hh:1741)
==4912== by 0x6F8E45: Port::sendRetry() (port.hh:212)
==4912== by 0x92F5D5: Bus::recvRetry(int) (bus.cc:305)
==4912== Address 0x18ecb46c is 12 bytes inside a block of size 88
free'd
==4912== at 0x4A0618C: operator delete(void*)
(vg_replace_malloc.c:342)
==4912== by 0x9407D9: Packet::~Packet() (packet.hh:570)
==4912== by 0x99FAE7: Cache<LRU>::timingAccess(Packet*)
(cache_impl.hh:527)
==4912== by 0x9A057D: Cache<LRU>::CpuSidePort::recvTiming(Packet*)
(cache_impl.hh:1583)
==4912== by 0x5A0D73: Port::sendTiming(Packet*) (port.hh:186)
==4912== by 0x931281: Bus::recvTiming(Packet*) (bus.cc:265)
==4912== by 0x93C483: Bus::BusPort::recvTiming(Packet*) (bus.hh:89)
==4912== by 0x5A0D73: Port::sendTiming(Packet*) (port.hh:186)
==4912== by 0x9991E9: Cache<LRU>::MemSidePort::sendPacket()
(cache_impl.hh:1702)
==4912== by 0x99A146: Cache<LRU>::MemSidePort::recvRetry()
(cache_impl.hh:1741)
==4912== by 0x6F8E45: Port::sendRetry() (port.hh:212)
==4912== by 0x92F5D5: Bus::recvRetry(int) (bus.cc:305)
I've tracked it down to the following:
// check for non-response packets (requests & writebacks)
PacketPtr pkt = myCache()->getTimingPacket();
if (pkt == NULL) {
....
} else {
MSHR *mshr = dynamic_cast<MSHR*>(pkt->senderState);
bool success = sendTiming(pkt); <-------- Writeback
packet is sent to lower level cache
<-------- It's
immediately accepted and deleted (see below)
waitingOnRetry = !success;
if (waitingOnRetry) {
DPRINTF(CachePort, "now waiting on a retry\n");
if (!mshr->isForwardNoResponse()) {
delete pkt;
}
} else {
myCache()->markInService(mshr, pkt); <---- Now we call
markInService which checks if the packet is
<-----
isForwardNoResponse(), unfortunately, the pkt has been deleted.
}
On the receive side of the cache
if (satisfied) {
if (needsResponse) {
pkt->makeTimingResponse();
cpuSidePort->respond(pkt, curTick()+lat);
} else {
delete pkt; <-- Writeback doesn't need a response, so the
receiver deletes it, but the sender hasn't figured
<-- out if it's isForwardNoResponse() to delete
the MSHR, and thus we access freed memory.
}
.............
} else {
I can't really come up with a solution I like to this problem. If I
don't delete the packet in the down stream cache and put a hack in to
delete it in the upstream cache that seems like a hack and violates the
principle that the recipient is responsible for the packet. I could copy
the packet in the sending cache and feed that into the markInService
function, but I don't like that either.
Suggestions?
Thanks,
Ali
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev