Daniel Carvalho has submitted this change and it was merged. (
https://gem5-review.googlesource.com/c/public/gem5/+/17530 )
Change subject: mem-cache: Add match functions to QueueEntry
......................................................................
mem-cache: Add match functions to QueueEntry
Having the caller decide the matching logic is error-prone, and
frequently ends up with the secure bit being forgotten. This
change adds matching functions to the QueueEntry to avoid this
problem.
As a side effect the signature of findPending has been changed.
Change-Id: I6e494a821c1e6e841ab103ec69632c0e1b269a08
Signed-off-by: Daniel R. Carvalho <[email protected]>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/17530
Tested-by: kokoro <[email protected]>
Reviewed-by: Nikos Nikoleris <[email protected]>
Maintainer: Nikos Nikoleris <[email protected]>
---
M src/mem/cache/base.cc
M src/mem/cache/mshr.cc
M src/mem/cache/mshr.hh
M src/mem/cache/queue.hh
M src/mem/cache/queue_entry.hh
M src/mem/cache/write_queue_entry.cc
M src/mem/cache/write_queue_entry.hh
7 files changed, 100 insertions(+), 19 deletions(-)
Approvals:
Nikos Nikoleris: Looks good to me, approved; Looks good to me, approved
kokoro: Statistics mismatch
diff --git a/src/mem/cache/base.cc b/src/mem/cache/base.cc
index ddcfd80..2a6bc2a 100644
--- a/src/mem/cache/base.cc
+++ b/src/mem/cache/base.cc
@@ -729,9 +729,7 @@
// full write buffer, otherwise we favour the miss requests
if (wq_entry && (writeBuffer.isFull() || !miss_mshr)) {
// need to search MSHR queue for conflicting earlier miss.
- MSHR *conflict_mshr =
- mshrQueue.findPending(wq_entry->blkAddr,
- wq_entry->isSecure);
+ MSHR *conflict_mshr = mshrQueue.findPending(wq_entry);
if (conflict_mshr && conflict_mshr->order < wq_entry->order) {
// Service misses in order until conflict is cleared.
@@ -744,9 +742,7 @@
return wq_entry;
} else if (miss_mshr) {
// need to check for conflicting earlier writeback
- WriteQueueEntry *conflict_mshr =
- writeBuffer.findPending(miss_mshr->blkAddr,
- miss_mshr->isSecure);
+ WriteQueueEntry *conflict_mshr =
writeBuffer.findPending(miss_mshr);
if (conflict_mshr) {
// not sure why we don't check order here... it was in the
// original code but commented out.
diff --git a/src/mem/cache/mshr.cc b/src/mem/cache/mshr.cc
index 8db7c29..13a5016 100644
--- a/src/mem/cache/mshr.cc
+++ b/src/mem/cache/mshr.cc
@@ -273,6 +273,9 @@
Target::Source source = (target->cmd == MemCmd::HardPFReq) ?
Target::FromPrefetcher : Target::FromCPU;
targets.add(target, when_ready, _order, source, true, alloc_on_fill);
+
+ // All targets must refer to the same block
+ assert(target->matchBlockAddr(targets.front().pkt, blkSize));
}
@@ -685,3 +688,24 @@
print(str);
return str.str();
}
+
+bool
+MSHR::matchBlockAddr(const Addr addr, const bool is_secure) const
+{
+ assert(hasTargets());
+ return (blkAddr == addr) && (isSecure == is_secure);
+}
+
+bool
+MSHR::matchBlockAddr(const PacketPtr pkt) const
+{
+ assert(hasTargets());
+ return pkt->matchBlockAddr(blkAddr, isSecure, blkSize);
+}
+
+bool
+MSHR::conflictAddr(const QueueEntry* entry) const
+{
+ assert(hasTargets());
+ return entry->matchBlockAddr(blkAddr, isSecure);
+}
diff --git a/src/mem/cache/mshr.hh b/src/mem/cache/mshr.hh
index e9505eb..4b05489 100644
--- a/src/mem/cache/mshr.hh
+++ b/src/mem/cache/mshr.hh
@@ -531,6 +531,10 @@
* @return string with mshr fields + [deferred]targets
*/
std::string print() const;
+
+ bool matchBlockAddr(const Addr addr, const bool is_secure) const
override;
+ bool matchBlockAddr(const PacketPtr pkt) const override;
+ bool conflictAddr(const QueueEntry* entry) const override;
};
#endif // __MEM_CACHE_MSHR_HH__
diff --git a/src/mem/cache/queue.hh b/src/mem/cache/queue.hh
index 6c8a192..30fe4ba 100644
--- a/src/mem/cache/queue.hh
+++ b/src/mem/cache/queue.hh
@@ -174,7 +174,7 @@
// cacheable accesses being added to an WriteQueueEntry
// serving an uncacheable access
if (!(ignore_uncacheable && entry->isUncacheable()) &&
- entry->blkAddr == blk_addr && entry->isSecure ==
is_secure) {
+ entry->matchBlockAddr(blk_addr, is_secure)) {
return entry;
}
}
@@ -185,7 +185,8 @@
{
pkt->pushLabel(label);
for (const auto& entry : allocatedList) {
- if (entry->blkAddr == blk_addr &&
entry->trySatisfyFunctional(pkt)) {
+ if (entry->matchBlockAddr(blk_addr, pkt->isSecure()) &&
+ entry->trySatisfyFunctional(pkt)) {
pkt->popLabel();
return true;
}
@@ -195,16 +196,17 @@
}
/**
- * Find any pending requests that overlap the given request.
- * @param blk_addr Block address.
- * @param is_secure True if the target memory space is secure.
- * @return A pointer to the earliest matching WriteQueueEntry.
+ * Find any pending requests that overlap the given request of a
+ * different queue.
+ *
+ * @param entry The entry to be compared against.
+ * @return A pointer to the earliest matching entry.
*/
- Entry* findPending(Addr blk_addr, bool is_secure) const
+ Entry* findPending(const QueueEntry* entry) const
{
- for (const auto& entry : readyList) {
- if (entry->blkAddr == blk_addr && entry->isSecure ==
is_secure) {
- return entry;
+ for (const auto& ready_entry : readyList) {
+ if (ready_entry->conflictAddr(entry)) {
+ return ready_entry;
}
}
return nullptr;
diff --git a/src/mem/cache/queue_entry.hh b/src/mem/cache/queue_entry.hh
index 39ee0a0..61c898d 100644
--- a/src/mem/cache/queue_entry.hh
+++ b/src/mem/cache/queue_entry.hh
@@ -119,14 +119,41 @@
/** True if the entry targets the secure memory space. */
bool isSecure;
- QueueEntry() : readyTime(0), _isUncacheable(false),
- inService(false), order(0), blkAddr(0), blkSize(0),
- isSecure(false)
+ QueueEntry()
+ : readyTime(0), _isUncacheable(false),
+ inService(false), order(0), blkAddr(0), blkSize(0),
isSecure(false)
{}
bool isUncacheable() const { return _isUncacheable; }
/**
+ * Check if entry corresponds to the one being looked for.
+ *
+ * @param addr Address to match against.
+ * @param is_secure Whether the target should be in secure space or
not.
+ * @return True if entry matches given information.
+ */
+ virtual bool matchBlockAddr(const Addr addr, const bool is_secure)
+ const = 0;
+
+ /**
+ * Check if entry contains a packet that corresponds to the one being
+ * looked for.
+ *
+ * @param pkt The packet to search for.
+ * @return True if any of its targets' packets matches the given one.
+ */
+ virtual bool matchBlockAddr(const PacketPtr pkt) const = 0;
+
+ /**
+ * Check if given entry's packets conflict with this' entries packets.
+ *
+ * @param entry Other entry to compare against.
+ * @return True if entry matches given information.
+ */
+ virtual bool conflictAddr(const QueueEntry* entry) const = 0;
+
+ /**
* Send this queue entry as a downstream packet, with the exact
* behaviour depending on the specific entry type.
*/
diff --git a/src/mem/cache/write_queue_entry.cc
b/src/mem/cache/write_queue_entry.cc
index 6c8387b..f3106e4 100644
--- a/src/mem/cache/write_queue_entry.cc
+++ b/src/mem/cache/write_queue_entry.cc
@@ -112,6 +112,9 @@
"a cacheable eviction or a writeclean");
targets.add(target, when_ready, _order);
+
+ // All targets must refer to the same block
+ assert(target->matchBlockAddr(targets.front().pkt, blkSize));
}
void
@@ -141,6 +144,27 @@
return cache.sendWriteQueuePacket(this);
}
+bool
+WriteQueueEntry::matchBlockAddr(const Addr addr, const bool is_secure)
const
+{
+ assert(hasTargets());
+ return (blkAddr == addr) && (isSecure == is_secure);
+}
+
+bool
+WriteQueueEntry::matchBlockAddr(const PacketPtr pkt) const
+{
+ assert(hasTargets());
+ return pkt->matchBlockAddr(blkAddr, isSecure, blkSize);
+}
+
+bool
+WriteQueueEntry::conflictAddr(const QueueEntry* entry) const
+{
+ assert(hasTargets());
+ return entry->matchBlockAddr(blkAddr, isSecure);
+}
+
void
WriteQueueEntry::print(std::ostream &os, int verbosity,
const std::string &prefix) const
diff --git a/src/mem/cache/write_queue_entry.hh
b/src/mem/cache/write_queue_entry.hh
index 59714d9..9aaac49 100644
--- a/src/mem/cache/write_queue_entry.hh
+++ b/src/mem/cache/write_queue_entry.hh
@@ -179,6 +179,10 @@
* @return string with mshr fields
*/
std::string print() const;
+
+ bool matchBlockAddr(const Addr addr, const bool is_secure) const
override;
+ bool matchBlockAddr(const PacketPtr pkt) const override;
+ bool conflictAddr(const QueueEntry* entry) const override;
};
#endif // __MEM_CACHE_WRITE_QUEUE_ENTRY_HH__
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/17530
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-Change-Id: I6e494a821c1e6e841ab103ec69632c0e1b269a08
Gerrit-Change-Number: 17530
Gerrit-PatchSet: 6
Gerrit-Owner: Daniel Carvalho <[email protected]>
Gerrit-Reviewer: Daniel Carvalho <[email protected]>
Gerrit-Reviewer: Nikos Nikoleris <[email protected]>
Gerrit-Reviewer: kokoro <[email protected]>
Gerrit-MessageType: merged
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev