diff -r e99cba7081db -r 7aa00b79bc99 src/mem/cache/cache_impl.hh --- a/src/mem/cache/cache_impl.hh Fri Feb 13 08:45:46 2015 +0000 +++ b/src/mem/cache/cache_impl.hh Fri Feb 13 08:45:56 2015 +0000 @@ -1966,10 +1966,25 @@ snoop_pkt.senderState = mshr; cpuSidePort->sendTimingSnoopReq(&snoop_pkt); - // Check to see if the prefetch was squashed by an upper - // cache (to prevent us from grabbing the line) or if a - // writeback arrived between the time the prefetch was - // placed in the MSHRs and when it was selected to be sent. + // Check to see if a writeback arrived between the time the + // prefetch was placed in the MSHRs and when it was selected to + // send or if the prefetch was squashed by an upper cache. + + // It is important to check memInhibitAsserted before prefetch- + // squashed. If another cache has asserted memInhibit, it will be + // sending a response which will arrive at the mshr allocated for + // this request. Checking the prefetch squash first may result in + // the mshr being prematurely deallocated. + + if (snoop_pkt.memInhibitAsserted()) { + bool pending_dirty_resp = !snoop_pkt.sharedAsserted(); + markInService(mshr, pending_dirty_resp); + DPRINTF(Cache, "Upward snoop of prefetch for addr" + " %#x (%s) hit\n", + tgt_pkt->getAddr(), tgt_pkt->isSecure()? "s": "ns"); + return NULL; + } + if (snoop_pkt.prefetchSquashed() || blk != NULL) { DPRINTF(Cache, "Prefetch squashed by cache. " "Deallocating mshr target %#x.\n", mshr->addr); @@ -1982,19 +1997,6 @@ } return NULL; } - - // Check if the prefetch hit a writeback in an upper cache - // and if so we will eventually get a HardPFResp from - // above - if (snoop_pkt.memInhibitAsserted()) { - // If we are getting a non-shared response it is dirty - bool pending_dirty_resp = !snoop_pkt.sharedAsserted(); - markInService(mshr, pending_dirty_resp); - DPRINTF(Cache, "Upward snoop of prefetch for addr" - " %#x (%s) hit\n", - tgt_pkt->getAddr(), tgt_pkt->isSecure()? "s": "ns"); - return NULL; - } } pkt = getBusPacket(tgt_pkt, blk, mshr->needsExclusive());