diff -r 4575d2f29d66 -r 88c63064bb48 src/mem/cache/cache_impl.hh --- a/src/mem/cache/cache_impl.hh Thu Jun 12 14:48:05 2014 -0500 +++ b/src/mem/cache/cache_impl.hh Thu Jun 12 14:48:06 2014 -0500 @@ -166,8 +166,12 @@ } else if (pkt->isWrite()) { if (blk->checkWrite(pkt)) { pkt->writeDataToBlock(blk->data, blkSize); - blk->status |= BlkDirty; } + // Always mark the line as dirty even if we are a failed + // StoreCond so we supply data to any snoops that have + // appended themselves to this cache before knowing the store + // will fail. + blk->status |= BlkDirty; } else if (pkt->isRead()) { if (pkt->isLLSC()) { blk->trackLoadLocked(pkt); @@ -654,6 +658,13 @@ // (read-only) and we need exclusive assert(needsExclusive && !blk->isWritable()); cmd = cpu_pkt->isLLSC() ? MemCmd::SCUpgradeReq : MemCmd::UpgradeReq; + } else if (cpu_pkt->cmd == MemCmd::SCUpgradeFailReq || + cpu_pkt->cmd == MemCmd::StoreCondFailReq) { + // Even though this SC will fail, we still need to send out the + // request and get the data to supply it to other snoopers in the case + // where the determination the StoreCond fails is delayed due to + // all caches not being on the same local bus. + cmd = MemCmd::SCUpgradeFailReq; } else { // block is invalid cmd = needsExclusive ? MemCmd::ReadExReq : MemCmd::ReadReq; @@ -1720,18 +1731,7 @@ DPRINTF(CachePort, "%s %s for address %x size %d\n", __func__, tgt_pkt->cmdString(), tgt_pkt->getAddr(), tgt_pkt->getSize()); - if (tgt_pkt->cmd == MemCmd::SCUpgradeFailReq || - tgt_pkt->cmd == MemCmd::StoreCondFailReq) { - // SCUpgradeReq or StoreCondReq saw invalidation while queued - // in MSHR, so now that we are getting around to processing - // it, just treat it as if we got a failure response - pkt = new Packet(tgt_pkt); - pkt->cmd = MemCmd::UpgradeFailResp; - pkt->senderState = mshr; - pkt->busFirstWordDelay = pkt->busLastWordDelay = 0; - recvTimingResp(pkt); - return NULL; - } else if (mshr->isForwardNoResponse()) { + if (mshr->isForwardNoResponse()) { // no response expected, just forward packet as it is assert(tags->findBlock(mshr->addr, mshr->isSecure) == NULL); pkt = tgt_pkt; diff -r 4575d2f29d66 -r 88c63064bb48 src/mem/packet.cc --- a/src/mem/packet.cc Thu Jun 12 14:48:05 2014 -0500 +++ b/src/mem/packet.cc Thu Jun 12 14:48:06 2014 -0500 @@ -115,12 +115,13 @@ /* UpgradeResp */ { SET3(NeedsExclusive, IsUpgrade, IsResponse), InvalidCmd, "UpgradeResp" }, - /* SCUpgradeFailReq: generates UpgradeFailResp ASAP */ - { SET5(IsInvalidate, NeedsExclusive, IsLlsc, - IsRequest, NeedsResponse), + /* SCUpgradeFailReq: generates UpgradeFailResp but still gets the data */ + { SET6(IsRead, NeedsExclusive, IsInvalidate, + IsLlsc, IsRequest, NeedsResponse), UpgradeFailResp, "SCUpgradeFailReq" }, - /* UpgradeFailResp */ - { SET2(NeedsExclusive, IsResponse), + /* UpgradeFailResp - Behaves like a ReadExReq, but notifies an SC + * that it has failed, acquires line as Dirty*/ + { SET4(IsRead, NeedsExclusive, IsResponse, HasData), InvalidCmd, "UpgradeFailResp" }, /* ReadExReq */ { SET5(IsRead, NeedsExclusive, IsInvalidate, IsRequest, NeedsResponse), @@ -136,7 +137,7 @@ { SET6(IsWrite, NeedsExclusive, IsLlsc, IsRequest, NeedsResponse, HasData), StoreCondResp, "StoreCondReq" }, - /* StoreCondFailReq: generates failing StoreCondResp ASAP */ + /* StoreCondFailReq: generates failing StoreCondResp */ { SET6(IsWrite, NeedsExclusive, IsLlsc, IsRequest, NeedsResponse, HasData), StoreCondResp, "StoreCondFailReq" },