From d9bc7858eda852d1fc5f1c9aaea75258e8cfc6d4 Mon Sep 17 00:00:00 2001 From: Jiayi Huang Date: Wed, 20 Jan 2021 17:16:49 -0800 Subject: [PATCH] sim-se: Handle simultaneous page faults in SE-mode multithreading 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 Maintainer: Jason Lowe-Power Tested-by: kokoro --- src/sim/process.cc | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/sim/process.cc b/src/sim/process.cc index 7819820ca..409b48afc 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -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, -- 2.30.2