diff -r 29f1c6149efb -r cda786f0fb05 src/mem/cache/cache_impl.hh --- a/src/mem/cache/cache_impl.hh Tue Mar 26 14:13:42 2013 -0400 +++ b/src/mem/cache/cache_impl.hh Tue Mar 26 14:13:42 2013 -0400 @@ -1310,6 +1310,9 @@ if (is_timing) { Packet snoopPkt(pkt, true); // clear flags snoopPkt.setExpressSnoop(); + if (pkt->isSnoopNoResp()) + snoopPkt.setSnoopNoResp(); + snoopPkt.pushSenderState(new ForwardResponseRecord(pkt->getSrc())); // the snoop packet does not need to wait any additional // time @@ -1335,7 +1338,10 @@ } } - if (!blk || !blk->isValid()) { + // If the packet is a snoop that doesn't want a response (because it's a + // prefetch that will get dropped), just return here. See comment in + // prefetch code for race that can occur if we don't. + if (!blk || !blk->isValid() || pkt->isSnoopNoResp()) { return; } @@ -1628,11 +1634,16 @@ // in place of the dirty one. PacketPtr snoop_pkt = new Packet(tgt_pkt, true); snoop_pkt->setExpressSnoop(); + snoop_pkt->setSnoopNoResp(); snoop_pkt->senderState = mshr; cpuSidePort->sendTimingSnoopReq(snoop_pkt); if (snoop_pkt->memInhibitAsserted()) { - markInService(mshr, snoop_pkt); + // Someone else has the line, we should forget about our + // prefetch. Otherwise, there is a race between this cache + // getting the line and another request coming in and hitting + // in the mshr that isn't known to be dirty yet + mshr->queue->deallocate(mshr); DPRINTF(Cache, "Upward snoop of prefetch for addr %#x hit\n", tgt_pkt->getAddr()); delete snoop_pkt; diff -r 29f1c6149efb -r cda786f0fb05 src/mem/packet.hh --- a/src/mem/packet.hh Tue Mar 26 14:13:42 2013 -0400 +++ b/src/mem/packet.hh Tue Mar 26 14:13:42 2013 -0400 @@ -245,6 +245,7 @@ static const FlagsType SUPPLY_EXCLUSIVE = 0x00000004; // Snoop response flags static const FlagsType MEM_INHIBIT = 0x00000008; + static const FlagsType SNOOP_NO_RESP = 0x00000010; /// Are the 'addr' and 'size' fields valid? static const FlagsType VALID_ADDR = 0x00000100; static const FlagsType VALID_SIZE = 0x00000200; @@ -514,6 +515,8 @@ // Special control flags void setExpressSnoop() { flags.set(EXPRESS_SNOOP); } bool isExpressSnoop() { return flags.isSet(EXPRESS_SNOOP); } + void setSnoopNoResp() { flags.set(SNOOP_NO_RESP); } + bool isSnoopNoResp() { return flags.isSet(SNOOP_NO_RESP); } void setSupplyExclusive() { flags.set(SUPPLY_EXCLUSIVE); } void clearSupplyExclusive() { flags.clear(SUPPLY_EXCLUSIVE); } bool isSupplyExclusive() { return flags.isSet(SUPPLY_EXCLUSIVE); }