diff --git a/src/mem/ruby/protocol/chi/CHI-cache-actions.sm b/src/mem/ruby/protocol/chi/CHI-cache-actions.sm index 65182ae960..280ae50fac 100644 --- a/src/mem/ruby/protocol/chi/CHI-cache-actions.sm +++ b/src/mem/ruby/protocol/chi/CHI-cache-actions.sm @@ -904,17 +904,18 @@ action(Initiate_CopyBack_Stale, desc="") { tbe.actions.pushNB(Event:SendCompDBIDRespStale); tbe.actions.pushNB(Event:WriteFEPipe); + tbe.actions.push(Event:FinishCopyBack_Stale); + assert((tbe.dir_ownerExists == false) || (tbe.dir_owner != tbe.requestor)); +} + +action(Finish_CopyBack_Stale, desc="") { // if it was the last known sharer and we don't have the data do the same // the Initiate_Evict - if ((is_HN == false) && (tbe.dir_sharers.count() == 1) && + if ((is_HN == false) && (tbe.dir_sharers.count() == 0) && tbe.dir_sharers.isElement(tbe.requestor) && (tbe.dataValid == false)) { tbe.actions.push(Event:SendEvict); } - - tbe.dir_sharers.remove(tbe.requestor); - assert((tbe.dir_ownerExists == false) || (tbe.dir_owner != tbe.requestor)); - } action(Initiate_Evict, desc="") { @@ -1756,7 +1757,10 @@ action(UpdateDirState_FromReqDataResp, desc="") { } else if (in_msg.type == CHIDataType:CBWrData_SC) { assert((tbe.dir_ownerExists == false) || (tbe.dir_owner != in_msg.responder)); - tbe.dir_sharers.remove(in_msg.responder); + // Do not remove the responder in case of stale WriteCleanFull + if (tbe.reqType != CHIRequestType:WriteCleanFull) { + tbe.dir_sharers.remove(in_msg.responder); + } } else if (in_msg.type == CHIDataType:CBWrData_SD_PD) { assert(tbe.dir_ownerExists && (tbe.dir_ownerIsExcl == false) && (tbe.dir_owner == in_msg.responder)); diff --git a/src/mem/ruby/protocol/chi/CHI-cache-transitions.sm b/src/mem/ruby/protocol/chi/CHI-cache-transitions.sm index 87e5f0b46c..d591af3781 100644 --- a/src/mem/ruby/protocol/chi/CHI-cache-transitions.sm +++ b/src/mem/ruby/protocol/chi/CHI-cache-transitions.sm @@ -1043,6 +1043,12 @@ transition(BUSY_BLKD, FinishCleanUnique) { ProcessNextState_ClearPending; } +transition(BUSY_BLKD, FinishCopyBack_Stale) { + Pop_TriggerQueue; + Finish_CopyBack_Stale; + ProcessNextState_ClearPending; +} + transition(BUSY_BLKD, CheckUpgrade_FromStore) { Pop_TriggerQueue; Callback_Miss; // note: Callback happens only if tbe.dataValid diff --git a/src/mem/ruby/protocol/chi/CHI-cache.sm b/src/mem/ruby/protocol/chi/CHI-cache.sm index a69748ef45..3770382bf3 100644 --- a/src/mem/ruby/protocol/chi/CHI-cache.sm +++ b/src/mem/ruby/protocol/chi/CHI-cache.sm @@ -504,6 +504,7 @@ machine(MachineType:Cache, "Cache coherency protocol") : TX_Data, desc="Transmit pending data messages"; MaintainCoherence, desc="Queues a WriteBack or Evict before droping the only valid copy of the block"; FinishCleanUnique, desc="Sends acks and perform any writeback after a CleanUnique"; + FinishCopyBack_Stale, desc="Check if a Evict needs to be sent"; ActionStalledOnHazard, desc="Stall a trigger action because until finish handling snoop hazard"; // This is triggered once a transaction doesn't have