Skip to content

Commit 7c559ea

Browse files
author
qianbaiquan
committed
arch-riscv: Refine PTW level limit handling
Skip PTW level limiting for prefetch requests. Keep the branch conflict resolution on the current xs-dev base. Remove temporary PTW level and MissQueue profiling stats.
1 parent 4e4e6da commit 7c559ea

3 files changed

Lines changed: 29 additions & 271 deletions

File tree

src/arch/riscv/pagetable_walker.cc

Lines changed: 15 additions & 220 deletions
Original file line numberDiff line numberDiff line change
@@ -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-
17396
bool
17497
Walker::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

239160
bool
240161
Walker::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

246169
bool
247170
Walker::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-
351187
bool
352188
Walker::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

20511846
int

0 commit comments

Comments
 (0)