sim-se: Handle simultaneous page faults in SE-mode multithreading
authorJiayi Huang <jyhuang91@gmail.com>
Thu, 21 Jan 2021 01:16:49 +0000 (17:16 -0800)
committerJiayi Huang <jyhuang91@gmail.com>
Fri, 22 Jan 2021 15:33:20 +0000 (15:33 +0000)
When running multithreaded programs in SE-mode with DerivO3CPU model,
there are cases that two or more cores have page faults on the same page
in nearby ticks (can be at the same tick) when fetching instructions
(more likely) or accessing data. When these cores try come to the commit
stage in nearby ticks/cycles, they will try to handle the faults
(without clobbering). Then the first core will ask for a physical page
frame to map with the virtual page. In the previous version, the right
next core that tries to handle the fault will hit a panic condition in
the EmulationPageTable::map(...) as the page has been mapped and this
page fault is not to clobber the existing mapping.

In this changeset, if it is found that the page has been mapped and it
is not to clobber the existing mapping, it will return without further
mapping activities as the page fault has been handled previously.

Jira Issue: https://gem5.atlassian.net/browse/GEM5-798

Change-Id: I9bb1163f9d1379c6fed9725101e4400fefdc8079
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/39515
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/sim/process.cc

index 7819820caee3c30f46062b53c982966e0e79b33b..409b48afc0ed7a5028a56a9dcdf5226485858425 100644 (file)
@@ -307,6 +307,21 @@ Process::drain()
 void
 Process::allocateMem(Addr vaddr, int64_t size, bool clobber)
 {
+    // Check if the page has been mapped by other cores if not to clobber.
+    // When running multithreaded programs in SE-mode with DerivO3CPU model,
+    // there are cases where two or more cores have page faults on the same
+    // page in nearby ticks. When the cores try to handle the faults at the
+    // commit stage (also in nearby ticks/cycles), the first core will ask for
+    // a physical page frame to map with the virtual page. Other cores can
+    // return if the page has been mapped and `!clobber`.
+    if (!clobber) {
+        const EmulationPageTable::Entry *pte = pTable->lookup(vaddr);
+        if (pte) {
+            warn("Process::allocateMem: addr %#x already mapped\n", vaddr);
+            return;
+        }
+    }
+
     int npages = divCeil(size, pTable->pageSize());
     Addr paddr = system->allocPhysPages(npages);
     pTable->map(vaddr, paddr, size,