memory inconsistencies
memory inconsistencies
Another problem about allocation (uff!).
We suppose to map the kernel in every process address space. Every process has its page directory and page tables.
To share the kernel address space I link every process PDE with the kernel page tables.
But what happens when kernel modifies its page map, for example when it allocates or deallocates some memory?!
I think it should update every process page directory, to obviate some inconsistencies between other page directory, but it could take a lot of time?! and a lot of confused code :'(
Are there better solutions?!
We suppose to map the kernel in every process address space. Every process has its page directory and page tables.
To share the kernel address space I link every process PDE with the kernel page tables.
But what happens when kernel modifies its page map, for example when it allocates or deallocates some memory?!
I think it should update every process page directory, to obviate some inconsistencies between other page directory, but it could take a lot of time?! and a lot of confused code :'(
Are there better solutions?!
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:memory inconsistencies
Well, if you just map the kernel directories in every process, then all you have to do is to keep directories up to date, and never touch to the PDE mapping the kernel (they'll be allocated statically).
Another option is to provide a Master Page Directory which is always up to date for the kernel and give it a "version number" (operations count). When you switch to another process, check it's own directory has the same version as the Master Page Directory. If not, update it
Another option is to provide a Master Page Directory which is always up to date for the kernel and give it a "version number" (operations count). When you switch to another process, check it's own directory has the same version as the Master Page Directory. If not, update it
Re:memory inconsistencies
If each process's page directory uses the kernel's page tables for the kernel region then the problem becomes less. That is, each process shares the same kernel page tables. Then most kernel allocations will apply automatically to all processes. It's only when you map a whole new page table that you need to update other processes, and you can do that whenever you see a page fault in the kernel region.
Re:memory inconsistencies
Hi drizzt, I am also confused with nearly same problem I did not want to create another thread because my question is similar to yours. My question is: Are page tables always in memory? Or can they be swapped out? I think it is not possible to swap them out because their usage is performed by mpu based on physical addressing right? So if they are swapped out then mpu should find the virtual address and then give a page fault right? Or am i confusing somewhere? thanx... to you drizzt.
Re:memory inconsistencies
You can swap them out no problem. The CPU will give a page fault if either the page table is not present or the page table entry is not present. In your page fault handler, you can check whether the page table associated with the virtual address is present; if not, you can rebuild the page table based on the VMM's internal structures (or just load it from disk) and continue.
Re:memory inconsistencies
...but in this case I must map every page directory into the kernel address space, as a global shared area... when the kernel ask for some memory and need new page tables, one or more page directory entries are updated and a new page tables are allocated... then I must update not only the current page directory but every processes' page directory (mapped as global vars)Well, if you just map the kernel directories in every process, then all you have to do is to keep directories up to date, and never touch to the PDE mapping the kernel (they'll be allocated statically).
.... this solution seems to me better... I think I'll adopt this one. In this case only the Master Page Directory is shared with every other process, when the task switch occurs I simply update the current page directory according to the MPD.Another option is to provide a Master Page Directory which is always up to date for the kernel and give it a "version number" (operations count). When you switch to another process, check it's own directory has the same version as the Master Page Directory. If not, update it
I hope I've understood well... thanks a lot for clarifications pype!!!
Re:memory inconsistencies
Yes Tim you're right... but I'll explain my problem better with an example.Tim Robinson wrote: If each process's page directory uses the kernel's page tables for the kernel region then the problem becomes less. That is, each process shares the same kernel page tables. Then most kernel allocations will apply automatically to all processes. It's only when you map a whole new page table that you need to update other processes, and you can do that whenever you see a page fault in the kernel region.
Suppose that a process is running... It perform a syscall and the control is passed to the kernel (shared in the process address space, so there are no task switches). Now the kernel deallocates a page table for some reasons... and sets the correspondent PDE to a NULL value. Then a task switch occurs, and a new page directory is loaded in the cr3 register... but the new task doesn't know that the previous PDE has been set to NULL if I don't update its page directory... so if it tries to read/write into this area it does't perform a page fault... simply nobody knows what happens... probably I'm wrong.. but I don't see a way to resolve this problem in the page fault handler... however thanks a lot to you Tim!!!
Re:memory inconsistencies
Then every time you need to unmap a page table in the kernel region you scan all process page directories and unmap the page table there. It's not difficult, and unmapping an entire 4MB should happen rarely enough that it makes little impact.
Re:memory inconsistencies
mmm... Tim your solution takes more kernel memory (to map into the kernel space every page directory), but it takes less time than the solution to update the current page directory with a master page dir every time the control is passed to the kernel (probably you have reason)...
well... I'm still undecided...
well... I'm still undecided...
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:memory inconsistencies
Another possible improvement for the "Master Page" scheme would be to give each version a "modified index" to know which entry has been update, and only copy that entry...
Code: Select all
on address-space entry do {
while(version<master.version) {
index=master.update(version);
table[index]=master.table[index];
version++;
}
}
Re:memory inconsistencies
Another point to the page directories mapped into the kernel space:
When a task is killed I'd like to free the memory occupied by it: stacks, TSS, some task's global variables... and also its page tables & page directory. But if a task can see only its page dir, it is difficult for me to free the physical frame associated by the page directory itself...
I would have to:
- temporary map the current page dir into the kernel space,
- switch to another task address space (still remaining into the kernel code),
- free the physical frame associated with the task's page dir,
- unmap the temporary mapped page dir.
If page directories are mapped into the kernel address space I have to:
- switch to another task address space (still remaining into the kernel code),
- free the page directory associated with the killed task.
In both solutions sooner or later I have to map the page directories into the kernel address space... So if I map every page dirs at once I think I can gain a lot of time... and simplify my code
When a task is killed I'd like to free the memory occupied by it: stacks, TSS, some task's global variables... and also its page tables & page directory. But if a task can see only its page dir, it is difficult for me to free the physical frame associated by the page directory itself...
I would have to:
- temporary map the current page dir into the kernel space,
- switch to another task address space (still remaining into the kernel code),
- free the physical frame associated with the task's page dir,
- unmap the temporary mapped page dir.
If page directories are mapped into the kernel address space I have to:
- switch to another task address space (still remaining into the kernel code),
- free the page directory associated with the killed task.
In both solutions sooner or later I have to map the page directories into the kernel address space... So if I map every page dirs at once I think I can gain a lot of time... and simplify my code
Re:memory inconsistencies
...however the pype solution seems to me conceptually more elegant... (still undecided: :-\ "to be or not to be...")
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:memory inconsistencies
I think you can make it easier. Note that you don't need to unmap anything that lies in the kernel range (as it is mapped everywhere anywayI would have to:
- temporary map the current page dir into the kernel space,
- switch to another task address space (still remaining into the kernel code),
- free the physical frame associated with the task's page dir,
- unmap the temporary mapped page dir.
Code: Select all
killAddressSpace(<kernel mode>) {
foreach pde in CurrentDirectory.list() {
if (!pde.belongsKernel() && !pde.isPageDirectory())
Pager.free_frame(pde.frame);
}
Scheduler.enterCritical();
Pager.sendMessage(DELAYED_FREEFRAME, CurrentDirectory.frame);
ProcessManager.sendMessage(DELAYED_KILLPROCESS,pid);
Scheduler.dropTask();
}
In Clicker, this is done by the "process manager" thread, which runs in microkernel area only. In a monolithic system, it could be a thread from /sbin/init, /sbin/kpagerd, or whatever. The only important thing is that it continues running when there are no more processes (it must not be bound to a specific thread). It could also be a function call by the scheduler: when a task gets reactivated, the kernel check it has no pending operations before it resumes the task's activities.
Re:memory inconsistencies
good! this is very easier... I think I've understood. There's no reason to map/unmap the page dir, simply I can add the frame to the free frames stack (or list, or bitmap, etc.) and drop the current task.
Many thanks pype!!! ;D
Many thanks pype!!! ;D