mem: Determine if a packet queue forces ordering at construction
authorNikos Nikoleris <nikos.nikoleris@arm.com>
Tue, 27 Nov 2018 16:55:50 +0000 (16:55 +0000)
committerNikos Nikoleris <nikos.nikoleris@arm.com>
Thu, 17 Jan 2019 11:09:41 +0000 (11:09 +0000)
A packet queue is typically used to hold on to packets that are
schedules to be sent in the future or when they need to queue behind
younger packets that have been sent out yet. Due to memory order
requirements, some MemObjects need to maintain the order for packet
(mostly responses) that reference the same cache block.

Prior to this patch the ordering requirements where determined when
the packet was scheduled to be sent. This patch moves the parameter to
the constructor.

Change-Id: Ieb4d94e86bc7514f5036b313ec23ea47dd653164
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/15555
Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br>
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Maintainer: Jason Lowe-Power <jason@lowepower.com>

src/mem/cache/base.cc
src/mem/cache/cache.cc
src/mem/cache/noncoherent_cache.cc
src/mem/dram_ctrl.cc
src/mem/packet_queue.cc
src/mem/packet_queue.hh
src/mem/qos/mem_sink.cc
src/mem/qport.hh
src/mem/ruby/slicc_interface/AbstractController.cc

index 08cd09fc5a0a3f375689f8f358632f35b7d9012f..6049ca6a6abd01379e9aa3a300890138c0954f77 100644 (file)
@@ -69,7 +69,8 @@ using namespace std;
 BaseCache::CacheSlavePort::CacheSlavePort(const std::string &_name,
                                           BaseCache *_cache,
                                           const std::string &_label)
-    : QueuedSlavePort(_name, _cache, queue), queue(*_cache, *this, _label),
+    : QueuedSlavePort(_name, _cache, queue),
+      queue(*_cache, *this, true, _label),
       blocked(false), mustSendRetry(false),
       sendRetryEvent([this]{ processSendRetry(); }, _name)
 {
@@ -228,7 +229,7 @@ BaseCache::handleTimingReqHit(PacketPtr pkt, CacheBlk *blk, Tick request_time)
         // lat, neglecting responseLatency, modelling hit latency
         // just as the value of lat overriden by access(), which calls
         // the calculateAccessLatency() function.
-        cpuSidePort.schedTimingResp(pkt, request_time, true);
+        cpuSidePort.schedTimingResp(pkt, request_time);
     } else {
         DPRINTF(Cache, "%s satisfied %s, no response needed\n", __func__,
                 pkt->print());
@@ -400,7 +401,7 @@ BaseCache::handleUncacheableWriteResp(PacketPtr pkt)
     // Reset the bus additional time as it is now accounted for
     pkt->headerDelay = pkt->payloadDelay = 0;
 
-    cpuSidePort.schedTimingResp(pkt, completion_time, true);
+    cpuSidePort.schedTimingResp(pkt, completion_time);
 }
 
 void
@@ -2400,7 +2401,7 @@ BaseCache::MemSidePort::MemSidePort(const std::string &_name,
                                     const std::string &_label)
     : CacheMasterPort(_name, _cache, _reqQueue, _snoopRespQueue),
       _reqQueue(*_cache, *this, _snoopRespQueue, _label),
-      _snoopRespQueue(*_cache, *this, _label), cache(_cache)
+      _snoopRespQueue(*_cache, *this, true, _label), cache(_cache)
 {
 }
 
index 90c4b9b5a4a8bb36c2ad4557b69d92e6a0610334..e23c4ef30b71a4ed87d7064dea36e73ef28e39db 100644 (file)
@@ -391,7 +391,7 @@ Cache::handleTimingReqMiss(PacketPtr pkt, CacheBlk *blk, Tick forward_time,
 
         // request_time is used here, taking into account lat and the delay
         // charged if the packet comes from the xbar.
-        cpuSidePort.schedTimingResp(pkt, request_time, true);
+        cpuSidePort.schedTimingResp(pkt, request_time);
 
         // If an outstanding request is in progress (we found an
         // MSHR) this is set to null
@@ -802,7 +802,7 @@ Cache::serviceMSHRTargets(MSHR *mshr, const PacketPtr pkt, CacheBlk *blk)
             }
             // Reset the bus additional time as it is now accounted for
             tgt_pkt->headerDelay = tgt_pkt->payloadDelay = 0;
