@@ -89,87 +89,10 @@ Walker::WalkerStats::WalkerStats(statistics::Group *parent)
8989 statistics::units::Cycle,
9090 statistics::units::Count>::get(),
9191 "Average PTW memory latency",
92- ptwMemCycle / ptwMemCount),
93- ADD_STAT(ptwLevel0ResourceBlocked, statistics::units::Count::get(),
94- "Number of one-stage direct PTW walks blocked by level-0 limit"),
95- ADD_STAT(ptwLevel1ResourceBlocked, statistics::units::Count::get(),
96- "Number of one-stage direct PTW walks blocked by level-1 limit"),
97- ADD_STAT(ptwLevel2ResourceBlocked, statistics::units::Count::get(),
98- "Number of one-stage direct PTW walks blocked by level-2 limit"),
99- ADD_STAT(ptwLevel3ResourceBlocked, statistics::units::Count::get(),
100- "Number of one-stage direct PTW walks blocked by level-3 limit"),
101- ADD_STAT(ptwMissQueueResourceBlocked, statistics::units::Count::get(),
102- "Number of PTW misses enqueued because the target PTW level was busy"),
103- ADD_STAT(ptwMissQueueFifoBlocked, statistics::units::Count::get(),
104- "Number of PTW misses enqueued to preserve MissQueue FIFO order"),
105- ADD_STAT(ptwMissQueueFullBlocked, statistics::units::Count::get(),
106- "Number of PTW misses blocked because MissQueue was full"),
107- ADD_STAT(ptwMissQueueEnqueues, statistics::units::Count::get(),
108- "Number of one-stage direct PTW misses enqueued"),
109- ADD_STAT(ptwMissQueueDequeues, statistics::units::Count::get(),
110- "Number of one-stage direct PTW misses dequeued"),
111- ADD_STAT(ptwMissQueueRequeues, statistics::units::Count::get(),
112- "Number of one-stage direct PTW miss queue head retries"),
113- ADD_STAT(ptwMissQueueAdmissionWaits, statistics::units::Count::get(),
114- "Number of one-stage direct PTW misses waiting for MissQueue space"),
115- ADD_STAT(ptwMissQueueAdmissionRetries, statistics::units::Count::get(),
116- "Number of waiting one-stage direct PTW misses admitted to MissQueue"),
117- ADD_STAT(ptwMissQueueFullEvents, statistics::units::Count::get(),
118- "Number of one-stage direct PTW miss queue full events"),
119- ADD_STAT(ptwMissQueueHintChecks, statistics::units::Count::get(),
120- "Number of MissQueue entries checked by TLB refill hints"),
121- ADD_STAT(ptwMissQueueHintMatches, statistics::units::Count::get(),
122- "Number of MissQueue entries matched by TLB refill hints"),
123- ADD_STAT(ptwMissQueueHintRetries, statistics::units::Count::get(),
124- "Number of MissQueue entries retried by TLB refill hints"),
125- ADD_STAT(ptwMissQueueHintResolved, statistics::units::Count::get(),
126- "Number of hint retried MissQueue entries completed immediately"),
127- ADD_STAT(ptwMissQueueHintDelayed, statistics::units::Count::get(),
128- "Number of hint retried MissQueue entries delayed again"),
129- ADD_STAT(ptwMissQueueHintDirectChecks, statistics::units::Count::get(),
130- "Number of direct refill hint MissQueue checks"),
131- ADD_STAT(ptwMissQueueHintDirectMatches, statistics::units::Count::get(),
132- "Number of direct refill hint MissQueue matches"),
133- ADD_STAT(ptwMissQueueHintDirectRetries, statistics::units::Count::get(),
134- "Number of direct refill hint MissQueue retries"),
135- ADD_STAT(ptwMissQueueHintDirectResolved, statistics::units::Count::get(),
136- "Number of direct refill hint retries completed immediately"),
137- ADD_STAT(ptwMissQueueHintDirectDelayed, statistics::units::Count::get(),
138- "Number of direct refill hint retries delayed again"),
139- ADD_STAT(ptwMissQueueHintAllstageChecks, statistics::units::Count::get(),
140- "Number of all-stage refill hint MissQueue checks"),
141- ADD_STAT(ptwMissQueueHintAllstageMatches, statistics::units::Count::get(),
142- "Number of all-stage refill hint MissQueue matches"),
143- ADD_STAT(ptwMissQueueHintAllstageRetries, statistics::units::Count::get(),
144- "Number of all-stage refill hint MissQueue retries"),
145- ADD_STAT(ptwMissQueueHintAllstageResolved, statistics::units::Count::get(),
146- "Number of all-stage refill hint retries completed immediately"),
147- ADD_STAT(ptwMissQueueHintAllstageDelayed, statistics::units::Count::get(),
148- "Number of all-stage refill hint retries delayed again")
92+ ptwMemCycle / ptwMemCount)
14993{
15094}
15195
152- void
153- Walker::recordPtwLevelBlocked (int level)
154- {
155- switch (level) {
156- case 0 :
157- stats.ptwLevel0ResourceBlocked ++;
158- break ;
159- case 1 :
160- stats.ptwLevel1ResourceBlocked ++;
161- break ;
162- case 2 :
163- stats.ptwLevel2ResourceBlocked ++;
164- break ;
165- case 3 :
166- stats.ptwLevel3ResourceBlocked ++;
167- break ;
168- default :
169- panic (" Invalid PTW level %d\n " , level);
170- }
171- }
172-
17396bool
17497Walker::ptwLevelAvailable (WalkerState *state, int level) const
17598{
@@ -199,10 +122,8 @@ Walker::reservePtwLevel(WalkerState *state, int level)
199122 return true ;
200123
201124 releasePtwLevel (state);
202- if (ptwLevelActive[level] >= ptwLevelLimit[level]) {
203- recordPtwLevelBlocked (level);
125+ if (ptwLevelActive[level] >= ptwLevelLimit[level])
204126 return false ;
205- }
206127
207128 ptwLevelActive[level]++;
208129 state->reservedPtwLevel = level;
@@ -238,16 +159,19 @@ Walker::retryPtwLevelBlockedStates()
238159
239160bool
240161Walker::usePtwLevelLimitForStart (bool from_forward_pre_req,
241- bool from_back_pre_req) const
162+ bool from_back_pre_req,
163+ bool is_prefetch) const
242164{
243- return enablePtwLevelLimit && !from_forward_pre_req && !from_back_pre_req;
165+ return enablePtwLevelLimit && !from_forward_pre_req &&
166+ !from_back_pre_req && !is_prefetch;
244167}
245168
246169bool
247170Walker::canStartPtwLevel (int level, bool from_forward_pre_req,
248- bool from_back_pre_req)
171+ bool from_back_pre_req, bool is_prefetch )
249172{
250- if (!usePtwLevelLimitForStart (from_forward_pre_req, from_back_pre_req))
173+ if (!usePtwLevelLimitForStart (from_forward_pre_req, from_back_pre_req,
174+ is_prefetch))
251175 return true ;
252176
253177 panic_if (level < 0 || level >= static_cast <int >(ptwLevelLimit.size ()),
@@ -257,97 +181,9 @@ Walker::canStartPtwLevel(int level, bool from_forward_pre_req,
257181 if (ptwLevelActive[level] < ptwLevelLimit[level])
258182 return true ;
259183
260- recordPtwLevelBlocked (level);
261184 return false ;
262185}
263186
264- void
265- Walker::recordPtwMissQueueResourceBlocked ()
266- {
267- stats.ptwMissQueueResourceBlocked ++;
268- }
269-
270- void
271- Walker::recordPtwMissQueueFifoBlocked ()
272- {
273- stats.ptwMissQueueFifoBlocked ++;
274- }
275-
276- void
277- Walker::recordPtwMissQueueHintCheck (uint8_t translateMode)
278- {
279- switch (translateMode) {
280- case direct:
281- stats.ptwMissQueueHintDirectChecks ++;
282- break ;
283- case allstage:
284- stats.ptwMissQueueHintAllstageChecks ++;
285- break ;
286- default :
287- break ;
288- }
289- }
290-
291- void
292- Walker::recordPtwMissQueueHintMatch (uint8_t translateMode)
293- {
294- switch (translateMode) {
295- case direct:
296- stats.ptwMissQueueHintDirectMatches ++;
297- break ;
298- case allstage:
299- stats.ptwMissQueueHintAllstageMatches ++;
300- break ;
301- default :
302- break ;
303- }
304- }
305-
306- void
307- Walker::recordPtwMissQueueHintRetry (uint8_t translateMode)
308- {
309- switch (translateMode) {
310- case direct:
311- stats.ptwMissQueueHintDirectRetries ++;
312- break ;
313- case allstage:
314- stats.ptwMissQueueHintAllstageRetries ++;
315- break ;
316- default :
317- break ;
318- }
319- }
320-
321- void
322- Walker::recordPtwMissQueueHintResolved (uint8_t translateMode)
323- {
324- switch (translateMode) {
325- case direct:
326- stats.ptwMissQueueHintDirectResolved ++;
327- break ;
328- case allstage:
329- stats.ptwMissQueueHintAllstageResolved ++;
330- break ;
331- default :
332- break ;
333- }
334- }
335-
336- void
337- Walker::recordPtwMissQueueHintDelayed (uint8_t translateMode)
338- {
339- switch (translateMode) {
340- case direct:
341- stats.ptwMissQueueHintDirectDelayed ++;
342- break ;
343- case allstage:
344- stats.ptwMissQueueHintAllstageDelayed ++;
345- break ;
346- default :
347- break ;
348- }
349- }
350-
351187bool
352188Walker::ptwMissQueueHintMatch (const MissQueueEntry &entry,
353189 const TlbEntry &refill_entry,
@@ -373,31 +209,15 @@ Walker::notifyTlbRefillHint(const TlbEntry &entry, uint8_t translateMode)
373209
374210 if (translateMode == allstage) {
375211 MissQueueEntry mq_entry = ptwMissQueue.front ();
376- stats.ptwMissQueueHintChecks ++;
377- recordPtwMissQueueHintCheck (translateMode);
378212 if (!ptwMissQueueHintMatch (mq_entry, entry, translateMode))
379213 return ;
380214
381215 ptwMissQueue.pop_front ();
382- stats.ptwMissQueueHintMatches ++;
383- recordPtwMissQueueHintMatch (translateMode);
384- stats.ptwMissQueueHintRetries ++;
385- recordPtwMissQueueHintRetry (translateMode);
386216
387217 processingPtwMissQueueHint = true ;
388- bool resolved = tlb->retryTimingPtwMiss (mq_entry.tc ,
389- mq_entry.translation ,
390- mq_entry.req ,
391- mq_entry.mode ,
392- true );
218+ tlb->retryTimingPtwMiss (mq_entry.tc , mq_entry.translation ,
219+ mq_entry.req , mq_entry.mode , true );
393220 processingPtwMissQueueHint = false ;
394- if (resolved) {
395- stats.ptwMissQueueHintResolved ++;
396- recordPtwMissQueueHintResolved (translateMode);
397- } else {
398- stats.ptwMissQueueHintDelayed ++;
399- recordPtwMissQueueHintDelayed (translateMode);
400- }
401221 return ;
402222 }
403223
@@ -408,11 +228,7 @@ Walker::notifyTlbRefillHint(const TlbEntry &entry, uint8_t translateMode)
408228 while (!ptwMissQueue.empty ()) {
409229 MissQueueEntry mq_entry = ptwMissQueue.front ();
410230 ptwMissQueue.pop_front ();
411- stats.ptwMissQueueHintChecks ++;
412- recordPtwMissQueueHintCheck (translateMode);
413231 if (ptwMissQueueHintMatch (mq_entry, entry, translateMode)) {
414- stats.ptwMissQueueHintMatches ++;
415- recordPtwMissQueueHintMatch (translateMode);
416232 matched.push_back (mq_entry);
417233 } else {
418234 remaining.push_back (mq_entry);
@@ -424,20 +240,8 @@ Walker::notifyTlbRefillHint(const TlbEntry &entry, uint8_t translateMode)
424240 while (!matched.empty ()) {
425241 MissQueueEntry mq_entry = matched.front ();
426242 matched.pop_front ();
427- stats.ptwMissQueueHintRetries ++;
428- recordPtwMissQueueHintRetry (translateMode);
429- bool resolved = tlb->retryTimingPtwMiss (mq_entry.tc ,
430- mq_entry.translation ,
431- mq_entry.req ,
432- mq_entry.mode ,
433- true );
434- if (resolved) {
435- stats.ptwMissQueueHintResolved ++;
436- recordPtwMissQueueHintResolved (translateMode);
437- } else {
438- stats.ptwMissQueueHintDelayed ++;
439- recordPtwMissQueueHintDelayed (translateMode);
440- }
243+ tlb->retryTimingPtwMiss (mq_entry.tc , mq_entry.translation ,
244+ mq_entry.req , mq_entry.mode , true );
441245 }
442246
443247 processingPtwMissQueueHint = false ;
@@ -457,10 +261,7 @@ Walker::enqueuePtwMiss(ThreadContext *tc, BaseMMU::Translation *translation,
457261 entry.mode = mode;
458262
459263 if (!front && ptwMissQueue.size () >= ptwMissQueueSize) {
460- stats.ptwMissQueueFullEvents ++;
461- stats.ptwMissQueueFullBlocked ++;
462264 ptwMissQueueWaiters.push_back (entry);
463- stats.ptwMissQueueAdmissionWaits ++;
464265 DPRINTF (PageTableWalker,
465266 " PTW MissQueue full, hold vaddr %#lx waiter size %u\n " ,
466267 req->getVaddr (), ptwMissQueueWaiters.size ());
@@ -473,10 +274,6 @@ Walker::enqueuePtwMiss(ThreadContext *tc, BaseMMU::Translation *translation,
473274 } else {
474275 ptwMissQueue.push_back (entry);
475276 }
476- if (front)
477- stats.ptwMissQueueRequeues ++;
478- else
479- stats.ptwMissQueueEnqueues ++;
480277 DPRINTF (PageTableWalker,
481278 " Enqueue PTW miss vaddr %#lx queue size %u\n " ,
482279 req->getVaddr (), ptwMissQueue.size ());
@@ -493,7 +290,6 @@ Walker::retryPtwMissQueue()
493290 ptwMissQueue.size () < ptwMissQueueSize) {
494291 ptwMissQueue.push_back (ptwMissQueueWaiters.front ());
495292 ptwMissQueueWaiters.pop_front ();
496- stats.ptwMissQueueAdmissionRetries ++;
497293 }
498294 if (ptwMissQueue.empty ())
499295 return ;
@@ -504,7 +300,6 @@ Walker::retryPtwMissQueue()
504300 ptwMissQueueHeadRequeued = false ;
505301 MissQueueEntry entry = ptwMissQueue.front ();
506302 ptwMissQueue.pop_front ();
507- stats.ptwMissQueueDequeues ++;
508303 DPRINTF (PageTableWalker,
509304 " Dequeue PTW miss vaddr %#lx queue size %u\n " ,
510305 entry.req ->getVaddr (), ptwMissQueue.size ());
@@ -516,7 +311,6 @@ Walker::retryPtwMissQueue()
516311 ptwMissQueue.size () < ptwMissQueueSize) {
517312 ptwMissQueue.push_back (ptwMissQueueWaiters.front ());
518313 ptwMissQueueWaiters.pop_front ();
519- stats.ptwMissQueueAdmissionRetries ++;
520314 }
521315 }
522316 retryingPtwMissQueue = false ;
@@ -2045,7 +1839,8 @@ Walker::WalkerState::usePtwLevelLimit() const
20451839{
20461840 return timing && (translateMode == defaultmode ||
20471841 translateMode == twoStageMode) &&
2048- !fromPre && !fromBackPre;
1842+ !fromPre && !fromBackPre &&
1843+ mainReq && !mainReq->isPrefetch ();
20491844}
20501845
20511846int
0 commit comments