gem5  v21.1.0.2
HTMSequencer.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 ARM Limited
3  * All rights reserved
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions are
16  * met: redistributions of source code must retain the above copyright
17  * notice, this list of conditions and the following disclaimer;
18  * redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution;
21  * neither the name of the copyright holders nor the names of its
22  * contributors may be used to endorse or promote products derived from
23  * this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  */
37 
39 
40 #include "debug/HtmMem.hh"
41 #include "debug/RubyPort.hh"
43 #include "sim/system.hh"
44 
45 namespace gem5
46 {
47 
48 namespace ruby
49 {
50 
53  const HtmFailedInCacheReason ruby_ret_code)
54 {
55  switch (ruby_ret_code) {
56  case HtmFailedInCacheReason_NO_FAIL:
58  case HtmFailedInCacheReason_FAIL_SELF:
60  case HtmFailedInCacheReason_FAIL_REMOTE:
62  case HtmFailedInCacheReason_FAIL_OTHER:
64  default:
65  panic("Invalid htm return code\n");
66  }
67 }
68 
69 HTMSequencer::HTMSequencer(const RubyHTMSequencerParams &p)
70  : Sequencer(p),
71  ADD_STAT(m_htm_transaction_cycles, "number of cycles spent in an outer "
72  "transaction"),
73  ADD_STAT(m_htm_transaction_instructions, "number of instructions spent "
74  "in an outer transaction"),
75  ADD_STAT(m_htm_transaction_abort_cause, "cause of htm transaction abort")
76 {
77  m_htmstart_tick = 0;
79 
80  // hardware transactional memory
82  .init(10)
85  ;
87  .init(10)
90  ;
91  auto num_causes = static_cast<int>(HtmFailureFaultCause::NUM_CAUSES);
93  .init(num_causes)
96  ;
97 
98  for (unsigned cause_idx = 0; cause_idx < num_causes; ++cause_idx) {
100  cause_idx,
102  }
103 
104 }
105 
107 {
108 }
109 
110 void
112  const HtmCallbackMode mode,
113  const HtmFailedInCacheReason htm_return_code)
114 {
115  // mode=0: HTM command
116  // mode=1: transaction failed - inform via LD
117  // mode=2: transaction failed - inform via ST
118 
119  if (mode == HtmCallbackMode_HTM_CMD) {
120  SequencerRequest* request = nullptr;
121 
122  assert(m_htmCmdRequestTable.size() > 0);
123 
124  request = m_htmCmdRequestTable.front();
125  m_htmCmdRequestTable.pop_front();
126 
127  assert(isHtmCmdRequest(request->m_type));
128 
129  PacketPtr pkt = request->pkt;
130  delete request;
131 
132  // valid responses have zero as the payload
133  uint8_t* dataptr = pkt->getPtr<uint8_t>();
134  memset(dataptr, 0, pkt->getSize());
135  *dataptr = (uint8_t) htm_return_code;
136 
137  // record stats
138  if (htm_return_code == HtmFailedInCacheReason_NO_FAIL) {
139  if (pkt->req->isHTMStart()) {
140  m_htmstart_tick = pkt->req->time();
141  m_htmstart_instruction = pkt->req->getInstCount();
142  DPRINTF(HtmMem, "htmStart - htmUid=%u\n",
143  pkt->getHtmTransactionUid());
144  } else if (pkt->req->isHTMCommit()) {
145  Tick transaction_ticks = pkt->req->time() - m_htmstart_tick;
146  Cycles transaction_cycles = ticksToCycles(transaction_ticks);
147  m_htm_transaction_cycles.sample(transaction_cycles);
148  m_htmstart_tick = 0;
149  Counter transaction_instructions =
150  pkt->req->getInstCount() - m_htmstart_instruction;
152  transaction_instructions);
154  DPRINTF(HtmMem, "htmCommit - htmUid=%u\n",
155  pkt->getHtmTransactionUid());
156  } else if (pkt->req->isHTMAbort()) {
157  HtmFailureFaultCause cause = pkt->req->getHtmAbortCause();
158  assert(cause != HtmFailureFaultCause::INVALID);
159  auto cause_idx = static_cast<int>(cause);
160  m_htm_transaction_abort_cause[cause_idx]++;
161  DPRINTF(HtmMem, "htmAbort - reason=%s - htmUid=%u\n",
162  htmFailureToStr(cause),
163  pkt->getHtmTransactionUid());
164  }
165  } else {
166  DPRINTF(HtmMem, "HTM_CMD: fail - htmUid=%u\n",
167  pkt->getHtmTransactionUid());
168  }
169 
170  rubyHtmCallback(pkt, htm_return_code);
172  } else if (mode == HtmCallbackMode_LD_FAIL ||
173  mode == HtmCallbackMode_ST_FAIL) {
174  // transaction failed
175  assert(address == makeLineAddress(address));
176  assert(m_RequestTable.find(address) != m_RequestTable.end());
177 
178  auto &seq_req_list = m_RequestTable[address];
179  while (!seq_req_list.empty()) {
180  SequencerRequest &request = seq_req_list.front();
181 
182  PacketPtr pkt = request.pkt;
183  markRemoved();
184 
185  // TODO - atomics
186 
187  // store conditionals should indicate failure
188  if (request.m_type == RubyRequestType_Store_Conditional) {
189  pkt->req->setExtraData(0);
190  }
191 
192  DPRINTF(HtmMem, "%s_FAIL: size=%d - "
193  "addr=0x%lx - htmUid=%d\n",
194  (mode == HtmCallbackMode_LD_FAIL) ? "LD" : "ST",
195  pkt->getSize(),
196  address, pkt->getHtmTransactionUid());
197 
198  rubyHtmCallback(pkt, htm_return_code);
200  pkt = nullptr;
201  seq_req_list.pop_front();
202  }
203  // free all outstanding requests corresponding to this address
204  if (seq_req_list.empty()) {
205  m_RequestTable.erase(address);
206  }
207  } else {
208  panic("unrecognised HTM callback mode\n");
209  }
210 }
211 
212 void
214 {
215  // hardware transactional memory
217  .init(10)
218  .name(name() + ".htm_transaction_cycles")
219  .desc("number of cycles spent in an outer transaction")
222  ;
224  .init(10)
225  .name(name() + ".htm_transaction_instructions")
226  .desc("number of instructions spent in an outer transaction")
229  ;
230  auto num_causes = static_cast<int>(HtmFailureFaultCause::NUM_CAUSES);
232  .init(num_causes)
233  .name(name() + ".htm_transaction_abort_cause")
234  .desc("cause of htm transaction abort")
237  ;
238 
239  for (unsigned cause_idx = 0; cause_idx < num_causes; ++cause_idx) {
241  cause_idx,
243  }
244 }
245 
246 void
248  const HtmFailedInCacheReason htm_return_code)
249 {
250  // The packet was destined for memory and has not yet been turned
251  // into a response
252  assert(system->isMemAddr(pkt->getAddr()) || system->isDeviceMemAddr(pkt));
253  assert(pkt->isRequest());
254 
255  // First retrieve the request port from the sender State
256  RubyPort::SenderState *senderState =
257  safe_cast<RubyPort::SenderState *>(pkt->popSenderState());
258 
259  MemResponsePort *port = safe_cast<MemResponsePort*>(senderState->port);
260  assert(port != nullptr);
261  delete senderState;
262 
263  //port->htmCallback(pkt, htm_return_code);
264  DPRINTF(HtmMem, "HTM callback: start=%d, commit=%d, "
265  "cancel=%d, rc=%d\n",
266  pkt->req->isHTMStart(), pkt->req->isHTMCommit(),
267  pkt->req->isHTMCancel(), htm_return_code);
268 
269  // turn packet around to go back to requestor if response expected
270  if (pkt->needsResponse()) {
271  DPRINTF(RubyPort, "Sending packet back over port\n");
273  htmRetCodeConversion(htm_return_code));
274  port->schedTimingResp(pkt, curTick());
275  } else {
276  delete pkt;
277  }
278 
279  trySendRetries();
280 }
281 
282 void
284 {
286 
287  // Check for deadlock of any of the requests
288  Cycles current_time = curCycle();
289 
290  // hardware transactional memory commands
292  m_htmCmdRequestTable.begin();
294  m_htmCmdRequestTable.end();
295 
296  for (; htm != htm_end; ++htm) {
297  SequencerRequest* request = *htm;
298  if (current_time - request->issue_time < m_deadlock_threshold)
299  continue;
300 
301  panic("Possible Deadlock detected. Aborting!\n"
302  "version: %d m_htmCmdRequestTable: %d "
303  "current time: %u issue_time: %d difference: %d\n",
305  current_time * clockPeriod(),
306  request->issue_time * clockPeriod(),
307  (current_time * clockPeriod()) -
308  (request->issue_time * clockPeriod()));
309  }
310 }
311 
312 bool
314 {
315  return Sequencer::empty() && m_htmCmdRequestTable.empty();
316 }
317 
318 template <class VALUE>
319 std::ostream &
320 operator<<(std::ostream &out, const std::deque<VALUE> &queue)
321 {
322  auto i = queue.begin();
323  auto end = queue.end();
324 
325  out << "[";
326  for (; i != end; ++i)
327  out << " " << *i;
328  out << " ]";
329 
330  return out;
331 }
332 
333 void
334 HTMSequencer::print(std::ostream& out) const
335 {
336  Sequencer::print(out);
337 
338  out << "+ [HTMSequencer: " << m_version
339  << ", htm cmd request table: " << m_htmCmdRequestTable
340  << "]";
341 }
342 
343 // Insert the request in the request table. Return RequestStatus_Aliased
344 // if the entry was already present.
345 RequestStatus
346 HTMSequencer::insertRequest(PacketPtr pkt, RubyRequestType primary_type,
347  RubyRequestType secondary_type)
348 {
349  if (isHtmCmdRequest(primary_type)) {
350  // for the moment, allow just one HTM cmd into the cache controller.
351  // Later this can be adjusted for optimization, e.g.
352  // back-to-back HTM_Starts.
353  if ((m_htmCmdRequestTable.size() > 0) && !pkt->req->isHTMAbort())
354  return RequestStatus_BufferFull;
355 
356  // insert request into HtmCmd queue
357  SequencerRequest* htmReq =
358  new SequencerRequest(pkt, primary_type, secondary_type,
359  curCycle());
360  assert(htmReq);
361  m_htmCmdRequestTable.push_back(htmReq);
362  return RequestStatus_Ready;
363  } else {
364  return Sequencer::insertRequest(pkt, primary_type, secondary_type);
365  }
366 }
367 
368 } // namespace ruby
369 } // namespace gem5
gem5::curTick
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:46
gem5::HtmCacheFailure::FAIL_OTHER
@ FAIL_OTHER
gem5::ruby::Sequencer::m_RequestTable
std::unordered_map< Addr, std::list< SequencerRequest > > m_RequestTable
Definition: Sequencer.hh:217
gem5::ruby::HTMSequencer::~HTMSequencer
~HTMSequencer()
Definition: HTMSequencer.cc:106
gem5::ruby::Sequencer
Definition: Sequencer.hh:86
gem5::ruby::RubyPort::m_version
uint32_t m_version
Definition: RubyPort.hh:196
gem5::ruby::RubyPort::SenderState::port
MemResponsePort * port
Definition: RubyPort.hh:148
gem5::Packet::isRequest
bool isRequest() const
Definition: packet.hh:586
HTMSequencer.hh
gem5::ruby::Sequencer::m_deadlock_threshold
Cycles m_deadlock_threshold
Definition: Sequencer.hh:219
system.hh
gem5::Clocked::curCycle
Cycles curCycle() const
Determine the current cycle, corresponding to a tick aligned to a clock edge.
Definition: clocked_object.hh:195
gem5::ruby::HTMSequencer::print
void print(std::ostream &out) const override
Definition: HTMSequencer.cc:334
gem5::HtmFailureFaultCause
HtmFailureFaultCause
Definition: htm.hh:47
gem5::ruby::operator<<
std::ostream & operator<<(std::ostream &os, const BoolVec &myvector)
Definition: BoolVec.cc:49
gem5::HtmCacheFailure::NO_FAIL
@ NO_FAIL
gem5::Packet::req
RequestPtr req
A pointer to the original request.
Definition: packet.hh:366
gem5::ruby::RubyPort::system
System * system
Definition: RubyPort.hh:200
gem5::ruby::RubyPort::MemResponsePort
Definition: RubyPort.hh:81
gem5::statistics::nozero
const FlagsType nozero
Don't print if this is zero.
Definition: info.hh:68
gem5::HtmCacheFailure
HtmCacheFailure
Definition: htm.hh:59
gem5::ruby::Sequencer::insertRequest
virtual RequestStatus insertRequest(PacketPtr pkt, RubyRequestType primary_type, RubyRequestType secondary_type)
Definition: Sequencer.cc:302
gem5::statistics::DataWrapVec::subname
Derived & subname(off_type index, const std::string &name)
Set the subfield name for the given index, and marks this stat to print at the end of simulation.
Definition: statistics.hh:399
gem5::statistics::nonan
const FlagsType nonan
Don't print if this is NAN.
Definition: info.hh:70
gem5::ruby::RubyPort::trySendRetries
void trySendRetries()
Definition: RubyPort.cc:464
gem5::ruby::HTMSequencer::regStats
void regStats() override
Callback to set stat parameters.
Definition: HTMSequencer.cc:213
gem5::ruby::HTMSequencer::htmRetCodeConversion
HtmCacheFailure htmRetCodeConversion(const HtmFailedInCacheReason rc)
Htm return code conversion.
Definition: HTMSequencer.cc:52
gem5::ArmISA::i
Bitfield< 7 > i
Definition: misc_types.hh:66
gem5::ruby::makeLineAddress
Addr makeLineAddress(Addr addr)
Definition: Address.cc:60
gem5::ruby::HTMSequencer::m_htmstart_instruction
Counter m_htmstart_instruction
Definition: HTMSequencer.hh:101
gem5::ruby::HTMSequencer::m_htm_transaction_cycles
statistics::Histogram m_htm_transaction_cycles
Histogram of cycle latencies of HTM transactions.
Definition: HTMSequencer.hh:104
gem5::ruby::RubyPort::SenderState
Definition: RubyPort.hh:146
gem5::statistics::DistBase::sample
void sample(const U &v, int n=1)
Add a value to the distribtion n times.
Definition: statistics.hh:1325
gem5::statistics::dist
const FlagsType dist
Print the distribution.
Definition: info.hh:66
gem5::HtmCacheFailure::FAIL_SELF
@ FAIL_SELF
gem5::Cycles
Cycles is a wrapper class for representing cycle counts, i.e.
Definition: types.hh:78
gem5::statistics::pdf
const FlagsType pdf
Print the percent of the total that this entry represents.
Definition: info.hh:62
gem5::ruby::HTMSequencer::insertRequest
RequestStatus insertRequest(PacketPtr pkt, RubyRequestType primary_type, RubyRequestType secondary_type) override
Definition: HTMSequencer.cc:346
gem5::ruby::HTMSequencer::m_htmstart_tick
Tick m_htmstart_tick
Definition: HTMSequencer.hh:100
gem5::HtmCacheFailure::FAIL_REMOTE
@ FAIL_REMOTE
gem5::statistics::DataWrap::name
Derived & name(const std::string &name)
Set the name and marks this stat to print at the end of simulation.
Definition: statistics.hh:286
gem5::System::isMemAddr
bool isMemAddr(Addr addr) const
Check if a physical address is within a range of a memory that is part of the global address map.
Definition: system.cc:376
gem5::Named::name
virtual std::string name() const
Definition: named.hh:47
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:186
ADD_STAT
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:75
gem5::Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:283
gem5::ruby::HTMSequencer::htmCallback
void htmCallback(Addr, const HtmCallbackMode, const HtmFailedInCacheReason)
Definition: HTMSequencer.cc:111
gem5::MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:326
gem5::Tick
uint64_t Tick
Tick count type.
Definition: types.hh:58
gem5::ruby::SequencerRequest
Definition: Sequencer.hh:62
gem5::Packet::getHtmTransactionUid
uint64_t getHtmTransactionUid() const
If a packet/request originates in a CPU executing in transactional mode, i.e.
Definition: packet.cc:534
gem5::HtmFailureFaultCause::NUM_CAUSES
@ NUM_CAUSES
RubySlicc_Util.hh
gem5::ruby::HTMSequencer::empty
bool empty() const override
Definition: HTMSequencer.cc:313
gem5::Packet::makeHtmTransactionalReqResponse
void makeHtmTransactionalReqResponse(const HtmCacheFailure ret_code)
Communicates to the core that a packet was processed by the memory subsystem while running in transac...
Definition: packet.cc:482
gem5::HtmFailureFaultCause::INVALID
@ INVALID
gem5::ruby::HTMSequencer::m_htmCmdRequestTable
std::deque< SequencerRequest * > m_htmCmdRequestTable
Definition: HTMSequencer.hh:98
gem5::ruby::Sequencer::empty
virtual bool empty() const
Definition: Sequencer.cc:651
gem5::Packet::needsResponse
bool needsResponse() const
Definition: packet.hh:597
gem5::ruby::RubyPort::testDrainComplete
void testDrainComplete()
Definition: RubyPort.cc:490
gem5::Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
gem5::statistics::Histogram::init
Histogram & init(size_type size)
Set the parameters of this histogram.
Definition: statistics.hh:2151
gem5::ruby::HTMSequencer::m_htm_transaction_instructions
statistics::Histogram m_htm_transaction_instructions
Histogram of instruction lengths of HTM transactions.
Definition: HTMSequencer.hh:106
gem5::Packet::popSenderState
SenderState * popSenderState()
Pop the top of the state stack and return a pointer to it.
Definition: packet.cc:324
gem5::ruby::Sequencer::print
virtual void print(std::ostream &out) const
Definition: Sequencer.cc:832
gem5::ruby::Sequencer::wakeup
virtual void wakeup()
Definition: Sequencer.cc:221
gem5::System::isDeviceMemAddr
bool isDeviceMemAddr(const PacketPtr &pkt) const
Similar to isMemAddr but for devices.
Definition: system.cc:389
gem5::statistics::DataWrap::desc
Derived & desc(const std::string &_desc)
Set the description and marks this stat to print at the end of simulation.
Definition: statistics.hh:331
gem5::ruby::Sequencer::markRemoved
void markRemoved()
Definition: Sequencer.cc:329
gem5::ruby::HTMSequencer::HTMSequencer
HTMSequencer(const RubyHTMSequencerParams &p)
Definition: HTMSequencer.cc:69
gem5::htmFailureToStr
std::string htmFailureToStr(HtmFailureFaultCause cause)
Convert enum into string to be used for debug purposes.
Definition: htm.cc:44
gem5::ruby::HTMSequencer::rubyHtmCallback
void rubyHtmCallback(PacketPtr pkt, const HtmFailedInCacheReason fail_r)
Definition: HTMSequencer.cc:247
gem5::ruby::HTMSequencer::wakeup
void wakeup() override
Definition: HTMSequencer.cc:283
gem5::ruby::isHtmCmdRequest
bool isHtmCmdRequest(RubyRequestType type)
Definition: RubySlicc_Util.hh:152
std::deque
STL deque class.
Definition: stl.hh:44
gem5::statistics::Counter
double Counter
All counters are of 64-bit values.
Definition: types.hh:47
gem5::ruby::SequencerRequest::m_type
RubyRequestType m_type
Definition: Sequencer.hh:65
gem5::ruby::SequencerRequest::issue_time
Cycles issue_time
Definition: Sequencer.hh:67
gem5::ruby::HTMSequencer::m_htm_transaction_abort_cause
statistics::Vector m_htm_transaction_abort_cause
Causes for HTM transaction aborts.
Definition: HTMSequencer.hh:108
gem5::statistics::DataWrap::flags
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
Definition: statistics.hh:355
gem5::Clocked::ticksToCycles
Cycles ticksToCycles(Tick t) const
Definition: clocked_object.hh:222
gem5::Packet::getAddr
Addr getAddr() const
Definition: packet.hh:781
gem5::QueuedResponsePort::schedTimingResp
void schedTimingResp(PacketPtr pkt, Tick when)
Schedule the sending of a timing response.
Definition: qport.hh:93
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: decoder.cc:40
gem5::statistics::total
const FlagsType total
Print the total.
Definition: info.hh:60
gem5::statistics::VectorBase::init
Derived & init(size_type size)
Set this vector to have the given size.
Definition: statistics.hh:1037
gem5::ruby::RubyPort
Definition: RubyPort.hh:64
gem5::Packet::getSize
unsigned getSize() const
Definition: packet.hh:791
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:177
gem5::Clocked::clockPeriod
Tick clockPeriod() const
Definition: clocked_object.hh:217
gem5::ArmISA::mode
Bitfield< 4, 0 > mode
Definition: misc_types.hh:73
gem5::Packet::getPtr
T * getPtr()
get a pointer to the data ptr.
Definition: packet.hh:1184
gem5::ruby::SequencerRequest::pkt
PacketPtr pkt
Definition: Sequencer.hh:64

Generated on Tue Sep 21 2021 12:25:42 for gem5 by doxygen 1.8.17