-            cpuSidePort.schedTimingResp(tgt_pkt, completion_time, true);
+            cpuSidePort.schedTimingResp(tgt_pkt, completion_time);
             break;
 
           case MSHR::Target::FromPrefetcher:
@@ -932,7 +932,7 @@ Cache::doTimingSupplyResponse(PacketPtr req_pkt, const uint8_t *blk_data,
     pkt->headerDelay = pkt->payloadDelay = 0;
     DPRINTF(CacheVerbose, "%s: created response: %s tick: %lu\n", __func__,
             pkt->print(), forward_time);
-    memSidePort.schedTimingSnoopResp(pkt, forward_time, true);
+    memSidePort.schedTimingSnoopResp(pkt, forward_time);
 }
 
 uint32_t
index ca282a38dab3e7c1f142120c63be8ec6963b64c2..08cfdd6540b2d135b5d7ddbfe90491fafd139dc0 100644 (file)
@@ -288,7 +288,7 @@ NoncoherentCache::serviceMSHRTargets(MSHR *mshr, const PacketPtr pkt,
 
             // Reset the bus additional time as it is now accounted for
             tgt_pkt->headerDelay = tgt_pkt->payloadDelay = 0;
-            cpuSidePort.schedTimingResp(tgt_pkt, completion_time, true);
+            cpuSidePort.schedTimingResp(tgt_pkt, completion_time);
             break;
 
           case MSHR::Target::FromPrefetcher:
index e7af75bb8db93a9b7cb99930075eb5fe3d8f3516..b6ec4653ddf451c97008a94a4b7f8d59c14e20e4 100644 (file)
@@ -938,7 +938,7 @@ DRAMCtrl::accessAndRespond(PacketPtr pkt, Tick static_latency)
 
         // queue the packet in the response queue to be sent out after
         // the static latency has passed
-        port.schedTimingResp(pkt, response_time, true);
+        port.schedTimingResp(pkt, response_time);
     } else {
         // @todo the packet is going to be deleted, and the DRAMPacket
         // is still having a pointer to it
@@ -2924,7 +2924,7 @@ DRAMCtrl::drainResume()
 }
 
 DRAMCtrl::MemoryPort::MemoryPort(const std::string& name, DRAMCtrl& _memory)
-    : QueuedSlavePort(name, &_memory, queue), queue(_memory, *this),
+    : QueuedSlavePort(name, &_memory, queue), queue(_memory, *this, true),
       memory(_memory)
 { }
 
index 7aa2fc1f9e106d77bfcfe00242ad6fc168ea4256..45378aec666148c6341354f80416c8713f545386 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012,2015 ARM Limited
+ * Copyright (c) 2012,2015,2018 ARM Limited
  * All rights reserved.
  *
  * The license below extends only to copyright in the software and shall
 
 PacketQueue::PacketQueue(EventManager& _em, const std::string& _label,
                          const std::string& _sendEventName,
+                         bool force_order,
                          bool disable_sanity_check)
     : em(_em), sendEvent([this]{ processSendEvent(); }, _sendEventName),
       _disableSanityCheck(disable_sanity_check),
+      forceOrder(force_order),
       label(_label), waitingOnRetry(false)
 {
 }
@@ -102,11 +104,11 @@ PacketQueue::trySatisfyFunctional(PacketPtr pkt)
 }
 
 void
