From: Nikos Nikoleris Date: Tue, 27 Nov 2018 16:55:50 +0000 (+0000) Subject: mem: Determine if a packet queue forces ordering at construction X-Git-Tag: v19.0.0.0~1255 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ccc50b7355fa9964c6da3ca1de2b3c48b7728bae;p=gem5.git mem: Determine if a packet queue forces ordering at construction 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 Reviewed-on: https://gem5-review.googlesource.com/c/15555 Reviewed-by: Daniel Carvalho Reviewed-by: Jason Lowe-Power Maintainer: Jason Lowe-Power --- diff --git a/src/mem/cache/base.cc b/src/mem/cache/base.cc index 08cd09fc5..6049ca6a6 100644 --- a/src/mem/cache/base.cc +++ b/src/mem/cache/base.cc @@ -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) { } diff --git a/src/mem/cache/cache.cc b/src/mem/cache/cache.cc index 90c4b9b5a..e23c4ef30 100644 --- a/src/mem/cache/cache.cc +++ b/src/mem/cache/cache.cc @@ -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 diff --git a/src/mem/cache/noncoherent_cache.cc b/src/mem/cache/noncoherent_cache.cc index ca282a38d..08cfdd654 100644 --- a/src/mem/cache/noncoherent_cache.cc +++ b/src/mem/cache/noncoherent_cache.cc @@ -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: diff --git a/src/mem/dram_ctrl.cc b/src/mem/dram_ctrl.cc index e7af75bb8..b6ec4653d 100644 --- a/src/mem/dram_ctrl.cc +++ b/src/mem/dram_ctrl.cc @@ -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) { } diff --git a/src/mem/packet_queue.cc b/src/mem/packet_queue.cc index 7aa2fc1f9..45378aec6 100644 --- a/src/mem/packet_queue.cc +++ b/src/mem/packet_queue.cc @@ -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 @@ -49,9 +49,11 @@ 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) { } diff --git a/src/mem/packet_queue.hh b/src/mem/packet_queue.hh index 629fca58e..4ac4bf349 100644 --- a/src/mem/packet_queue.hh +++ b/src/mem/packet_queue.hh @@ -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() { } diff --git a/src/mem/qos/mem_sink.cc b/src/mem/qos/mem_sink.cc index a951daee2..77cfbaf22 100644 --- a/src/mem/qos/mem_sink.cc +++ b/src/mem/qos/mem_sink.cc @@ -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 diff --git a/src/mem/qport.hh b/src/mem/qport.hh index 708347a21..77d8dfafa 100644 --- a/src/mem/qport.hh +++ b/src/mem/qport.hh @@ -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. */ diff --git a/src/mem/ruby/slicc_interface/AbstractController.cc b/src/mem/ruby/slicc_interface/AbstractController.cc index 101a4ce7f..1327eccfb 100644 --- a/src/mem/ruby/slicc_interface/AbstractController.cc +++ b/src/mem/ruby/slicc_interface/AbstractController.cc @@ -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) { }