diff options
author | Daniel R. Carvalho <odanrc@yahoo.com.br> | 2019-06-12 17:26:11 +0200 |
---|---|---|
committer | Daniel Carvalho <odanrc@yahoo.com.br> | 2020-01-17 16:31:03 +0000 |
commit | 7dce9e3782523e1b1989c50be194385b93603aea (patch) | |
tree | 47e9084bf1a6c5b229836a659d4e4a9e9b79956f | |
parent | c5d87b0693f1f3cab8bf05ba5327986940cedf5b (diff) | |
download | gem5-7dce9e3782523e1b1989c50be194385b93603aea.tar.xz |
mem-cache: Factor out multiple block eviction
Create a function to try to evict multiple blocks while checking for
transient state.
Change-Id: I6a879fa5e793cd92c4bdf4a258a133de4c865012
Signed-off-by: Daniel R. Carvalho <odanrc@yahoo.com.br>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/22607
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com>
-rw-r--r-- | src/mem/cache/base.cc | 112 | ||||
-rw-r--r-- | src/mem/cache/base.hh | 12 |
2 files changed, 58 insertions, 66 deletions
diff --git a/src/mem/cache/base.cc b/src/mem/cache/base.cc index d56fcbeee..87f2af161 100644 --- a/src/mem/cache/base.cc +++ b/src/mem/cache/base.cc @@ -795,6 +795,43 @@ BaseCache::getNextQueueEntry() } bool +BaseCache::handleEvictions(std::vector<CacheBlk*> &evict_blks, + PacketList &writebacks) +{ + bool replacement = false; + for (const auto& blk : evict_blks) { + if (blk->isValid()) { + replacement = true; + + const MSHR* mshr = + mshrQueue.findMatch(regenerateBlkAddr(blk), blk->isSecure()); + if (mshr) { + // Must be an outstanding upgrade or clean request on a block + // we're about to replace + assert((!blk->isWritable() && mshr->needsWritable()) || + mshr->isCleaning()); + return false; + } + } + } + + // The victim will be replaced by a new entry, so increase the replacement + // counter if a valid block is being replaced + if (replacement) { + stats.replacements++; + + // Evict valid blocks associated to this victim block + for (auto& blk : evict_blks) { + if (blk->isValid()) { + evictBlock(blk, writebacks); + } + } + } + + return true; +} + +bool BaseCache::updateCompressionData(CacheBlk *blk, const uint64_t* data, PacketList &writebacks) { @@ -833,37 +870,20 @@ BaseCache::updateCompressionData(CacheBlk *blk, const uint64_t* data, // allocated blocks to make room for the expansion, but other approaches // that take the replacement data of the superblock into account may // generate better results - std::vector<CacheBlk*> evict_blks; const bool was_compressed = compression_blk->isCompressed(); if (was_compressed && !is_co_allocatable) { - // Get all co-allocated blocks + std::vector<CacheBlk*> evict_blks; for (const auto& sub_blk : superblock->blks) { if (sub_blk->isValid() && (compression_blk != sub_blk)) { - // Check for transient state allocations. If any of the - // entries listed for eviction has a transient state, the - // allocation fails - const Addr repl_addr = regenerateBlkAddr(sub_blk); - const MSHR *repl_mshr = - mshrQueue.findMatch(repl_addr, sub_blk->isSecure()); - if (repl_mshr) { - DPRINTF(CacheRepl, "Aborting data expansion of %s due " \ - "to replacement of block in transient state: %s\n", - compression_blk->print(), sub_blk->print()); - // Too hard to replace block with transient state, so it - // cannot be evicted. Mark the update as failed and expect - // the caller to evict this block. Since this is called - // only when writebacks arrive, and packets do not contain - // compressed data, there is no need to decompress - compression_blk->setSizeBits(blkSize * 8); - compression_blk->setDecompressionLatency(Cycles(0)); - compression_blk->setUncompressed(); - return false; - } - evict_blks.push_back(sub_blk); } } + // Try to evict blocks; if it fails, give up on update + if (!handleEvictions(evict_blks, writebacks)) { + return false; + } + // Update the number of data expansions stats.dataExpansions++; @@ -880,13 +900,6 @@ BaseCache::updateCompressionData(CacheBlk *blk, const uint64_t* data, compression_blk->setSizeBits(compression_size); compression_blk->setDecompressionLatency(decompression_lat); - // Evict valid blocks - for (const auto& evict_blk : evict_blks) { - if (evict_blk->isValid()) { - evictBlock(evict_blk, writebacks); - } - } - return true; } @@ -1427,42 +1440,9 @@ BaseCache::allocateBlock(const PacketPtr pkt, PacketList &writebacks) // Print victim block's information DPRINTF(CacheRepl, "Replacement victim: %s\n", victim->print()); - // Check for transient state allocations. If any of the entries listed - // for eviction has a transient state, the allocation fails - bool replacement = false; - for (const auto& blk : evict_blks) { - if (blk->isValid()) { - replacement = true; - - Addr repl_addr = regenerateBlkAddr(blk); - MSHR *repl_mshr = mshrQueue.findMatch(repl_addr, blk->isSecure()); - if (repl_mshr) { - // must be an outstanding upgrade or clean request - // on a block we're about to replace... - assert((!blk->isWritable() && repl_mshr->needsWritable()) || - repl_mshr->isCleaning()); - - // too hard to replace block with transient state - // allocation failed, block not inserted - return nullptr; - } - } - } - - // The victim will be replaced by a new entry, so increase the replacement - // counter if a valid block is being replaced - if (replacement) { - // Evict valid blocks associated to this victim block - for (const auto& blk : evict_blks) { - if (blk->isValid()) { - DPRINTF(CacheRepl, "Evicting %s (%#llx) to make room for " \ - "%#llx (%s)\n", blk->print(), regenerateBlkAddr(blk), - addr, is_secure); - evictBlock(blk, writebacks); - } - } - - stats.replacements++; + // Try to evict blocks; if it fails, give up on allocation + if (!handleEvictions(evict_blks, writebacks)) { + return nullptr; } // If using a compressor, set compression data. This must be done before diff --git a/src/mem/cache/base.hh b/src/mem/cache/base.hh index cd467c8ad..8e5c18c11 100644 --- a/src/mem/cache/base.hh +++ b/src/mem/cache/base.hh @@ -710,6 +710,18 @@ class BaseCache : public ClockedObject void maintainClusivity(bool from_cache, CacheBlk *blk); /** + * Try to evict the given blocks. If any of them is a transient eviction, + * that is, the block is present in the MSHR queue all evictions are + * cancelled since handling such cases has not been implemented. + * + * @param evict_blks Blocks marked for eviction. + * @param writebacks List for any writebacks that need to be performed. + * @return False if any of the evicted blocks is in transient state. + */ + bool handleEvictions(std::vector<CacheBlk*> &evict_blks, + PacketList &writebacks); + + /** * Handle a fill operation caused by a received packet. * * Populates a cache block and handles all outstanding requests for the |