-PacketQueue::schedSendTiming(PacketPtr pkt, Tick when, bool force_order)
+PacketQueue::schedSendTiming(PacketPtr pkt, Tick when)
 {
     DPRINTF(PacketQueue, "%s for %s address %x size %d when %lu ord: %i\n",
             __func__, pkt->cmdString(), pkt->getAddr(), pkt->getSize(), when,
-            force_order);
+            forceOrder);
 
     // we can still send a packet before the end of this tick
     assert(when >= curTick());
@@ -137,13 +139,13 @@ PacketQueue::schedSendTiming(PacketPtr pkt, Tick when, bool force_order)
     // assert(waitingOnRetry || sendEvent.scheduled());
 
     // this belongs in the middle somewhere, so search from the end to
-    // order by tick; however, if force_order is set, also make sure
+    // order by tick; however, if forceOrder is set, also make sure
     // not to re-order in front of some existing packet with the same
     // address
     auto i = transmitList.end();
     --i;
     while (i != transmitList.begin() && when < i->tick &&
-           !(force_order && i->pkt->getAddr() == pkt->getAddr()))
+           !(forceOrder && i->pkt->getAddr() == pkt->getAddr()))
         --i;
 
     // emplace inserts the element before the position pointed to by
@@ -250,8 +252,9 @@ ReqPacketQueue::sendTiming(PacketPtr pkt)
 
 SnoopRespPacketQueue::SnoopRespPacketQueue(EventManager& _em,
                                            MasterPort& _masterPort,
+                                           bool force_order,
                                            const std::string _label)
-    : PacketQueue(_em, _label, name(_masterPort, _label)),
+    : PacketQueue(_em, _label, name(_masterPort, _label), force_order),
       masterPort(_masterPort)
 {
 }
@@ -263,8 +266,9 @@ SnoopRespPacketQueue::sendTiming(PacketPtr pkt)
 }
 
 RespPacketQueue::RespPacketQueue(EventManager& _em, SlavePort& _slavePort,
+                                 bool force_order,
                                  const std::string _label)
-    : PacketQueue(_em, _label, name(_slavePort, _label)),
+    : PacketQueue(_em, _label, name(_slavePort, _label), force_order),
       slavePort(_slavePort)
 {
 }
index 629fca58e2071eaf5c8e26fcfd3996c13263a102..4ac4bf349e9cd63f416360e99af9549e90136497 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012,2015 ARM Limited
+ * Copyright (c) 2012,2015,2018 ARM Limited
  * All rights reserved.
  *
  * The license below extends only to copyright in the software and shall
@@ -96,6 +96,13 @@ class PacketQueue : public Drainable
       */
     bool _disableSanityCheck;
 
+    /**
+     * if true, inserted packets have to be unconditionally scheduled
+     * after the last packet in the queue that references the same
+     * address
+     */
+    bool forceOrder;
+
   protected:
 
     /** Label to use for print request packets label stack. */
@@ -130,11 +137,13 @@ class PacketQueue : public Drainable
      *
      * @param _em Event manager used for scheduling this queue
      * @param _label Label to push on the label stack for print request packets
+     * @param force_order Force insertion order for packets with same address
      * @param disable_sanity_check Flag used to disable the sanity check
      *        on the size of the transmitList. The check is enabled by default.
      */
     PacketQueue(EventManager& _em, const std::string& _label,
                 const std::string& _sendEventName,
+                bool force_order = false,
                 bool disable_sanity_check = false);
 
     /**
@@ -187,9 +196,8 @@ class PacketQueue : public Drainable
      *
      * @param pkt Packet to send
      * @param when Absolute time (in ticks) to send packet
-     * @param force_order Force insertion order for packets with same address
      */
