summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Hestness <jthestness@gmail.com>2013-04-09 16:25:30 -0500
committerJoel Hestness <jthestness@gmail.com>2013-04-09 16:25:30 -0500
commit1583056de8d5d9698cfeb87fb72a80e532e275c3 (patch)
tree0c20a636a5a3b030cbf89ee14919bc126e1411af
parent46d4b71aa244da24453d86184f3cf2ba8b5bdbac (diff)
downloadgem5-1583056de8d5d9698cfeb87fb72a80e532e275c3.tar.xz
Ruby: Fix RubyPort evict packet memory leak
When using the o3 or inorder CPUs with many Ruby protocols, the caches may need to forward invalidations to the CPUs. The RubyPort was instantiating a packet to be sent to the CPUs to signal the eviction, but the packets were not being freed by the CPUs. Consistent with the classic memory model, stack allocate the packet and heap allocate the request so on ruby_eviction_callback() completion, the packet deconstructor is called, and deletes the request (*Note: stack allocating the request causes double deletion, since it will be deleted in the packet destructor). This results in the least memory allocations without memory errors.
-rw-r--r--src/mem/ruby/system/RubyPort.cc13
1 files changed, 9 insertions, 4 deletions
diff --git a/src/mem/ruby/system/RubyPort.cc b/src/mem/ruby/system/RubyPort.cc
index 4cfc1f252..1ebc1b0f6 100644
--- a/src/mem/ruby/system/RubyPort.cc
+++ b/src/mem/ruby/system/RubyPort.cc
@@ -496,14 +496,19 @@ void
RubyPort::ruby_eviction_callback(const Address& address)
{
DPRINTF(RubyPort, "Sending invalidations.\n");
- // should this really be using funcMasterId?
- Request req(address.getAddress(), 0, 0, Request::funcMasterId);
+ // This request is deleted in the stack-allocated packet destructor
+ // when this function exits
+ // TODO: should this really be using funcMasterId?
+ RequestPtr req =
+ new Request(address.getAddress(), 0, 0, Request::funcMasterId);
+ // Use a single packet to signal all snooping ports of the invalidation.
+ // This assumes that snooping ports do NOT modify the packet/request
+ Packet pkt(req, MemCmd::InvalidationReq);
for (CpuPortIter p = slave_ports.begin(); p != slave_ports.end(); ++p) {
// check if the connected master port is snooping
if ((*p)->isSnooping()) {
- Packet *pkt = new Packet(&req, MemCmd::InvalidationReq);
// send as a snoop request
- (*p)->sendTimingSnoopReq(pkt);
+ (*p)->sendTimingSnoopReq(&pkt);
}
}
}