Page 1 of 1

Synchronize kernel pages (global resource) across processes

Posted: Sun Apr 22, 2012 6:04 am
by bluemoon
Hi,

My kernel uses plain old 32-bit 2-level paging, and now face an issue:

Adding page
Upon adding new page into global address space, I can synchronize that to other process upon page fault (lazy TLB update). There is no problem.

Removing page
Problem! I may need to loop all the process's PD structure and remove the entry there.

Remapping address into different page
This may happen for example when switching video mode or hardware state changes, but I'm not sure.
Problem! I may need to loop all the process's PD structure and modify the entry there.


To resolve these issue I'm thinking to use PAE. With extra level of directory, all process can refer to the same PDE to put kernel and global resource there.

So, before I do this move, is there any other way to resolve the above issues? How people do before PAE exist?

Re: Synchronize kernel pages (global resource) across proces

Posted: Sun Apr 22, 2012 6:51 am
by gerryg400
One method I have used is to use a version number on the kernel page directory. Whenever the kernel PD is updated increase a 64bit number in the kernel. Whenever you do a context switch, check that the version number of the PD copy in the new process is correct. If it is not, copy the kernel PD to the process and update the process' PD version number.

Re: Synchronize kernel pages (global resource) across proces

Posted: Sun Apr 22, 2012 7:11 am
by serviper
gerryg400 wrote:One method I have used is to use a version number on the kernel page directory. Whenever the kernel PD is updated increase a 64bit number in the kernel. Whenever you do a context switch, check that the version number of the PD copy in the new process is correct. If it is not, copy the kernel PD to the process and update the process' PD version number.
That's a nice solution...Thanks for the idea!

Re: Synchronize kernel pages (global resource) across proces

Posted: Sun Apr 22, 2012 7:11 am
by bluemoon
good idea.

Re: Synchronize kernel pages (global resource) across proces

Posted: Sun Apr 22, 2012 2:23 pm
by egos
It's possible to map page tables for kernel reserved space during initialization, and then to copy their entries into new pagedir when process is forking.

Re: Synchronize kernel pages (global resource) across proces

Posted: Sun Apr 22, 2012 2:49 pm
by TylerH

Re: Synchronize kernel pages (global resource) across proces

Posted: Sun Apr 22, 2012 4:39 pm
by Brendan
Hi,
bluemoon wrote:So, before I do this move, is there any other way to resolve the above issues? How people do before PAE exist?
There's 4 ways that I know of:
  1. Pre-allocate page tables: If page tables are pre-allocated then page directory entries never change and the problem disappears. This is the fastest method. The disadvantage is that (if kernel space is 1 GiB) all the page tables will consume 1 MiB of RAM and you might not actually use half of them, so maybe 512 KiB of RAM gets wasted. This doesn't sound like much for a modern machine that supports PAE, but for older computers that don't support PAE there might only be 8 MiB of RAM and you might be wasting 6.25% of it.
  2. Map all page directories into kernel space: This works and is fairly easy to do. The disadvantage is that you have to compromise between kernel space usage and the maximum number of processes you can support. For example, if you reserve 128 MiB of kernel space for a "sparse array of page directory mappings" then you'd be limited to a maximum of 32768 processes.
  3. Version Number: This is the fastest way of making the actual page directory changes. The disadvantage is that it adds overhead to task switching, and because you don't remember which page directory entries were changed you have to copy all of them during the task switch. For example, if you change one page directory entry, then (if kernel space is 1 GiB) 1 KiB of data would have to be copied for each process, during later task switches.
  4. Journaling: This is like the version numbering; except you keep a journal/log of the last "n" changes. During the task switch you work out how many changes were made ("change_count = current global version - process version"). If "change_count" is zero you do nothing, if "change_count" is less than "n" you make the latest "change_count" changes listed in the journal/log, and if "change_count" is greater than "n" you copy the entire area of the page directory. The disadvantage here is complexity - whether it's worth the hassle or not depends on how often page directory entries are changed.
Also, note that the first 2 methods are the only methods that work if you allow page directory entries that are used by the kernel's code to be changed. Most people don't allow that though.


Cheers,

Brendan