-    void schedSendTiming(PacketPtr pkt, Tick when, bool force_order = false);
+    void schedSendTiming(PacketPtr pkt, Tick when);
 
     /**
      * Retry sending a packet from the queue. Note that this is not
@@ -267,9 +275,11 @@ class SnoopRespPacketQueue : public PacketQueue
      *
      * @param _em Event manager used for scheduling this queue
      * @param _masterPort Master port used to send the packets
+     * @param force_order Force insertion order for packets with same address
      * @param _label Label to push on the label stack for print request packets
      */
     SnoopRespPacketQueue(EventManager& _em, MasterPort& _masterPort,
+                         bool force_order = false,
                          const std::string _label = "SnoopRespPacketQueue");
 
     virtual ~SnoopRespPacketQueue() { }
@@ -303,10 +313,12 @@ class RespPacketQueue : public PacketQueue
      *
      * @param _em Event manager used for scheduling this queue
      * @param _slavePort Slave port used to send the packets
+     * @param force_order Force insertion order for packets with same address
      * @param _label Label to push on the label stack for print request packets
      */
     RespPacketQueue(EventManager& _em, SlavePort& _slavePort,
-                     const std::string _label = "RespPacketQueue");
+                    bool force_order = false,
+                    const std::string _label = "RespPacketQueue");
 
     virtual ~RespPacketQueue() { }
 
index a951daee2a1419f5ac00524c60a79d1401abf009..77cfbaf22a88b3de0528e11e6acfb3da6fa75c98 100644 (file)
@@ -289,7 +289,7 @@ MemSinkCtrl::processNextReqEvent()
                 removed_entries, responseLatency);
 
     // Schedule the response
-    port.schedTimingResp(pkt, curTick() + responseLatency, true);
+    port.schedTimingResp(pkt, curTick() + responseLatency);
     DPRINTF(QOS,
             "%s response scheduled at time %d\n",
             __func__, curTick() + responseLatency);
@@ -344,7 +344,7 @@ MemSinkCtrl::regStats()
 
 MemSinkCtrl::MemoryPort::MemoryPort(const std::string& n,
                                     MemSinkCtrl& m)
-  : QueuedSlavePort(n, &m, queue), memory(m), queue(memory, *this)
+  : QueuedSlavePort(n, &m, queue, true), memory(m), queue(memory, *this, true)
 {}
 
 AddrRangeList
index 708347a21ba282d13e57af21277691a9bdb53b25..77d8dfafa18b0e60a097e9118616af7c9d5909be 100644 (file)
@@ -88,8 +88,8 @@ class QueuedSlavePort : public SlavePort
      * @param pkt Packet to send
      * @param when Absolute time (in ticks) to send packet
      */
-    void schedTimingResp(PacketPtr pkt, Tick when, bool force_order = false)
-    { respQueue.schedSendTiming(pkt, when, force_order); }
+    void schedTimingResp(PacketPtr pkt, Tick when)
+    { respQueue.schedSendTiming(pkt, when); }
 
     /** Check the list of buffered packets against the supplied
      * functional request. */
@@ -153,9 +153,8 @@ class QueuedMasterPort : public MasterPort
      * @param pkt Packet to send
      * @param when Absolute time (in ticks) to send packet
      */
-    void schedTimingSnoopResp(PacketPtr pkt, Tick when, bool force_order =
-                              false)
-    { snoopRespQueue.schedSendTiming(pkt, when, force_order); }
+    void schedTimingSnoopResp(PacketPtr pkt, Tick when)
+    { snoopRespQueue.schedSendTiming(pkt, when); }
 
     /** Check the list of buffered packets against the supplied
      * functional request. */
index 101a4ce7f9ad2ee3edad0687af8c736448e97f84..1327eccfb0b17f0aebf821f14a846e456cbecf44 100644 (file)
@@ -382,7 +382,7 @@ AbstractController::MemoryPort::MemoryPort(const std::string &_name,
                                            const std::string &_label)
     : QueuedMasterPort(_name, _controller, reqQueue, snoopRespQueue),
       reqQueue(*_controller, *this, _label),
-      snoopRespQueue(*_controller, *this, _label),
+      snoopRespQueue(*_controller, *this, false, _label),
       controller(_controller)
 {
 }