Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change for split requests #257

Open
wants to merge 5 commits into
base: jason/dynamorio-traces
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 87 additions & 12 deletions src/cpu/testers/dr_trace_player/trace_player.cc
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,6 @@ DRTracePlayer::executeMemInst(DRTraceReader::TraceRef &mem_ref)
}

if (!trySendMemRef(mem_ref)) {
numOutstandingMemReqs++;
stats.outstandingMemReqs.sample(numOutstandingMemReqs);
stats.numMemInsts++;
return false;
} else {
Expand All @@ -167,24 +165,73 @@ DRTracePlayer::executeMemInst(DRTraceReader::TraceRef &mem_ref)
bool
DRTracePlayer::trySendMemRef(DRTraceReader::TraceRef &mem_ref)
{
PacketPtr pkt = getPacket(mem_ref);
// split_pkt will be nullptr if not a split req
auto [pkt, split_pkt] = getPacket(mem_ref);

// ensure that currently we are not in process of
// retrying to send the second part of a previously
// stalled request to avoid duplicate first pkt in
// the memory system.
// Also, the assumption is that we cannot start a
// new memory request in parallel.
Comment on lines +175 to +176
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how to interpret this statement. Otherwise, it looks good.

if (!retrySplitPkt) {
DPRINTF(DRTrace, "Trying to send %s\n", pkt->print());

if (!port.sendTimingReq(pkt)) {
DPRINTF(DRTrace, "Failed to send pkt\n");
if (stats.memStallStart == 0) {
stats.memStallStart = curTick();
}
delete pkt;
delete split_pkt;

// return true if we have to stall on the first pkt
// irrespective of if this is a split req
return true;
powerjg marked this conversation as resolved.
Show resolved Hide resolved
} else {
numOutstandingMemReqs++;
stats.outstandingMemReqs.sample(numOutstandingMemReqs);
stats.latencyTracker[pkt] = curTick();
if (split_pkt == nullptr) {
// if this is not a split req, we can
// return here
return false;
}
}
} else {
// we should delete the first pkt here
// if we are only trying to resend the
// second pkt
delete pkt;
}
powerjg marked this conversation as resolved.
Show resolved Hide resolved

DPRINTF(DRTrace, "Trying to send %s\n", pkt->print());
DPRINTF(DRTrace, "Trying to send split %s\n", split_pkt->print());
powerjg marked this conversation as resolved.
Show resolved Hide resolved

if (!port.sendTimingReq(pkt)) {
DPRINTF(DRTrace, "Failed to send pkt\n");
// if the first pkt is sent out, and the current
// request is a split request, try to send out
// the second pkt
if (!port.sendTimingReq(split_pkt)) {
DPRINTF(DRTrace, "Failed to send pkt (split pkt) \n");
if (stats.memStallStart == 0) {
stats.memStallStart = curTick();
}
delete pkt;
delete split_pkt;
// also remember that we only need to retry on second part of
// the split pkt
retrySplitPkt = true;
powerjg marked this conversation as resolved.
Show resolved Hide resolved
return true;
} else {
stats.latencyTracker[pkt] = curTick();
numOutstandingMemReqs++;
stats.outstandingMemReqs.sample(numOutstandingMemReqs);
stats.latencyTracker[split_pkt] = curTick();
retrySplitPkt = false;
// At this point, we are sure that both pkts of the split req
// are received by the port
return false;
}
}

PacketPtr
std::tuple<PacketPtr, PacketPtr>
DRTracePlayer::getPacket(DRTraceReader::TraceRef &mem_ref)
{
Request::Flags flags = Request::PHYSICAL;
Expand All @@ -198,11 +245,13 @@ DRTracePlayer::getPacket(DRTraceReader::TraceRef &mem_ref)
addr %= compressAddressRange.size();
}

bool split_req = false;
unsigned size = mem_ref.size;
Addr split_addr = roundDown(addr + size - 1, cacheLineSize);
if (split_addr > addr) {
warn("Ignoring split packet that crosses cache line boundary.");
DPRINTF(DRTrace, "Split pkt (crosses cache line boundary) created\n");
size = split_addr - addr;
split_req = true;
}

// Create new request
Expand Down Expand Up @@ -230,9 +279,35 @@ DRTracePlayer::getPacket(DRTraceReader::TraceRef &mem_ref)
}
}

return pkt;
}
PacketPtr split_pkt = nullptr;

// In case of split packets when we want to send two requests.
// For the second request, the starting address
// will be split_addr and the size will be cacheLineSize - size

if (split_req) {

// Create the split request
RequestPtr split_req = std::make_shared<Request>(split_addr,
cacheLineSize - size, flags, requestorId);
split_req->setPC(curPC);

// Embed it in a packet
split_pkt = new Packet(split_req, cmd);

if (params().send_data) {
uint8_t* split_pkt_data = new uint8_t[split_req->getSize()];
split_pkt->dataDynamic(split_pkt_data);

if (cmd.isWrite()) {
std::fill_n(split_pkt_data, split_req->getSize(),
(uint8_t)requestorId);
}
}
}

return {pkt, split_pkt};
}

Port &
DRTracePlayer::getPort(const std::string &if_name, PortID idx)
Expand Down
6 changes: 5 additions & 1 deletion src/cpu/testers/dr_trace_player/trace_player.hh
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ class DRTracePlayer : public ClockedObject
AddrRange compressAddressRange;
int cacheLineSize;

// variable to keep track of retries for split pkts
bool retrySplitPkt = false;

// State
bool stalled = false;
Addr curPC = 0;
Expand Down Expand Up @@ -129,7 +132,8 @@ class DRTracePlayer : public ClockedObject

bool recvTimingResp(PacketPtr pkt);

PacketPtr getPacket(DRTraceReader::TraceRef &mem_ref);
std::tuple<PacketPtr, PacketPtr>
getPacket(DRTraceReader::TraceRef &mem_ref);

/**
* @brief Send a request to memory based on the trace
Expand Down