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 * This file contains the several functions to manage the page tables
*/ */
#include <eduos/tasks_types.h>
#ifndef __PAGE_H__ #ifndef __PAGE_H__
#define __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 Success. Everything went fine.
* @retval <0 Error. Something went wrong. * @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 */ /** @brief Free a whole page map tree */
int page_map_drop(); int page_map_drop();

View file

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

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); kprintf("Terminate task: %u, return value %d\n", curr_task->id, arg);
page_map_drop(); page_map_drop();
curr_task->status = TASK_FINISHED; curr_task->status = TASK_FINISHED;
reschedule(); 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); spinlock_irqsave_init(&task_table[i].page_lock);
atomic_int32_set(&task_table[i].user_usage, 0); atomic_int32_set(&task_table[i].user_usage, 0);
/* Allocated new PGD or PML4 and copy page table */ /* Allocated new PGD or PML4 and copy page table */
size_t map = get_pages(1); task_table[i].page_map = get_pages(1);
if (BUILTIN_EXPECT(!map, 0)) if (BUILTIN_EXPECT(!task_table[i].page_map, 0))
goto out; goto out;
page_map_copy(map); /* Copy page tables & user frames of current task to new one */
task_table[i].page_map = map; page_map_copy(&task_table[i]);
if (id) if (id)
*id = i; *id = i;