after process termination, the PGD and its PGTs will be freed
This commit is contained in:
parent
6f23361bf5
commit
54d636d25c
8 changed files with 77 additions and 12 deletions
|
@ -110,6 +110,11 @@ int get_kernel_pgd(task_t* task);
|
|||
*/
|
||||
int get_user_pgd(task_t* task);
|
||||
|
||||
/*
|
||||
* Delete page directory and its page tables
|
||||
*/
|
||||
int drop_pgd(void);
|
||||
|
||||
/*
|
||||
* Change the page permission in the page tables of the current task
|
||||
*/
|
||||
|
|
|
@ -116,6 +116,31 @@ int get_user_pgd(task_t* task)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int drop_pgd(void)
|
||||
{
|
||||
uint32_t i;
|
||||
page_dir_t* pgd = per_core(current_task)->pgd;
|
||||
size_t phy_pgd = virt_to_phys((size_t) pgd);
|
||||
|
||||
if (BUILTIN_EXPECT(pgd == &boot_pgd, 0))
|
||||
return -EINVAL;
|
||||
|
||||
spinlock_lock(per_core(current_task)->pgd_lock);
|
||||
|
||||
for(i=KERNEL_SPACE/(1024*PAGE_SIZE); i<1024; i++)
|
||||
if (pgd->entries[i] & 0xFFFFF000)
|
||||
put_page(pgd->entries[i] & 0xFFFFF000);
|
||||
|
||||
// freeing the page directory
|
||||
put_page(phy_pgd);
|
||||
|
||||
per_core(current_task)->pgd = NULL;
|
||||
|
||||
spinlock_unlock(per_core(current_task)->pgd_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t virt_to_phys(size_t viraddr)
|
||||
{
|
||||
task_t* task = per_core(current_task);
|
||||
|
|
|
@ -34,6 +34,8 @@ extern atomic_int32_t total_available_pages;
|
|||
|
||||
int mmu_init(void);
|
||||
size_t get_pages(uint32_t no_pages);
|
||||
static inline size_t get_page(void) { return get_pages(1); }
|
||||
int put_page(size_t phyaddr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -64,9 +64,12 @@ void NORETURN leave_kernel_task(void);
|
|||
/* by leaving user level task, this function will be called */
|
||||
void NORETURN leave_user_task(void);
|
||||
|
||||
/* system call to terminate a user level task */
|
||||
/* system call to terminate a user level process */
|
||||
void NORETURN sys_exit(int);
|
||||
|
||||
/* system call to create a new child process */
|
||||
int sys_fork(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -68,10 +68,12 @@ int syscall_handler(uint32_t sys_nr, ...)
|
|||
ret = per_core(current_task)->id;
|
||||
break;
|
||||
case __NR_fork:
|
||||
ret = sys_fork();
|
||||
break;
|
||||
case __NR_fstat:
|
||||
default:
|
||||
kputs("invalid system call\n");
|
||||
ret = -EINVAL;
|
||||
ret = -ENOSYS;
|
||||
break;
|
||||
};
|
||||
|
||||
|
|
|
@ -38,8 +38,7 @@ static spinlock_t table_lock = SPINLOCK_INIT;
|
|||
/*
|
||||
* helper function for the assembly code to determine the current task
|
||||
*/
|
||||
task_t* get_current_task(void)
|
||||
{
|
||||
task_t* get_current_task(void) {
|
||||
return per_core(current_task);
|
||||
}
|
||||
|
||||
|
@ -83,6 +82,8 @@ static void NORETURN do_exit(int arg) {
|
|||
|
||||
kprintf("Terminate task: %u, return value %d\n", per_core(current_task)->id, arg);
|
||||
|
||||
wakeup_blocked_tasks(arg);
|
||||
|
||||
//vma_dump(per_core(current_task));
|
||||
spinlock_lock(&(per_core(current_task)->vma_lock));
|
||||
|
||||
|
@ -95,7 +96,8 @@ static void NORETURN do_exit(int arg) {
|
|||
|
||||
spinlock_unlock(&(per_core(current_task)->vma_lock));
|
||||
|
||||
wakeup_blocked_tasks(arg);
|
||||
drop_pgd(); // delete page directory and its page tables
|
||||
|
||||
if (atomic_int32_read(&per_core(current_task)->mem_usage))
|
||||
kprintf("Memory leak! Task %d did not release %d pages\n", per_core(current_task)->id, atomic_int32_read(&per_core(current_task)->mem_usage));
|
||||
per_core(current_task)->status = TASK_FINISHED;
|
||||
|
@ -114,8 +116,7 @@ void NORETURN leave_kernel_task(void) {
|
|||
do_exit(result);
|
||||
}
|
||||
|
||||
void NORETURN sys_exit(int arg)
|
||||
{
|
||||
void NORETURN sys_exit(int arg) {
|
||||
do_exit(arg);
|
||||
}
|
||||
|
||||
|
@ -135,10 +136,14 @@ static int create_task(tid_t* id, entry_point_t ep, void* arg, int user)
|
|||
|
||||
for(i=0; i<MAX_TASKS; i++) {
|
||||
if (task_table[i].status == TASK_INVALID) {
|
||||
if (!user)
|
||||
if (!user) {
|
||||
ret = get_kernel_pgd(task_table+i);
|
||||
else
|
||||
atomic_int32_set(&task_table[i].mem_usage, 0);
|
||||
} else {
|
||||
ret = get_user_pgd(task_table+i);
|
||||
// user-level pgd needs already a page
|
||||
atomic_int32_set(&task_table[i].mem_usage, 1);
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
ret = -ENOMEM;
|
||||
|
@ -147,7 +152,6 @@ static int create_task(tid_t* id, entry_point_t ep, void* arg, int user)
|
|||
|
||||
task_table[i].id = i;
|
||||
task_table[i].status = TASK_READY;
|
||||
atomic_int32_set(&task_table[i].mem_usage, 0);
|
||||
spinlock_init(&task_table[i].vma_lock);
|
||||
task_table[i].vma_list = NULL;
|
||||
memset(task_table[i].mbox, 0x00, sizeof(mailbox_int32_t*)*MAX_TASKS);
|
||||
|
@ -313,6 +317,11 @@ int create_user_task(tid_t* id, size_t sz, const char* fname, int argc, char** a
|
|||
return create_task(id, user_entry, node, 1);
|
||||
}
|
||||
|
||||
int sys_fork(void)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int join_task(tid_t id, int* result)
|
||||
{
|
||||
int32_t tmp;
|
||||
|
|
|
@ -104,7 +104,7 @@ int test_init(void)
|
|||
sem_init(&consuming, 0);
|
||||
mailbox_int32_init(&mbox);
|
||||
|
||||
create_kernel_task(NULL, foo, "Hello from foo1\n");
|
||||
//create_kernel_task(NULL, foo, "Hello from foo1\n");
|
||||
//create_kernel_task(NULL, join_test, NULL);
|
||||
//create_kernel_task(NULL, producer, NULL);
|
||||
//create_kernel_task(NULL, consumer, NULL);
|
||||
|
|
21
mm/memory.c
21
mm/memory.c
|
@ -25,6 +25,7 @@
|
|||
#include <metalsvm/time.h>
|
||||
#include <metalsvm/processor.h>
|
||||
#include <metalsvm/page.h>
|
||||
#include <metalsvm/errno.h>
|
||||
#ifdef CONFIG_MULTIBOOT
|
||||
#include <asm/multiboot.h>
|
||||
#endif
|
||||
|
@ -235,6 +236,25 @@ oom:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int put_page(size_t phyaddr)
|
||||
{
|
||||
uint32_t index = phyaddr / PAGE_SIZE;
|
||||
task_t* task = per_core(current_task);
|
||||
|
||||
if (BUILTIN_EXPECT(!phyaddr, 0))
|
||||
return -EINVAL;
|
||||
|
||||
spinlock_lock(&bitmap_lock);
|
||||
page_clear_mark(index);
|
||||
spinlock_unlock(&bitmap_lock);
|
||||
|
||||
atomic_int32_sub(&total_allocated_pages, 1);
|
||||
atomic_int32_add(&total_available_pages, 1);
|
||||
atomic_int32_sub(&(task->mem_usage), 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* mem_allocation(size_t sz, uint32_t flags)
|
||||
{
|
||||
size_t phyaddr, viraddr;
|
||||
|
@ -273,7 +293,6 @@ void kfree(void* addr, size_t sz)
|
|||
if (sz % PAGE_SIZE)
|
||||
npages++;
|
||||
|
||||
|
||||
spinlock_lock(&bitmap_lock);
|
||||
for(i=0; i<npages; i++) {
|
||||
phyaddr = virt_to_phys((size_t) addr+i*PAGE_SIZE);
|
||||
|
|
Loading…
Add table
Reference in a new issue