memory inconsistencies

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
drizzt

memory inconsistencies

Post by drizzt »

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?!
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:memory inconsistencies

Post by Pype.Clicker »

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 :)
Tim

Re:memory inconsistencies

Post by Tim »

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.
Ozguxxx

Re:memory inconsistencies

Post by Ozguxxx »

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. :)
Tim

Re:memory inconsistencies

Post by Tim »

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.
drizzt

Re:memory inconsistencies

Post by drizzt »

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).
...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)
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 :)
.... 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.

I hope I've understood well... thanks a lot for clarifications pype!!!
drizzt

Re:memory inconsistencies

Post by drizzt »

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.
Yes Tim you're right... but I'll explain my problem better with an example.
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!!!
Tim

Re:memory inconsistencies

Post by Tim »

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.
drizzt

Re:memory inconsistencies

Post by drizzt »

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...
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:memory inconsistencies

Post by Pype.Clicker »

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++;
     }
}
drizzt

Re:memory inconsistencies

Post by drizzt »

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 :)
drizzt

Re:memory inconsistencies

Post by drizzt »

...however the pype solution seems to me conceptually more elegant... (still undecided: :-\ "to be or not to be...")
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:memory inconsistencies

Post by Pype.Clicker »

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.
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 anyway :)

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();
}
The only "advanced" stuff you need is a way to defer some work to the kernel, so that it can safely free your page directory when no code is in that directory anymore.

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.
drizzt

Re:memory inconsistencies

Post by drizzt »

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
Post Reply