sysprog21 / semu

A minimalist RISC-V system emulator capable of running Linux kernel
MIT License
253 stars 47 forks source link

Caching for MMU translations #28

Open onnokort opened 1 year ago

onnokort commented 1 year ago

Here is the proposed MMU caching scheme as discussed also here: https://github.com/sysprog21/semu/issues/26

This is likely not yet final and needs to be discussed. As said, the savings at -O3 are not great, YMMV. If you add extra test delays to RAM access, you can hopefully see that this does as it should.

Given that the MMU logic is one of, if not the most involved parts of the code, I have a couple of questions & doubts about my own code still:

jserv commented 1 year ago

I have noticed that the RISCV MMU spec allows for an even simpler MMU implementation in the single-core case, which does not update any access bits upon lookup. More specifically, I have noticed that if I comment out this part from riscv.c:

if (new_pte != pte)
        *pte_ref = new_pte;

that nothing changes in terms of runtime behaviour (again, did a bit-for-bit check of the output RAM at the end of ~300Mcycles) of the emulator. What gives? Is that to be expected? Is that simply how Linux assumes everything to be if on a single RISCV32 core? If so, is that something that should potentially be conditionally #ifdef-ed out to optimize for single-core use of the emu? I must really admit that I have no great oversight of how it all fits together with the exact Linux MMU accesses yet, I am really a bit out of my depth here at the moment.

Given the current heavily simplified MMU implementation, the page table walker might not even traverse into such cases, so I could potentially use tools like stress-ng to generate memory stressing workloads and determine the necessity. Initially, we should consider leaving some FIXME/TODO comments in the source files. Would you agree?