summaryrefslogtreecommitdiff
path: root/src/kern
diff options
context:
space:
mode:
authorJoel Hestness <jthestness@gmail.com>2015-10-10 16:45:38 -0500
committerJoel Hestness <jthestness@gmail.com>2015-10-10 16:45:38 -0500
commit1f2e7c1aaa17e55b06504264e40bde1a000f2214 (patch)
tree087714697f803f238d3507a01e76240fbf696946 /src/kern
parentd3d159749a0a6c3b69a9181fab8db34b6ba0f7a1 (diff)
downloadgem5-1f2e7c1aaa17e55b06504264e40bde1a000f2214.tar.xz
sim: Don't quiesce UDelayEvents with 0 latency
ARM uses UDelayEvents to emulate kernel __*udelay functions and speed up simulation. UDelayEvents call Pseudoinst::quiesceNs to quiesce the system for a specified delay. Changeset 10341:0b4d10f53c2d introduced the requirement that any quiesce process that is started must also be completed by scheduling an EndQuiesceEvent. This change causes the CPU to hang if an IsQuiesce instruction is executed, but the corresponding EndQuiesceEvent is not scheduled. Changeset 11058:d0934b57735a introduces a fix for uses of PseudoInst::quiesce* that would conditionally execute the EndQuiesceEvent. ARM UDelayEvents specify quiesce period of 0 ns (src/arch/arm/linux/system.cc), so changeset 11058 causes these events to now execute full quiesce processes, greatly increasing the total instructions executed in kernel delay loops and slowing simulation. This patch updates the UDelayEvent to conditionally execute PseudoInst::quiesceNs (**a quiesce operation**) only if the specified delay is >0 ns. The result is ARM delay loops no longer execute instructions for quiesce handling, and regression time returns to normal.
Diffstat (limited to 'src/kern')
-rw-r--r--src/kern/freebsd/events.cc8
-rw-r--r--src/kern/linux/events.cc8
2 files changed, 14 insertions, 2 deletions
diff --git a/src/kern/freebsd/events.cc b/src/kern/freebsd/events.cc
index 2f4ceb056..15954d672 100644
--- a/src/kern/freebsd/events.cc
+++ b/src/kern/freebsd/events.cc
@@ -65,7 +65,13 @@ UDelayEvent::process(ThreadContext *tc)
SkipFuncEvent::process(tc);
- PseudoInst::quiesceNs(tc, time);
+ // Currently, only ARM full-system simulation uses UDelayEvents to skip
+ // __delay and __loop_delay functions. One form involves setting quiesce
+ // time to 0 with the assumption that quiesce will not happen. To avoid
+ // the quiesce handling in this case, only execute the quiesce if time > 0.
+ if (time > 0) {
+ PseudoInst::quiesceNs(tc, time);
+ }
}
} // namespace FreeBSD
diff --git a/src/kern/linux/events.cc b/src/kern/linux/events.cc
index c8b53d848..42f058a72 100644
--- a/src/kern/linux/events.cc
+++ b/src/kern/linux/events.cc
@@ -85,7 +85,13 @@ UDelayEvent::process(ThreadContext *tc)
SkipFuncEvent::process(tc);
- PseudoInst::quiesceNs(tc, time);
+ // Currently, only ARM full-system simulation uses UDelayEvents to skip
+ // __delay and __loop_delay functions. One form involves setting quiesce
+ // time to 0 with the assumption that quiesce will not happen. To avoid
+ // the quiesce handling in this case, only execute the quiesce if time > 0.
+ if (time > 0) {
+ PseudoInst::quiesceNs(tc, time);
+ }
}