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

Reply via email to