From 2141c2904af0f72dba4f6ec19983392d53c718bd Mon Sep 17 00:00:00 2001 From: Nikos Nikoleris Date: Thu, 8 Sep 2016 12:02:47 +0100 Subject: mem: Promote deferred targets only when the block is valid When a response indicates that there are no other sharers of the block, the cache can promote its copy of the block to writable and potential service deferred targets even if the request didn't ask for a writable copy. Previously, a response would guarantee the presence of the block in the cache. A response could either be filling, upgrading or a response to an invalidation due to a pending whole line write. Responses to cache maintenance invalidations break this assumption. This change adds an extra check to make sure that the block was already valid or that the response is filling before promoting the block. Change-Id: I6839f683a05d4dad4205c23f365a925b7b05e366 Reviewed-by: Curtis Dunham Reviewed-by: Anouk Van Laer Reviewed-on: https://gem5-review.googlesource.com/5048 Maintainer: Nikos Nikoleris Reviewed-by: Jason Lowe-Power --- src/mem/cache/cache.cc | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/mem/cache/cache.cc b/src/mem/cache/cache.cc index 97df5625b..48974c73e 100644 --- a/src/mem/cache/cache.cc +++ b/src/mem/cache/cache.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2016 ARM Limited + * Copyright (c) 2010-2017 ARM Limited * All rights reserved. * * The license below extends only to copyright in the software and shall @@ -1336,16 +1336,17 @@ Cache::recvTimingResp(PacketPtr pkt) Tick forward_time = clockEdge(forwardLatency) + pkt->headerDelay; - // upgrade deferred targets if the response has no sharers, and is - // thus passing writable - if (!pkt->hasSharers()) { - mshr->promoteWritable(); - } - bool is_fill = !mshr->isForward && (pkt->isRead() || pkt->cmd == MemCmd::UpgradeResp); CacheBlk *blk = tags->findBlock(pkt->getAddr(), pkt->isSecure()); + const bool valid_blk = blk && blk->isValid(); + // If the response indicates that there are no sharers and we + // either had the block already or the response is filling we can + // promote our copy to writable + if (!pkt->hasSharers() && (is_fill || valid_blk)) { + mshr->promoteWritable(); + } if (is_fill && !is_error) { DPRINTF(Cache, "Block for addr %#llx being updated in Cache\n", -- cgit v1.2.3