summaryrefslogtreecommitdiff
path: root/src/mem
diff options
context:
space:
mode:
authorNikos Nikoleris <nikos.nikoleris@arm.com>2019-11-26 12:59:03 +0000
committerNikos Nikoleris <nikos.nikoleris@arm.com>2020-01-06 11:09:21 +0000
commit44e3c95555b380f62c3fa4d878d78f26ad035475 (patch)
treedae42b1608eac6b602449493a410103901d99d65 /src/mem
parent6f864aaf4a472036e97c0ba28743f221811f1fc0 (diff)
downloadgem5-44e3c95555b380f62c3fa4d878d78f26ad035475.tar.xz
mem-cache: Avoid write merging if there are reads in between
This CL reworks the logic in the MSHR to make sure we do not coalesce requests unless there is a series of write requests for the whole cache block without any other incompatible requests (e.g., read) in between. Change-Id: I0b3195858fb33ef85d7aae27376506057dd53ea7 Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com> Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/23666 Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br> Tested-by: kokoro <noreply+kokoro@google.com>
Diffstat (limited to 'src/mem')
-rw-r--r--src/mem/cache/mshr.cc46
-rw-r--r--src/mem/cache/mshr.hh33
2 files changed, 47 insertions, 32 deletions
diff --git a/src/mem/cache/mshr.cc b/src/mem/cache/mshr.cc
index 4241fa375..1b21546aa 100644
--- a/src/mem/cache/mshr.cc
+++ b/src/mem/cache/mshr.cc
@@ -111,6 +111,52 @@ MSHR::TargetList::populateFlags()
}
}
+void
+MSHR::TargetList::updateWriteFlags(PacketPtr pkt)
+{
+ if (isWholeLineWrite()) {
+ // if we have already seen writes for the full block
+ // stop here, this might be a full line write followed
+ // by other compatible requests (e.g., reads)
+ return;
+ }
+
+ if (canMergeWrites) {
+ if (!pkt->isWrite()) {
+ // We won't allow further merging if this hasn't
+ // been a write
+ canMergeWrites = false;
+ return;
+ }
+
+ // Avoid merging requests with special flags (e.g.,
+ // strictly ordered)
+ const Request::FlagsType no_merge_flags =
+ Request::UNCACHEABLE | Request::STRICT_ORDER |
+ Request::MMAPPED_IPR | Request::PRIVILEGED |
+ Request::LLSC | Request::MEM_SWAP |
+ Request::MEM_SWAP_COND | Request::SECURE;
+ const auto &req_flags = pkt->req->getFlags();
+ bool compat_write = !req_flags.isSet(no_merge_flags);
+
+ // if this is the first write, it might be a whole
+ // line write and even if we can't merge any
+ // subsequent write requests, we still need to service
+ // it as a whole line write (e.g., SECURE whole line
+ // write)
+ bool first_write = empty();
+ if (first_write || compat_write) {
+ auto offset = pkt->getOffset(blkSize);
+ auto begin = writesBitmap.begin() + offset;
+ std::fill(begin, begin + pkt->getSize(), true);
+ }
+
+ // We won't allow further merging if this has been a
+ // special write
+ canMergeWrites &= compat_write;
+ }
+}
+
inline void
MSHR::TargetList::add(PacketPtr pkt, Tick readyTime,
Counter order, Target::Source source, bool markPending,
diff --git a/src/mem/cache/mshr.hh b/src/mem/cache/mshr.hh
index 40eb970c0..685064f39 100644
--- a/src/mem/cache/mshr.hh
+++ b/src/mem/cache/mshr.hh
@@ -227,38 +227,7 @@ class MSHR : public QueueEntry, public Printable
*
* @param pkt Packet considered for adding
*/
- void
- updateWriteFlags(PacketPtr pkt)
- {
- // if we have already seen writes for the full block stop
- // here, this might be a full line write followed by
- // other compatible requests (e.g., reads)
- if (!isWholeLineWrite()) {
- // Avoid merging requests with special flags (e.g.,
- // strictly ordered)
- const Request::FlagsType no_merge_flags =
- Request::UNCACHEABLE | Request::STRICT_ORDER |
- Request::MMAPPED_IPR | Request::PRIVILEGED |
- Request::LLSC | Request::MEM_SWAP |
- Request::MEM_SWAP_COND | Request::SECURE;
- const auto &req_flags = pkt->req->getFlags();
- bool compat_write = pkt->isWrite() &&
- !req_flags.isSet(no_merge_flags);
- canMergeWrites &= compat_write;
-
- // if this request is the first target in this list
- // and additionally a whole-line write, we need to
- // service it as a whole-line even if we won't allow
- // any further merging (e.g., SECURE whole line
- // write).
- bool first_write = pkt->isWrite() && (size() == 0);
- if (first_write || compat_write) {
- auto offset = pkt->getOffset(blkSize);
- auto begin = writesBitmap.begin() + offset;
- std::fill(begin, begin + pkt->getSize(), true);
- }
- }
- }
+ void updateWriteFlags(PacketPtr pkt);
/**
* Tests if the flags of this TargetList have their default