cpu: fix issues with ruby's memtest

If the size of the address range is smaller than the maximum number
of outstanding requests allowed downstream, the tester will get stuck
trying to find a unique address. This patch adds a check for this
condition and forces the tester to wait for responses before
trying to generate another request.

Change-Id: Ie894a074cc4f8c7ad3d875dc21e8eb4f04562d72
Signed-off-by: Tiago Mück <tiago.muck@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/56811
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Tiago Mück
2022-02-14 15:17:38 -06:00
committed by Tiago Muck
parent 48aa4692df
commit f5fc1006c3
2 changed files with 23 additions and 1 deletions

View File

@@ -88,6 +88,7 @@ MemTest::MemTest(const Params &p)
noResponseEvent([this]{ noResponse(); }, name()),
port("port", *this),
retryPkt(nullptr),
waitResponse(false),
size(p.size),
interval(p.interval),
percentReads(p.percent_reads),
@@ -96,6 +97,7 @@ MemTest::MemTest(const Params &p)
requestorId(p.system->getRequestorId(this)),
blockSize(p.system->cacheLineSize()),
blockAddrMask(blockSize - 1),
sizeBlocks(size / blockSize),
baseAddr1(p.base_addr_1),
baseAddr2(p.base_addr_2),
uncacheAddr(p.uncacheable_base_addr),
@@ -191,6 +193,12 @@ MemTest::completeRequest(PacketPtr pkt, bool functional)
reschedule(noResponseEvent, clockEdge(progressCheck));
else if (noResponseEvent.scheduled())
deschedule(noResponseEvent);
// schedule the next tick
if (waitResponse) {
waitResponse = false;
schedule(tickEvent, clockEdge(interval));
}
}
MemTest::MemTestStats::MemTestStats(statistics::Group *parent)
: statistics::Group(parent),
@@ -205,8 +213,9 @@ MemTest::MemTestStats::MemTestStats(statistics::Group *parent)
void
MemTest::tick()
{
// we should never tick if we are waiting for a retry
// we should never tick if we are waiting for a retry or response
assert(!retryPkt);
assert(!waitResponse);
// create a new request
unsigned cmd = random_mt.random(0, 100);
@@ -216,6 +225,13 @@ MemTest::tick()
Request::Flags flags;
Addr paddr;
// halt until we clear outstanding requests, otherwise it won't be able to
// find a new unique address
if (outstandingAddrs.size() >= sizeBlocks) {
waitResponse = true;
return;
}
// generate a unique address
do {
unsigned offset = random_mt.random<unsigned>(0, size - 1);

View File

@@ -120,6 +120,10 @@ class MemTest : public ClockedObject
PacketPtr retryPkt;
// Set if reached the maximum number of outstanding requests.
// Won't tick until a response is received.
bool waitResponse;
const unsigned size;
const Cycles interval;
@@ -142,6 +146,8 @@ class MemTest : public ClockedObject
const Addr blockAddrMask;
const unsigned sizeBlocks;
/**
* Get the block aligned address.
*