From 260527c0a337a41f0b83a9ba9f874d9bbdc594e8 Mon Sep 17 00:00:00 2001 From: Bahadir Balban Date: Fri, 1 May 2009 17:06:24 +0300 Subject: [PATCH] Added utcb create/destroy and better reorganized calls to them. --- tasks/mm0/include/lib/idpool.h | 1 + tasks/mm0/src/exit.c | 11 +++--- tasks/mm0/src/lib/idpool.c | 8 +++++ tasks/mm0/src/task.c | 33 ++++++++++++----- tasks/mm0/src/utcb.c | 65 +++++++++++++++++++++++++++++++--- 5 files changed, 101 insertions(+), 17 deletions(-) diff --git a/tasks/mm0/include/lib/idpool.h b/tasks/mm0/include/lib/idpool.h index bdb384f..b66424f 100644 --- a/tasks/mm0/include/lib/idpool.h +++ b/tasks/mm0/include/lib/idpool.h @@ -14,6 +14,7 @@ struct id_pool *id_pool_new_init(int mapsize); int id_new(struct id_pool *pool); int id_del(struct id_pool *pool, int id); int id_get(struct id_pool *pool, int id); +int id_is_empty(struct id_pool *pool); int ids_new_contiguous(struct id_pool *pool, int numids); int ids_del_contiguous(struct id_pool *pool, int first, int numids); diff --git a/tasks/mm0/src/exit.c b/tasks/mm0/src/exit.c index 580eef7..a0e7d20 100644 --- a/tasks/mm0/src/exit.c +++ b/tasks/mm0/src/exit.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -92,10 +93,6 @@ int execve_recycle_task(struct tcb *new, struct tcb *orig) /* Copy shared page */ new->shared_page = orig->shared_page; - /* Copy utcb descriptors and unique utcb */ - new->utcb_head = orig->utcb_head; - new->utcb_address = orig->utcb_address; - /* Copy parent relationship */ BUG_ON(new->parent); new->parent = orig->parent; @@ -104,6 +101,9 @@ int execve_recycle_task(struct tcb *new, struct tcb *orig) /* Flush all IO on task's files and close fds */ task_close_files(orig); + /* Destroy task's utcb slot */ + task_destroy_utcb(orig); + /* Vfs still knows the thread */ /* Keep the shared page on vfs */ @@ -132,6 +132,9 @@ void do_exit(struct tcb *task, int status) /* Flush all IO on task's files and close fds */ task_close_files(task); + /* Destroy task's utcb slot */ + task_destroy_utcb(task); + /* Tell vfs that task is exiting */ vfs_notify_exit(task, status); diff --git a/tasks/mm0/src/lib/idpool.c b/tasks/mm0/src/lib/idpool.c index d225cc8..9d1f3df 100644 --- a/tasks/mm0/src/lib/idpool.c +++ b/tasks/mm0/src/lib/idpool.c @@ -78,3 +78,11 @@ int id_get(struct id_pool *pool, int id) return id; } +int id_is_empty(struct id_pool *pool) +{ + for (int i = 0; i < pool->nwords; i++) + if (pool->bitmap[i]) + return 0; + return 1; +} + diff --git a/tasks/mm0/src/task.c b/tasks/mm0/src/task.c index 72c3286..17d1f05 100644 --- a/tasks/mm0/src/task.c +++ b/tasks/mm0/src/task.c @@ -7,29 +7,32 @@ #include #include #include +#include #include #include #include #include INC_GLUE(memory.h) + #include #include #include #include #include -#include + #include #include + #include #include #include #include +#include #include #include #include #include #include #include -#include #include #include @@ -150,6 +153,17 @@ int task_free_resources(struct tcb *task) kfree(task->vm_area_head); } + /* + * Threads may share utcb chain + */ + if (!(--task->utcb_head->tcb_refs)) { + /* UTCBs must have been deleted explicitly */ + BUG_ON(!list_empty(&task->utcb_head->list)); + + /* Free the head */ + kfree(task->utcb_head); + } + return 0; } @@ -269,9 +283,6 @@ int copy_tcb(struct tcb *to, struct tcb *from, unsigned int flags) */ } - /* Set up a new utcb for new thread */ - task_setup_utcb(to); - /* Copy all file descriptors */ if (flags & TCB_SHARED_FILES) { to->files = from->files; @@ -336,6 +347,10 @@ struct tcb *task_create(struct tcb *parent, struct task_ids *ids, if (parent) { copy_tcb(task, parent, share_flags); + /* Set up a new utcb for new thread */ + task_setup_utcb(task); + + /* Set up parent-child relationship */ if ((share_flags & TCB_SHARED_PARENT) || (share_flags & TCB_SHARED_TGROUP)) { @@ -557,10 +572,12 @@ int task_mmap_segments(struct tcb *task, struct vm_file *file, struct exec_file_ return err; } + /* Get a new utcb slot for new task */ + task_setup_utcb(task); + /* - * Task already has recycled task's shared page. It will attach to it - * when it starts in userspace. Task also already utilizes recycled - * task's utcb. + * Recycled task's shared page shm still exists. Current task will + * attach to it when it starts in userspace. */ //if (IS_ERR(shm = shm_new((key_t)task->utcb, __pfn(DEFAULT_UTCB_SIZE)))) // return (int)shm; diff --git a/tasks/mm0/src/utcb.c b/tasks/mm0/src/utcb.c index 041130f..6f11f43 100644 --- a/tasks/mm0/src/utcb.c +++ b/tasks/mm0/src/utcb.c @@ -42,7 +42,7 @@ int utcb_delete_address(void *utcb_address, int npages) } /* Return an empty utcb slot in this descriptor */ -unsigned long utcb_slot(struct utcb_desc *desc) +unsigned long utcb_new_slot(struct utcb_desc *desc) { int slot; @@ -52,6 +52,13 @@ unsigned long utcb_slot(struct utcb_desc *desc) return desc->utcb_base + (unsigned long)slot * UTCB_SIZE; } +int utcb_delete_slot(struct utcb_desc *desc, unsigned long address) +{ + BUG_ON(id_del(desc->slots, (address - desc->utcb_base) + / UTCB_SIZE) < 0); + return 0; +} + unsigned long task_new_utcb_desc(struct tcb *task) { struct utcb_desc *d; @@ -69,13 +76,31 @@ unsigned long task_new_utcb_desc(struct tcb *task) d->slots = id_pool_new_init(PAGE_SIZE / UTCB_SIZE); /* Obtain a new and unique utcb base */ + /* FIXME: Use variable size than a page */ d->utcb_base = (unsigned long)utcb_new_address(1); /* Add descriptor to tcb's chain */ list_add(&d->list, &task->utcb_head->list); /* Obtain and return first slot */ - return d->utcb_base + UTCB_SIZE * id_new(d->slots); + return utcb_new_slot(d); +} + +int task_delete_utcb_desc(struct tcb *task, struct utcb_desc *d) +{ + /* Unlink desc from its list */ + list_del_init(&d->list); + + /* Unmap the descriptor region */ + do_munmap(task, d->utcb_base, 1); + + /* Return descriptor address */ + utcb_delete_address((void *)d->utcb_base, 1); + + /* Free the descriptor */ + kfree(d); + + return 0; } /* @@ -102,7 +127,7 @@ int task_setup_utcb(struct tcb *task) /* Search for an empty utcb slot already allocated to this space */ list_for_each_entry(udesc, &task->utcb_head->list, list) - if ((slot = utcb_slot(udesc))) + if ((slot = utcb_new_slot(udesc))) goto out; /* Allocate a new utcb memory region and return its base */ @@ -118,12 +143,42 @@ out: printf("UTCB: mmapping failed with %d\n", err); return (int)err; } - } else - printf("UTCB at 0x%x already mapped.\n", slot); + } /* Assign task's utcb address */ task->utcb_address = slot; + printf("UTCB at 0x%x.\n", slot); return 0; } +/* + * Deletes a utcb slot by first deleting the slot entry, the descriptor + * address if emptied, the mapping of the descriptor, and the descriptor itself + */ +int task_destroy_utcb(struct tcb *task) +{ + struct utcb_desc *udesc; + + printf("UTCB: Destroying 0x%x\n", task->utcb_address); + + /* Find the utcb descriptor slot first */ + list_for_each_entry(udesc, &task->utcb_head->list, list) { + /* FIXME: Use variable alignment than a page */ + /* Detect matching slot */ + if (page_align(task->utcb_address) == udesc->utcb_base) { + + /* Delete slot from the descriptor */ + utcb_delete_slot(udesc, task->utcb_address); + + /* Is the desc completely empty now? */ + if (id_is_empty(udesc->slots)) + /* Delete the descriptor */ + task_delete_utcb_desc(task, udesc); + return 0; /* Finished */ + } + } + BUG(); +} + +