summaryrefslogtreecommitdiff
path: root/src/cpu
diff options
context:
space:
mode:
authorAndreas Hansson <andreas.hansson@arm.com>2015-03-02 04:00:35 -0500
committerAndreas Hansson <andreas.hansson@arm.com>2015-03-02 04:00:35 -0500
commitf26a28929583f2ed7fb55521e49c3f9bef557c05 (patch)
treee5d71fc69566b02a394015776b0f3f4e3be81427 /src/cpu
parent6ebe8d863ae0c5a7799e9421da32593ac35e1cc7 (diff)
downloadgem5-f26a28929583f2ed7fb55521e49c3f9bef557c05.tar.xz
mem: Split port retry for all different packet classes
This patch fixes a long-standing isue with the port flow control. Before this patch the retry mechanism was shared between all different packet classes. As a result, a snoop response could get stuck behind a request waiting for a retry, even if the send/recv functions were split. This caused message-dependent deadlocks in stress-test scenarios. The patch splits the retry into one per packet (message) class. Thus, sendTimingReq has a corresponding recvReqRetry, sendTimingResp has recvRespRetry etc. Most of the changes to the code involve simply clarifying what type of request a specific object was accepting. The biggest change in functionality is in the cache downstream packet queue, facing the memory. This queue was shared by requests and snoop responses, and it is now split into two queues, each with their own flow control, but the same physical MasterPort. These changes fixes the previously seen deadlocks.
Diffstat (limited to 'src/cpu')
-rw-r--r--src/cpu/kvm/base.hh4
-rw-r--r--src/cpu/minor/fetch1.cc2
-rw-r--r--src/cpu/minor/fetch1.hh4
-rw-r--r--src/cpu/minor/lsq.cc2
-rw-r--r--src/cpu/minor/lsq.hh4
-rw-r--r--src/cpu/o3/cpu.cc8
-rw-r--r--src/cpu/o3/cpu.hh4
-rw-r--r--src/cpu/o3/fetch.hh2
-rw-r--r--src/cpu/o3/fetch_impl.hh2
-rw-r--r--src/cpu/o3/lsq.hh2
-rw-r--r--src/cpu/o3/lsq_impl.hh2
-rw-r--r--src/cpu/simple/atomic.hh2
-rw-r--r--src/cpu/simple/timing.cc8
-rw-r--r--src/cpu/simple/timing.hh8
-rw-r--r--src/cpu/testers/directedtest/RubyDirectedTester.hh2
-rw-r--r--src/cpu/testers/memtest/memtest.cc2
-rw-r--r--src/cpu/testers/memtest/memtest.hh2
-rw-r--r--src/cpu/testers/networktest/networktest.cc2
-rw-r--r--src/cpu/testers/networktest/networktest.hh2
-rw-r--r--src/cpu/testers/rubytest/RubyTester.hh2
-rw-r--r--src/cpu/testers/traffic_gen/traffic_gen.cc2
-rw-r--r--src/cpu/testers/traffic_gen/traffic_gen.hh4
22 files changed, 36 insertions, 36 deletions
diff --git a/src/cpu/kvm/base.hh b/src/cpu/kvm/base.hh
index dac4934cb..ce32cdbb1 100644
--- a/src/cpu/kvm/base.hh
+++ b/src/cpu/kvm/base.hh
@@ -561,9 +561,9 @@ class BaseKvmCPU : public BaseCPU
return true;
}
- void recvRetry()
+ void recvReqRetry()
{
- panic("The KVM CPU doesn't expect recvRetry!\n");
+ panic("The KVM CPU doesn't expect recvReqRetry!\n");
}
};
diff --git a/src/cpu/minor/fetch1.cc b/src/cpu/minor/fetch1.cc
index 79a5d0a78..567bd2ecc 100644
--- a/src/cpu/minor/fetch1.cc
+++ b/src/cpu/minor/fetch1.cc
@@ -417,7 +417,7 @@ Fetch1::recvTimingResp(PacketPtr response)
}
void
-Fetch1::recvRetry()
+Fetch1::recvReqRetry()
{
DPRINTF(Fetch, "recvRetry\n");
assert(icacheState == IcacheNeedsRetry);
diff --git a/src/cpu/minor/fetch1.hh b/src/cpu/minor/fetch1.hh
index 29e10def5..d4a35c468 100644
--- a/src/cpu/minor/fetch1.hh
+++ b/src/cpu/minor/fetch1.hh
@@ -77,7 +77,7 @@ class Fetch1 : public Named
bool recvTimingResp(PacketPtr pkt)
{ return fetch.recvTimingResp(pkt); }
- void recvRetry() { fetch.recvRetry(); }
+ void recvReqRetry() { fetch.recvReqRetry(); }
};
/** Memory access queuing.
@@ -345,7 +345,7 @@ class Fetch1 : public Named
/** Memory interface */
virtual bool recvTimingResp(PacketPtr pkt);
- virtual void recvRetry();
+ virtual void recvReqRetry();
public:
Fetch1(const std::string &name_,
diff --git a/src/cpu/minor/lsq.cc b/src/cpu/minor/lsq.cc
index 72873211b..06b6c5165 100644
--- a/src/cpu/minor/lsq.cc
+++ b/src/cpu/minor/lsq.cc
@@ -1235,7 +1235,7 @@ LSQ::recvTimingResp(PacketPtr response)
}
void
-LSQ::recvRetry()
+LSQ::recvReqRetry()
{
DPRINTF(MinorMem, "Received retry request\n");
diff --git a/src/cpu/minor/lsq.hh b/src/cpu/minor/lsq.hh
index 7936ae8f0..8a7d78216 100644
--- a/src/cpu/minor/lsq.hh
+++ b/src/cpu/minor/lsq.hh
@@ -101,7 +101,7 @@ class LSQ : public Named
bool recvTimingResp(PacketPtr pkt)
{ return lsq.recvTimingResp(pkt); }
- void recvRetry() { lsq.recvRetry(); }
+ void recvReqRetry() { lsq.recvReqRetry(); }
void recvTimingSnoopReq(PacketPtr pkt)
{ return lsq.recvTimingSnoopReq(pkt); }
@@ -712,7 +712,7 @@ class LSQ : public Named
/** Memory interface */
bool recvTimingResp(PacketPtr pkt);
- void recvRetry();
+ void recvReqRetry();
void recvTimingSnoopReq(PacketPtr pkt);
/** Return the raw-bindable port */
diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc
index 434bfd7da..fc7643be2 100644
--- a/src/cpu/o3/cpu.cc
+++ b/src/cpu/o3/cpu.cc
@@ -101,9 +101,9 @@ FullO3CPU<Impl>::IcachePort::recvTimingResp(PacketPtr pkt)
template<class Impl>
void
-FullO3CPU<Impl>::IcachePort::recvRetry()
+FullO3CPU<Impl>::IcachePort::recvReqRetry()
{
- fetch->recvRetry();
+ fetch->recvReqRetry();
}
template <class Impl>
@@ -126,9 +126,9 @@ FullO3CPU<Impl>::DcachePort::recvTimingSnoopReq(PacketPtr pkt)
template <class Impl>
void
-FullO3CPU<Impl>::DcachePort::recvRetry()
+FullO3CPU<Impl>::DcachePort::recvReqRetry()
{
- lsq->recvRetry();
+ lsq->recvReqRetry();
}
template <class Impl>
diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh
index 5b33285c4..c4ccd562b 100644
--- a/src/cpu/o3/cpu.hh
+++ b/src/cpu/o3/cpu.hh
@@ -150,7 +150,7 @@ class FullO3CPU : public BaseO3CPU
virtual void recvTimingSnoopReq(PacketPtr pkt) { }
/** Handles doing a retry of a failed fetch. */
- virtual void recvRetry();
+ virtual void recvReqRetry();
};
/**
@@ -185,7 +185,7 @@ class FullO3CPU : public BaseO3CPU
}
/** Handles doing a retry of the previous send. */
- virtual void recvRetry();
+ virtual void recvReqRetry();
/**
* As this CPU requires snooping to maintain the load store queue
diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh
index 968d94029..536568bc2 100644
--- a/src/cpu/o3/fetch.hh
+++ b/src/cpu/o3/fetch.hh
@@ -224,7 +224,7 @@ class DefaultFetch
void startupStage();
/** Handles retrying the fetch access. */
- void recvRetry();
+ void recvReqRetry();
/** Processes cache completion event. */
void processCacheCompletion(PacketPtr pkt);
diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh
index d3b0b3ac5..a462d9251 100644
--- a/src/cpu/o3/fetch_impl.hh
+++ b/src/cpu/o3/fetch_impl.hh
@@ -1407,7 +1407,7 @@ DefaultFetch<Impl>::fetch(bool &status_change)
template<class Impl>
void
-DefaultFetch<Impl>::recvRetry()
+DefaultFetch<Impl>::recvReqRetry()
{
if (retryPkt != NULL) {
assert(cacheBlocked);
diff --git a/src/cpu/o3/lsq.hh b/src/cpu/o3/lsq.hh
index 5d57bb52b..d726088ef 100644
--- a/src/cpu/o3/lsq.hh
+++ b/src/cpu/o3/lsq.hh
@@ -286,7 +286,7 @@ class LSQ {
/**
* Retry the previous send that failed.
*/
- void recvRetry();
+ void recvReqRetry();
/**
* Handles writing back and completing the load or store that has
diff --git a/src/cpu/o3/lsq_impl.hh b/src/cpu/o3/lsq_impl.hh
index e0107e36a..06467243d 100644
--- a/src/cpu/o3/lsq_impl.hh
+++ b/src/cpu/o3/lsq_impl.hh
@@ -330,7 +330,7 @@ LSQ<Impl>::violation()
template <class Impl>
void
-LSQ<Impl>::recvRetry()
+LSQ<Impl>::recvReqRetry()
{
iewStage->cacheUnblocked();
diff --git a/src/cpu/simple/atomic.hh b/src/cpu/simple/atomic.hh
index a2f3927b4..5ad5c4305 100644
--- a/src/cpu/simple/atomic.hh
+++ b/src/cpu/simple/atomic.hh
@@ -139,7 +139,7 @@ class AtomicSimpleCPU : public BaseSimpleCPU
return true;
}
- void recvRetry()
+ void recvReqRetry()
{
panic("Atomic CPU doesn't expect recvRetry!\n");
}
diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc
index 9171395b0..8b95696a3 100644
--- a/src/cpu/simple/timing.cc
+++ b/src/cpu/simple/timing.cc
@@ -729,7 +729,7 @@ TimingSimpleCPU::IcachePort::recvTimingResp(PacketPtr pkt)
}
void
-TimingSimpleCPU::IcachePort::recvRetry()
+TimingSimpleCPU::IcachePort::recvReqRetry()
{
// we shouldn't get a retry unless we have a packet that we're
// waiting to transmit
@@ -846,8 +846,8 @@ TimingSimpleCPU::DcachePort::recvTimingResp(PacketPtr pkt)
// In the case of a split transaction and a cache that is
// faster than a CPU we could get two responses in the
// same tick, delay the second one
- if (!retryEvent.scheduled())
- cpu->schedule(retryEvent, cpu->clockEdge(Cycles(1)));
+ if (!retryRespEvent.scheduled())
+ cpu->schedule(retryRespEvent, cpu->clockEdge(Cycles(1)));
return false;
}
}
@@ -859,7 +859,7 @@ TimingSimpleCPU::DcachePort::DTickEvent::process()
}
void
-TimingSimpleCPU::DcachePort::recvRetry()
+TimingSimpleCPU::DcachePort::recvReqRetry()
{
// we shouldn't get a retry unless we have a packet that we're
// waiting to transmit
diff --git a/src/cpu/simple/timing.hh b/src/cpu/simple/timing.hh
index d8460515b..3ce596fc7 100644
--- a/src/cpu/simple/timing.hh
+++ b/src/cpu/simple/timing.hh
@@ -157,7 +157,7 @@ class TimingSimpleCPU : public BaseSimpleCPU
public:
TimingCPUPort(const std::string& _name, TimingSimpleCPU* _cpu)
- : MasterPort(_name, _cpu), cpu(_cpu), retryEvent(this)
+ : MasterPort(_name, _cpu), cpu(_cpu), retryRespEvent(this)
{ }
protected:
@@ -179,7 +179,7 @@ class TimingSimpleCPU : public BaseSimpleCPU
void schedule(PacketPtr _pkt, Tick t);
};
- EventWrapper<MasterPort, &MasterPort::sendRetry> retryEvent;
+ EventWrapper<MasterPort, &MasterPort::sendRetryResp> retryRespEvent;
};
class IcachePort : public TimingCPUPort
@@ -195,7 +195,7 @@ class TimingSimpleCPU : public BaseSimpleCPU
virtual bool recvTimingResp(PacketPtr pkt);
- virtual void recvRetry();
+ virtual void recvReqRetry();
struct ITickEvent : public TickEvent
{
@@ -232,7 +232,7 @@ class TimingSimpleCPU : public BaseSimpleCPU
virtual bool recvTimingResp(PacketPtr pkt);
- virtual void recvRetry();
+ virtual void recvReqRetry();
virtual bool isSnooping() const {
return true;
diff --git a/src/cpu/testers/directedtest/RubyDirectedTester.hh b/src/cpu/testers/directedtest/RubyDirectedTester.hh
index cb58fa63f..0e3b1002a 100644
--- a/src/cpu/testers/directedtest/RubyDirectedTester.hh
+++ b/src/cpu/testers/directedtest/RubyDirectedTester.hh
@@ -60,7 +60,7 @@ class RubyDirectedTester : public MemObject
protected:
virtual bool recvTimingResp(PacketPtr pkt);
- virtual void recvRetry()
+ virtual void recvReqRetry()
{ panic("%s does not expect a retry\n", name()); }
};
diff --git a/src/cpu/testers/memtest/memtest.cc b/src/cpu/testers/memtest/memtest.cc
index 1d2554852..b0dde6d27 100644
--- a/src/cpu/testers/memtest/memtest.cc
+++ b/src/cpu/testers/memtest/memtest.cc
@@ -63,7 +63,7 @@ MemTest::CpuPort::recvTimingResp(PacketPtr pkt)
}
void
-MemTest::CpuPort::recvRetry()
+MemTest::CpuPort::recvReqRetry()
{
memtest.recvRetry();
}
diff --git a/src/cpu/testers/memtest/memtest.hh b/src/cpu/testers/memtest/memtest.hh
index 0648f8c11..daed5e5d2 100644
--- a/src/cpu/testers/memtest/memtest.hh
+++ b/src/cpu/testers/memtest/memtest.hh
@@ -114,7 +114,7 @@ class MemTest : public MemObject
Tick recvAtomicSnoop(PacketPtr pkt) { return 0; }
- void recvRetry();
+ void recvReqRetry();
};
CpuPort port;
diff --git a/src/cpu/testers/networktest/networktest.cc b/src/cpu/testers/networktest/networktest.cc
index 4a79d5a17..e3103f6b6 100644
--- a/src/cpu/testers/networktest/networktest.cc
+++ b/src/cpu/testers/networktest/networktest.cc
@@ -59,7 +59,7 @@ NetworkTest::CpuPort::recvTimingResp(PacketPtr pkt)
}
void
-NetworkTest::CpuPort::recvRetry()
+NetworkTest::CpuPort::recvReqRetry()
{
networktest->doRetry();
}
diff --git a/src/cpu/testers/networktest/networktest.hh b/src/cpu/testers/networktest/networktest.hh
index 253b48233..572097a09 100644
--- a/src/cpu/testers/networktest/networktest.hh
+++ b/src/cpu/testers/networktest/networktest.hh
@@ -91,7 +91,7 @@ class NetworkTest : public MemObject
virtual bool recvTimingResp(PacketPtr pkt);
- virtual void recvRetry();
+ virtual void recvReqRetry();
};
CpuPort cachePort;
diff --git a/src/cpu/testers/rubytest/RubyTester.hh b/src/cpu/testers/rubytest/RubyTester.hh
index e1b829a7d..c0ad554c6 100644
--- a/src/cpu/testers/rubytest/RubyTester.hh
+++ b/src/cpu/testers/rubytest/RubyTester.hh
@@ -75,7 +75,7 @@ class RubyTester : public MemObject
protected:
virtual bool recvTimingResp(PacketPtr pkt);
- virtual void recvRetry()
+ virtual void recvReqRetry()
{ panic("%s does not expect a retry\n", name()); }
};
diff --git a/src/cpu/testers/traffic_gen/traffic_gen.cc b/src/cpu/testers/traffic_gen/traffic_gen.cc
index 9eee7a119..e4759512d 100644
--- a/src/cpu/testers/traffic_gen/traffic_gen.cc
+++ b/src/cpu/testers/traffic_gen/traffic_gen.cc
@@ -476,7 +476,7 @@ TrafficGen::enterState(uint32_t newState)
}
void
-TrafficGen::recvRetry()
+TrafficGen::recvReqRetry()
{
assert(retryPkt != NULL);
diff --git a/src/cpu/testers/traffic_gen/traffic_gen.hh b/src/cpu/testers/traffic_gen/traffic_gen.hh
index b9081b1d4..eb9f6541d 100644
--- a/src/cpu/testers/traffic_gen/traffic_gen.hh
+++ b/src/cpu/testers/traffic_gen/traffic_gen.hh
@@ -91,7 +91,7 @@ class TrafficGen : public MemObject
* Receive a retry from the neighbouring port and attempt to
* resend the waiting packet.
*/
- void recvRetry();
+ void recvReqRetry();
/** Struct to represent a probabilistic transition during parsing. */
struct Transition {
@@ -148,7 +148,7 @@ class TrafficGen : public MemObject
protected:
- void recvRetry() { trafficGen.recvRetry(); }
+ void recvReqRetry() { trafficGen.recvReqRetry(); }
bool recvTimingResp(PacketPtr pkt);