summaryrefslogtreecommitdiff
path: root/src/mem/xbar.hh
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/mem/xbar.hh
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/mem/xbar.hh')
-rw-r--r--src/mem/xbar.hh70
1 files changed, 69 insertions, 1 deletions
diff --git a/src/mem/xbar.hh b/src/mem/xbar.hh
index 81b16c19d..f51b08da2 100644
--- a/src/mem/xbar.hh
+++ b/src/mem/xbar.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2014 ARM Limited
+ * Copyright (c) 2011-2015 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -174,6 +174,16 @@ class BaseXBar : public MemObject
*/
void regStats();
+ protected:
+
+ /**
+ * Sending the actual retry, in a manner specific to the
+ * individual layers. Note that for a MasterPort, there is
+ * both a RequestLayer and a SnoopResponseLayer using the same
+ * port, but using different functions for the flow control.
+ */
+ virtual void sendRetry(SrcType* retry_port) = 0;
+
private:
/** The destination port this layer converges at. */
@@ -241,6 +251,64 @@ class BaseXBar : public MemObject
};
+ class ReqLayer : public Layer<SlavePort,MasterPort>
+ {
+ public:
+ /**
+ * Create a request layer and give it a name.
+ *
+ * @param _port destination port the layer converges at
+ * @param _xbar the crossbar this layer belongs to
+ * @param _name the layer's name
+ */
+ ReqLayer(MasterPort& _port, BaseXBar& _xbar, const std::string& _name) :
+ Layer(_port, _xbar, _name) {}
+
+ protected:
+
+ void sendRetry(SlavePort* retry_port)
+ { retry_port->sendRetryReq(); }
+ };
+
+ class RespLayer : public Layer<MasterPort,SlavePort>
+ {
+ public:
+ /**
+ * Create a response layer and give it a name.
+ *
+ * @param _port destination port the layer converges at
+ * @param _xbar the crossbar this layer belongs to
+ * @param _name the layer's name
+ */
+ RespLayer(SlavePort& _port, BaseXBar& _xbar, const std::string& _name) :
+ Layer(_port, _xbar, _name) {}
+
+ protected:
+
+ void sendRetry(MasterPort* retry_port)
+ { retry_port->sendRetryResp(); }
+ };
+
+ class SnoopRespLayer : public Layer<SlavePort,MasterPort>
+ {
+ public:
+ /**
+ * Create a snoop response layer and give it a name.
+ *
+ * @param _port destination port the layer converges at
+ * @param _xbar the crossbar this layer belongs to
+ * @param _name the layer's name
+ */
+ SnoopRespLayer(MasterPort& _port, BaseXBar& _xbar,
+ const std::string& _name) :
+ Layer(_port, _xbar, _name) {}
+
+ protected:
+
+ void sendRetry(SlavePort* retry_port)
+ { retry_port->sendRetrySnoopResp(); }
+ };
+
/** cycles of overhead per transaction */
const Cycles headerCycles;
/** the width of the xbar in bytes */