Hi,
irvanherz wrote:
When system initialized and run its first init program, some high memory address had mapped. For example 0x80000000 - 0x80100000.
Then init execute its child processes, say process A, B, C,..., X. All process have mapped system address space equally.
What if X tries to load more kernel module? And now kernel mapping for X will grow till 0x80900000.
How each process (A,B,C,...,Y) adapt with newly mapped address space : 0x80100000 - 0x80900000?
I think, setting up higher half PDE at startup is inefficient. Especially for system that implements PAE.
For paging; the highest level paging structure (e.g. the Page Directory Pointer Table for PAE) must be different for different virtual address spaces/processes; but one (or more) of the second highest level paging structures (e.g. a Page Directory for PAE) can be used in all virtual address spaces, so that all lower level paging structures (e.g. Page Tables and Pages) used by it end up being global, and so any change made within the area effected by the second highest level paging structure is global.
Essentially; for PAE the second highest level paging structure (a Page Directory) effects 1 GiB of virtual space; which means that (for 2 GiB of "kernel space") you can pre-allocate 2 Page Directories during boot and use them in all virtual address spaces (in all Page Directory Pointer Tables) and any change made to kernel space from any virtual address space will automatically effect all virtual address spaces.
For long mode, the second highest level paging structure (a Page Directory Pointer Table) effects 512 GiB of virtual space; which is why a lot of operating systems use 512 GiB of kernel space in long mode.
For "plain 32-bit paging", the second highest level paging structure (a Page Table) only effects 4 MiB of virtual space; which means that (for 2 GiB of kernel space) you'd have to pre-allocate 512 Page Tables during boot. This isn't as nice (and will cost 2 MiB regardless of whether it's actually used or not).
Also note that (even for PAE where it could work very nicely) there may be other things that need to be taken into account. For example, if you decide to use paging to create a 32 MiB "CPU specific" area in kernel space (where that area is different for each different CPU) then the larger 1 GiB of space that contains that 32 MiB area can't be global.
For cases where you can't or don't use "global second highest level paging structure", you need an alternative. The simplest alternative is to map the highest (and/or second highest) level paging structure/s into kernel space as if they're normal pages. For example; for "plain 32-bit paging" you could have something like an array of Page Directories with one entry per virtual address space/process; then when you need to make a global change (e.g. add or remove a page table in kernel space) you'd do a "for each virtual address space { make change using the mapping }" loop.
More complex alternatives are possible. For example; you could have an authoritative copy in kernel space somewhere (e.g. in kernel's ".bss") and use version numbering; where you change the authoritative copy and do "authoritativeVersion++;" and then update each process that's currently running on each CPU (and don't bother updating processes that aren't currently running); and then during task switches you can do "if(process.kernelSpaceVersion != authoritativeVersion) { copy authoritative copy into this virtual address space; process.kernelSpaceVersion = authoritativeVersion;}".
The most complex (and possibly the fastest) alternative I've heard of is to combine "authoritative copy and versioning" with journaling. Essentially; you'd have a relatively small circular buffer of entries that describe what changed from one version to the next (the journal); and when you update a virtual address space from a "recent enough" version to the current version you only copy whatever is necessary from the authoritative copy (and don't have to copy everything from the authoritative copy). Of course if the virtual address space is too old (e.g. if the journal has 32 entries but the virtual address space needs more than 32 changes) you'd fall back to copying everything from the authoritative copy.
Cheers,
Brendan