added proper accounting of user used page frames

This commit is contained in:
Steffen Vogel 2014-12-04 21:44:02 +01:00
parent 5c4e1cee4f
commit 42571eb4eb
3 changed files with 18 additions and 10 deletions

View file

@ -33,6 +33,8 @@
* This file contains the several functions to manage the page tables
*/
#include <eduos/tasks_types.h>
#ifndef __PAGE_H__
#define __PAGE_H__
@ -135,7 +137,7 @@ int page_unmap(size_t viraddr, size_t npages);
* @retval 0 Success. Everything went fine.
* @retval <0 Error. Something went wrong.
*/
int page_map_copy(size_t dest);
int page_map_copy(task_t *dest);
/** @brief Free a whole page map tree */
int page_map_drop();

View file

@ -105,6 +105,9 @@ int page_map(size_t viraddr, size_t phyaddr, size_t npages, size_t bits)
if (BUILTIN_EXPECT(!phyaddr, 0))
goto out;
if (bits & PG_USER)
atomic_int32_inc(&current_task->user_usage);
/* Reference the new table within its parent */
self[lvl][vpn] = phyaddr | bits | PG_PRESENT;
@ -158,12 +161,13 @@ int page_map_drop()
void traverse(int lvl, long vpn) {
long stop;
for (stop=vpn+PAGE_MAP_ENTRIES; vpn<stop; vpn++) {
if (self[lvl][vpn] & PG_PRESENT && self[lvl][vpn] & PG_USER) {
if ((self[lvl][vpn] & PG_PRESENT) && (self[lvl][vpn] & PG_USER)) {
/* Post-order traversal */
if (lvl)
traverse(lvl-1, vpn<<PAGE_MAP_BITS);
put_pages(self[lvl][vpn] & PAGE_MASK, 1);
atomic_int32_dec(&current_task->user_usage);
}
}
}
@ -177,7 +181,7 @@ int page_map_drop()
return 0;
}
int page_map_copy(size_t dest)
int page_map_copy(task_t *dest)
{
int traverse(int lvl, long vpn) {
long stop;
@ -188,6 +192,8 @@ int page_map_copy(size_t dest)
if (BUILTIN_EXPECT(!phyaddr, 0))
return -ENOMEM;
atomic_int32_inc(&dest->user_usage);
other[lvl][vpn] = phyaddr | (self[lvl][vpn] & ~PAGE_MASK);
if (lvl) /* PML4, PDPT, PGD */
traverse(lvl-1, vpn<<PAGE_MAP_BITS); /* Pre-order traversal */

View file

@ -122,7 +122,7 @@ static void NORETURN do_exit(int arg)
kprintf("Terminate task: %u, return value %d\n", curr_task->id, arg);
page_map_drop();
page_map_drop();
curr_task->status = TASK_FINISHED;
reschedule();
@ -204,13 +204,13 @@ static int create_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio)
spinlock_irqsave_init(&task_table[i].page_lock);
atomic_int32_set(&task_table[i].user_usage, 0);
/* Allocated new PGD or PML4 and copy page table */
size_t map = get_pages(1);
if (BUILTIN_EXPECT(!map, 0))
goto out;
/* Allocated new PGD or PML4 and copy page table */
task_table[i].page_map = get_pages(1);
if (BUILTIN_EXPECT(!task_table[i].page_map, 0))
goto out;
page_map_copy(map);
task_table[i].page_map = map;
/* Copy page tables & user frames of current task to new one */
page_map_copy(&task_table[i]);
if (id)
*id = i;