gem5 v24.0.0.0
Loading...
Searching...
No Matches
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
45namespace gem5
46{
47
48namespace 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
69HTMSequencer::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{
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
109
110void
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);
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
212void
214 const HtmFailedInCacheReason htm_return_code)
215{
216 // The packet was destined for memory and has not yet been turned
217 // into a response
218 assert(system->isMemAddr(pkt->getAddr()) || system->isDeviceMemAddr(pkt));
219 assert(pkt->isRequest());
220
221 // First retrieve the request port from the sender State
222 RubyPort::SenderState *senderState =
224
226 assert(port != nullptr);
227 delete senderState;
228
229 //port->htmCallback(pkt, htm_return_code);
230 DPRINTF(HtmMem, "HTM callback: start=%d, commit=%d, "
231 "cancel=%d, rc=%d\n",
232 pkt->req->isHTMStart(), pkt->req->isHTMCommit(),
233 pkt->req->isHTMCancel(), htm_return_code);
234
235 // turn packet around to go back to requestor if response expected
236 if (pkt->needsResponse()) {
237 DPRINTF(RubyPort, "Sending packet back over port\n");
239 htmRetCodeConversion(htm_return_code));
240 port->schedTimingResp(pkt, curTick());
241 } else {
242 delete pkt;
243 }
244
246}
247
248void
250{
252
253 // Check for deadlock of any of the requests
254 Cycles current_time = curCycle();
255
256 // hardware transactional memory commands
258 m_htmCmdRequestTable.begin();
261
262 for (; htm != htm_end; ++htm) {
263 SequencerRequest* request = *htm;
264 if (current_time - request->issue_time < m_deadlock_threshold)
265 continue;
266
267 panic("Possible Deadlock detected. Aborting!\n"
268 "version: %d m_htmCmdRequestTable: %d "
269 "current time: %u issue_time: %d difference: %d\n",
271 current_time * clockPeriod(),
272 request->issue_time * clockPeriod(),
273 (current_time * clockPeriod()) -
274 (request->issue_time * clockPeriod()));
275 }
276}
277
278bool
280{
281 return Sequencer::empty() && m_htmCmdRequestTable.empty();
282}
283
284template <class VALUE>
285std::ostream &
286operator<<(std::ostream &out, const std::deque<VALUE> &queue)
287{
288 auto i = queue.begin();
289 auto end = queue.end();
290
291 out << "[";
292 for (; i != end; ++i)
293 out << " " << *i;
294 out << " ]";
295
296 return out;
297}
298
299void
300HTMSequencer::print(std::ostream& out) const
301{
302 Sequencer::print(out);
303
304 out << "+ [HTMSequencer: " << m_version
305 << ", htm cmd request table: " << m_htmCmdRequestTable
306 << "]";
307}
308
309// Insert the request in the request table. Return RequestStatus_Aliased
310// if the entry was already present.
311RequestStatus
312HTMSequencer::insertRequest(PacketPtr pkt, RubyRequestType primary_type,
313 RubyRequestType secondary_type)
314{
315 if (isHtmCmdRequest(primary_type)) {
316 // for the moment, allow just one HTM cmd into the cache controller.
317 // Later this can be adjusted for optimization, e.g.
318 // back-to-back HTM_Starts.
319 if ((m_htmCmdRequestTable.size() > 0) && !pkt->req->isHTMAbort())
320 return RequestStatus_BufferFull;
321
322 // insert request into HtmCmd queue
323 SequencerRequest* htmReq =
324 new SequencerRequest(pkt, primary_type, secondary_type,
325 curCycle());
326 assert(htmReq);
327 m_htmCmdRequestTable.push_back(htmReq);
328 return RequestStatus_Ready;
329 } else {
330 return Sequencer::insertRequest(pkt, primary_type, secondary_type);
331 }
332}
333
334} // namespace ruby
335} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:210
Cycles curCycle() const
Determine the current cycle, corresponding to a tick aligned to a clock edge.
Tick clockPeriod() const
Cycles ticksToCycles(Tick t) const
Cycles is a wrapper class for representing cycle counts, i.e.
Definition types.hh:79
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition packet.hh:295
Addr getAddr() const
Definition packet.hh:807
bool needsResponse() const
Definition packet.hh:608
SenderState * popSenderState()
Pop the top of the state stack and return a pointer to it.
Definition packet.cc:342
T * getPtr()
get a pointer to the data ptr.
Definition packet.hh:1225
uint64_t getHtmTransactionUid() const
If a packet/request originates in a CPU executing in transactional mode, i.e.
Definition packet.cc:529
RequestPtr req
A pointer to the original request.
Definition packet.hh:377
unsigned getSize() const
Definition packet.hh:817
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:477
bool isRequest() const
Definition packet.hh:597
void schedTimingResp(PacketPtr pkt, Tick when)
Schedule the sending of a timing response.
Definition qport.hh:94
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:288
bool isDeviceMemAddr(const PacketPtr &pkt) const
Similar to isMemAddr but for devices.
Definition system.cc:301
void rubyHtmCallback(PacketPtr pkt, const HtmFailedInCacheReason fail_r)
bool empty() const override
statistics::Vector m_htm_transaction_abort_cause
Causes for HTM transaction aborts.
HtmCacheFailure htmRetCodeConversion(const HtmFailedInCacheReason rc)
Htm return code conversion.
HTMSequencer(const RubyHTMSequencerParams &p)
RequestStatus insertRequest(PacketPtr pkt, RubyRequestType primary_type, RubyRequestType secondary_type) override
statistics::Histogram m_htm_transaction_cycles
Histogram of cycle latencies of HTM transactions.
statistics::Histogram m_htm_transaction_instructions
Histogram of instruction lengths of HTM transactions.
void htmCallback(Addr, const HtmCallbackMode, const HtmFailedInCacheReason)
std::deque< SequencerRequest * > m_htmCmdRequestTable
void print(std::ostream &out) const override
std::unordered_map< Addr, std::list< SequencerRequest > > m_RequestTable
Definition Sequencer.hh:236
virtual bool empty() const
Definition Sequencer.cc:907
virtual RequestStatus insertRequest(PacketPtr pkt, RubyRequestType primary_type, RubyRequestType secondary_type)
Definition Sequencer.cc:308
virtual void print(std::ostream &out) const
virtual void wakeup()
Definition Sequencer.cc:227
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.
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
void sample(const U &v, int n=1)
Add a value to the distribtion n times.
Histogram & init(size_type size)
Set the parameters of this histogram.
Derived & init(size_type size)
Set this vector to have the given size.
STL deque class.
Definition stl.hh:44
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition group.hh:75
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
Bitfield< 4, 0 > mode
Definition misc_types.hh:74
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 0 > p
Addr makeLineAddress(Addr addr)
Definition Address.cc:60
std::ostream & operator<<(std::ostream &os, const BoolVec &myvector)
Definition BoolVec.cc:49
bool isHtmCmdRequest(RubyRequestType type)
const FlagsType pdf
Print the percent of the total that this entry represents.
Definition info.hh:61
const FlagsType nonan
Don't print if this is NAN.
Definition info.hh:69
const FlagsType nozero
Don't print if this is zero.
Definition info.hh:67
const FlagsType total
Print the total.
Definition info.hh:59
double Counter
All counters are of 64-bit values.
Definition types.hh:46
const FlagsType dist
Print the distribution.
Definition info.hh:65
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
T safe_cast(U &&ref_or_ptr)
Definition cast.hh:74
Tick curTick()
The universal simulation clock.
Definition cur_tick.hh:46
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
std::string htmFailureToStr(HtmFailureFaultCause cause)
Convert enum into string to be used for debug purposes.
Definition htm.cc:44
uint64_t Tick
Tick count type.
Definition types.hh:58
HtmCacheFailure
Definition htm.hh:60
HtmFailureFaultCause
Definition htm.hh:48

Generated on Tue Jun 18 2024 16:24:05 for gem5 by doxygen 1.11.0