diff options
author | Nikos Nikoleris <nikos.nikoleris@arm.com> | 2018-03-12 10:11:16 +0000 |
---|---|---|
committer | Gabe Black <gabeblack@google.com> | 2018-03-21 22:28:26 +0000 |
commit | 0473286ab1e9992a906eff380000bf90c82eeccb (patch) | |
tree | d750bca0b96da2ab66c788ae3495dbe2f90f2cf3 /src/mem/cache/cache.cc | |
parent | 68af229490fc811aebddf68b3e2e09e63a5fa475 (diff) | |
download | gem5-0473286ab1e9992a906eff380000bf90c82eeccb.tar.xz |
mem-cache: Allow clean operations when block allocation fails
Block allocation can fail when there is an in-service MSHR that
operates on the victim block. This can happed due to:
* an upgrade operation: a request that needs a writable copy of the
block finds a shared (non-writable) copy of the block in the cache
and has allocates an MSHR for the pending upgrade operation, or
* a clean operation: a clean request finds a dirty copy of the block
and allocates an MSHR for the pending clean operation.
This changes relaxes an assertion to allow for the 2nd case (cache
clean operations).
Change-Id: Ib51482160b5f2b3702ed744b0eac2029d34bc9d4
Reviewed-by: Curtis Dunham <curtis.dunham@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/9021
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Maintainer: Gabe Black <gabeblack@google.com>
Diffstat (limited to 'src/mem/cache/cache.cc')
-rw-r--r-- | src/mem/cache/cache.cc | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/src/mem/cache/cache.cc b/src/mem/cache/cache.cc index 85c96772c..9ee935961 100644 --- a/src/mem/cache/cache.cc +++ b/src/mem/cache/cache.cc @@ -1826,10 +1826,10 @@ Cache::allocateBlock(Addr addr, bool is_secure, PacketList &writebacks) Addr repl_addr = tags->regenerateBlkAddr(blk); MSHR *repl_mshr = mshrQueue.findMatch(repl_addr, blk->isSecure()); if (repl_mshr) { - // must be an outstanding upgrade request + // must be an outstanding upgrade or clean request // on a block we're about to replace... - assert(!blk->isWritable() || blk->isDirty()); - assert(repl_mshr->needsWritable()); + assert((!blk->isWritable() && repl_mshr->needsWritable()) || + repl_mshr->isCleaning()); // too hard to replace block with transient state // allocation failed, block not inserted return nullptr; |