diff options
-rw-r--r-- | src/mem/cache/base.cc | 58 | ||||
-rw-r--r-- | src/mem/cache/tags/base.hh | 12 | ||||
-rw-r--r-- | src/mem/cache/tags/base_set_assoc.hh | 12 | ||||
-rw-r--r-- | src/mem/cache/tags/fa_lru.cc | 10 | ||||
-rw-r--r-- | src/mem/cache/tags/fa_lru.hh | 7 |
5 files changed, 70 insertions, 29 deletions
diff --git a/src/mem/cache/base.cc b/src/mem/cache/base.cc index efdb3be2c..75b17699a 100644 --- a/src/mem/cache/base.cc +++ b/src/mem/cache/base.cc @@ -1209,38 +1209,56 @@ CacheBlk* BaseCache::allocateBlock(Addr addr, bool is_secure, PacketList &writebacks) { // Find replacement victim - CacheBlk *blk = tags->findVictim(addr); + std::vector<CacheBlk*> evict_blks; + CacheBlk *victim = tags->findVictim(addr, evict_blks); // It is valid to return nullptr if there is no victim - if (!blk) + if (!victim) return nullptr; - if (blk->isValid()) { - 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; - } else { - DPRINTF(Cache, "replacement: replacing %#llx (%s) with %#llx " - "(%s): %s\n", repl_addr, blk->isSecure() ? "s" : "ns", - addr, is_secure ? "s" : "ns", - blk->isDirty() ? "writeback" : "clean"); + // Check for transient state allocations. If any of the entries listed + // for eviction has a transient state, the allocation fails + for (const auto& blk : evict_blks) { + if (blk->isValid()) { + 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 (victim->isValid()) { + DPRINTF(Cache, "replacement: replacing %#llx (%s) with %#llx " + "(%s): %s\n", regenerateBlkAddr(victim), + victim->isSecure() ? "s" : "ns", + addr, is_secure ? "s" : "ns", + victim->isDirty() ? "writeback" : "clean"); + replacements++; + } + + // Evict valid blocks associated to this victim block + for (const auto& blk : evict_blks) { + if (blk->isValid()) { if (blk->wasPrefetched()) { unusedPrefetches++; } + evictBlock(blk, writebacks); - replacements++; } } - return blk; + return victim; } void diff --git a/src/mem/cache/tags/base.hh b/src/mem/cache/tags/base.hh index 167364ff1..27771982a 100644 --- a/src/mem/cache/tags/base.hh +++ b/src/mem/cache/tags/base.hh @@ -262,12 +262,20 @@ class BaseTags : public ClockedObject } /** - * Find replacement victim based on address. + * Find replacement victim based on address. If the address requires + * blocks to be evicted, their locations are listed for eviction. If a + * conventional cache is being used, the list only contains the victim. + * However, if using sector or compressed caches, the victim is one of + * the blocks to be evicted, but its location is the only one that will + * be assigned to the newly allocated block associated to this address. + * @sa insertBlock * * @param addr Address to find a victim for. + * @param evict_blks Cache blocks to be evicted. * @return Cache block to be replaced. */ - virtual CacheBlk* findVictim(Addr addr) = 0; + virtual CacheBlk* findVictim(Addr addr, std::vector<CacheBlk*>& evict_blks) + const = 0; virtual CacheBlk* accessBlock(Addr addr, bool is_secure, Cycles &lat) = 0; diff --git a/src/mem/cache/tags/base_set_assoc.hh b/src/mem/cache/tags/base_set_assoc.hh index 475566268..d19a00ed9 100644 --- a/src/mem/cache/tags/base_set_assoc.hh +++ b/src/mem/cache/tags/base_set_assoc.hh @@ -200,12 +200,15 @@ class BaseSetAssoc : public BaseTags ReplaceableEntry* findBlockBySetAndWay(int set, int way) const override; /** - * Find replacement victim based on address. + * Find replacement victim based on address. The list of evicted blocks + * only contains the victim. * * @param addr Address to find a victim for. + * @param evict_blks Cache blocks to be evicted. * @return Cache block to be replaced. */ - CacheBlk* findVictim(Addr addr) override + CacheBlk* findVictim(Addr addr, std::vector<CacheBlk*>& evict_blks) const + override { // Get possible locations for the victim block std::vector<CacheBlk*> locations = getPossibleLocations(addr); @@ -215,6 +218,9 @@ class BaseSetAssoc : public BaseTags std::vector<ReplaceableEntry*>( locations.begin(), locations.end()))); + // There is only one eviction for this replacement + evict_blks.push_back(victim); + DPRINTF(CacheRepl, "set %x, way %x: selecting blk for replacement\n", victim->set, victim->way); @@ -230,7 +236,7 @@ class BaseSetAssoc : public BaseTags * @param addr The addr to a find possible locations for. * @return The possible locations. */ - const std::vector<CacheBlk*> getPossibleLocations(Addr addr) + const std::vector<CacheBlk*> getPossibleLocations(Addr addr) const { return sets[extractSet(addr)].blks; } diff --git a/src/mem/cache/tags/fa_lru.cc b/src/mem/cache/tags/fa_lru.cc index a6e1b3be1..8eab62845 100644 --- a/src/mem/cache/tags/fa_lru.cc +++ b/src/mem/cache/tags/fa_lru.cc @@ -193,9 +193,15 @@ FALRU::findBlockBySetAndWay(int set, int way) const } CacheBlk* -FALRU::findVictim(Addr addr) +FALRU::findVictim(Addr addr, std::vector<CacheBlk*>& evict_blks) const { - return tail; + // The victim is always stored on the tail for the FALRU + FALRUBlk* victim = tail; + + // There is only one eviction for this replacement + evict_blks.push_back(victim); + + return victim; } void diff --git a/src/mem/cache/tags/fa_lru.hh b/src/mem/cache/tags/fa_lru.hh index 22b67c534..b134417b5 100644 --- a/src/mem/cache/tags/fa_lru.hh +++ b/src/mem/cache/tags/fa_lru.hh @@ -195,12 +195,15 @@ class FALRU : public BaseTags ReplaceableEntry* findBlockBySetAndWay(int set, int way) const override; /** - * Find replacement victim based on address. + * Find replacement victim based on address. The list of evicted blocks + * only contains the victim. * * @param addr Address to find a victim for. + * @param evict_blks Cache blocks to be evicted. * @return Cache block to be replaced. */ - CacheBlk* findVictim(Addr addr) override; + CacheBlk* findVictim(Addr addr, std::vector<CacheBlk*>& evict_blks) const + override; /** * Insert the new block into the cache and update replacement data. |