Removed special-case utcb shared page from posix services.

Previously a so-called utcb shared page was used for transfering
data between posix services. This was a special shmat/get/dt case
allocating from its own virtual pool. Now the term utcb is renamed
as a shared page and integrated with the shm* handling routines.

Generic l4 threads will use long-ipc and not this method. Posix
services will continue to communicate on a shared page for now.
	modified:   tasks/libl4/include/l4lib/ipcdefs.h
	modified:   tasks/libl4/src/init.c
	new file:   tasks/libposix/init.c
	modified:   tasks/mm0/include/shm.h
	modified:   tasks/mm0/include/task.h
	deleted:    tasks/mm0/include/utcb.h
	modified:   tasks/mm0/main.c
	modified:   tasks/mm0/src/boot.c
	modified:   tasks/mm0/src/clone.c
	modified:   tasks/mm0/src/execve.c
	modified:   tasks/mm0/src/exit.c
	modified:   tasks/mm0/src/init.c
	modified:   tasks/mm0/src/shm.c
	modified:   tasks/mm0/src/task.c
	deleted:    tasks/mm0/src/utcb.c
	deleted:    tools/l4-qemu
This commit is contained in:
Bahadir Balban
2009-04-22 11:58:58 +03:00
parent 8d82fa5f5e
commit 203f053878
16 changed files with 209 additions and 268 deletions

View File

@@ -5,7 +5,6 @@
*/
#include <boot.h>
#include <mmap.h>
#include <utcb.h>
#include <shm.h>
#include <l4/api/thread.h>
#include <l4lib/arch/syslib.h>
@@ -74,11 +73,12 @@ int boottask_mmap_regions(struct tcb *task, struct vm_file *file)
return (int)mapped;
}
/* Task's utcb */
task->utcb = utcb_new_address();
/* Task's default shared page */
task->shared_page = shm_new_address(DEFAULT_SHPAGE_SIZE/PAGE_SIZE);
/* Create a shared memory segment available for shmat() */
if (IS_ERR(shm = shm_new((key_t)task->utcb, __pfn(DEFAULT_UTCB_SIZE))))
if (IS_ERR(shm = shm_new((key_t)task->shared_page,
__pfn(DEFAULT_SHPAGE_SIZE))))
return (int)shm;
return 0;

View File

@@ -12,7 +12,6 @@
#include <vm_area.h>
#include <task.h>
#include <mmap.h>
#include <utcb.h>
#include <shm.h>
#include <test.h>
#include <clone.h>
@@ -31,7 +30,7 @@ int vfs_notify_fork(struct tcb *child, struct tcb *parent, unsigned int flags)
/* Write parent and child information */
write_mr(L4SYS_ARG0, parent->tid);
write_mr(L4SYS_ARG1, child->tid);
write_mr(L4SYS_ARG2, (unsigned int)child->utcb);
write_mr(L4SYS_ARG2, (unsigned int)child->shared_page);
write_mr(L4SYS_ARG3, flags);
if ((err = l4_sendrecv(VFS_TID, VFS_TID,
@@ -85,8 +84,10 @@ int sys_fork(struct tcb *parent)
BUG();
/* Create and prefault a utcb for child and map it to vfs task */
utcb_map_to_task(child, find_task(VFS_TID),
UTCB_NEW_ADDRESS | UTCB_NEW_SHM | UTCB_PREFAULT);
shpage_map_to_task(child, find_task(VFS_TID),
SHPAGE_NEW_ADDRESS | SHPAGE_NEW_SHM |
SHPAGE_PREFAULT);
// printf("Mapped 0x%p to vfs as utcb of %d\n", child->utcb, child->tid);
/* We can now notify vfs about forked process */
@@ -138,8 +139,9 @@ int do_clone(struct tcb *parent, unsigned long child_stack, unsigned int flags)
BUG();
/* Create and prefault a utcb for child and map it to vfs task */
utcb_map_to_task(child, find_task(VFS_TID),
UTCB_NEW_ADDRESS | UTCB_NEW_SHM | UTCB_PREFAULT);
shpage_map_to_task(child, find_task(VFS_TID),
SHPAGE_NEW_ADDRESS | SHPAGE_NEW_SHM |
SHPAGE_PREFAULT);
/* We can now notify vfs about forked process */
vfs_notify_fork(child, parent, flags);

View File

@@ -37,16 +37,16 @@ int vfs_open_bypath(const char *pathname, unsigned long *vnum, unsigned long *le
return -ESRCH;
/*
* Copy string to vfs utcb.
* Copy string to vfs shared page.
*
* FIXME: There's a chance we're overwriting other tasks'
* ipc information that is on the vfs utcb.
* ipc information that is on the vfs shared page.
*/
strcpy(vfs->utcb, pathname);
strcpy(vfs->shared_page, pathname);
l4_save_ipcregs();
write_mr(L4SYS_ARG0, (unsigned long)vfs->utcb);
write_mr(L4SYS_ARG0, (unsigned long)vfs->shared_page);
if ((err = l4_sendrecv(VFS_TID, VFS_TID,
L4_IPC_TAG_PAGER_OPEN_BYPATH)) < 0) {

View File

@@ -3,9 +3,9 @@
*
* Copyright (C) 2008 Bahadir Balban
*/
#include <shm.h>
#include <task.h>
#include <file.h>
#include <utcb.h>
#include <exit.h>
#include <test.h>
#include <vm_area.h>
@@ -90,7 +90,7 @@ int execve_recycle_task(struct tcb *new, struct tcb *orig)
new->pagerid = orig->pagerid;
/* Copy utcb */
new->utcb = orig->utcb;
new->shared_page = orig->shared_page;
/* Copy parent relationship */
BUG_ON(new->parent);
@@ -131,9 +131,9 @@ void do_exit(struct tcb *task, int status)
/* Tell vfs that task is exiting */
vfs_notify_exit(task, status);
/* Remove utcb shm areas from vfs */
// printf("Unmapping 0x%p from vfs as utcb of %d\n", task->utcb, task->tid);
utcb_unmap_from_task(task, find_task(VFS_TID));
/* Remove default shared page shm areas from vfs */
// printf("Unmapping 0x%p from vfs as shared-page of %d\n", task->shared_page, task->tid);
shpage_unmap_from_task(task, find_task(VFS_TID));
/* Free task's local tcb */
tcb_destroy(task);

View File

@@ -15,7 +15,6 @@
#include <shm.h>
#include <file.h>
#include <init.h>
#include <utcb.h>
#include <test.h>
#include <boot.h>
@@ -168,12 +167,8 @@ void init_mm(struct initdata *initdata)
printf("SHM initialisation failed.\n");
BUG();
}
// printf("%s: Initialised shm structures.\n", __TASKNAME__);
printf("%s: Initialised shm structures.\n", __TASKNAME__);
if (utcb_pool_init() < 0) {
printf("UTCB initialisation failed.\n");
BUG();
}
/* For supplying contiguous virtual addresses to pager */
pager_address_pool_init();

View File

@@ -7,7 +7,6 @@
#include <stdio.h>
#include <task.h>
#include <mmap.h>
#include <utcb.h>
#include <vm_area.h>
#include <globals.h>
#include <lib/malloc.h>
@@ -181,15 +180,8 @@ void shm_destroy_priv_data(struct vm_file *shm_file)
struct shm_descriptor *shm_desc = shm_file_to_desc(shm_file);
/* Release the shared memory address */
if ((unsigned long)shm_desc->shm_addr >= UTCB_AREA_START &&
(unsigned long)shm_desc->shm_addr < UTCB_AREA_END) {
BUG_ON(utcb_delete_address(shm_desc->shm_addr) < 0);
} else if ((unsigned long)shm_desc->shm_addr >= SHM_AREA_START &&
(unsigned long)shm_desc->shm_addr < SHM_AREA_END) {
BUG_ON(shm_delete_address(shm_desc->shm_addr,
shm_file->vm_obj.npages) < 0);
} else
BUG();
BUG_ON(shm_delete_address(shm_desc->shm_addr,
shm_file->vm_obj.npages) < 0);
/* Release the shared memory id */
BUG_ON(id_del(shm_ids, shm_desc->shmid) < 0);
@@ -320,3 +312,76 @@ int sys_shmget(key_t key, int size, int shmflg)
return -ENOENT;
}
/*
* Currently, a default shm page is allocated to every thread in the system
* for efficient ipc communication. This part below provides the allocation
* and mapping of this page using shmat/get/dt call semantics.
*/
/*
* Sends shpage address information to requester. The requester then uses
* this address as a shm key and maps it via shmget/shmat.
*/
void *task_send_shpage_address(struct tcb *sender, l4id_t taskid)
{
struct tcb *task = find_task(taskid);
/* Is the task asking for its own utcb address */
if (sender->tid == taskid) {
/* It hasn't got one allocated. */
BUG_ON(!task->shared_page);
/* Return it to requester */
return task->shared_page;
/* A task is asking for someone else's utcb */
} else {
/* Only vfs is allowed to do so yet, because its a server */
if (sender->tid == VFS_TID) {
/*
* Return shpage address to requester. Note if there's
* none allocated so far, requester gets 0. We don't
* allocate one here.
*/
return task->shared_page;
}
}
return 0;
}
int shpage_map_to_task(struct tcb *owner, struct tcb *mapper, unsigned int flags)
{
struct vm_file *default_shm;
/* Allocate a new utcb address */
if (flags & SHPAGE_NEW_ADDRESS)
owner->shared_page =
shm_new_address(DEFAULT_SHPAGE_SIZE/PAGE_SIZE);
else if (!owner->shared_page)
BUG();
/* Create a new shared memory segment for utcb */
if (flags & SHPAGE_NEW_SHM)
if (IS_ERR(default_shm = shm_new((key_t)owner->shared_page,
__pfn(DEFAULT_SHPAGE_SIZE))))
return (int)default_shm;
/* Map the utcb to mapper */
if (IS_ERR(shmat_shmget_internal(mapper, (key_t)owner->shared_page,
owner->shared_page)))
BUG();
/* Prefault the owner's utcb to mapper's address space */
if (flags & SHPAGE_PREFAULT)
for (int i = 0; i < __pfn(DEFAULT_SHPAGE_SIZE); i++)
prefault_page(mapper, (unsigned long)owner->shared_page +
__pfn_to_addr(i), VM_READ | VM_WRITE);
return 0;
}
int shpage_unmap_from_task(struct tcb *owner, struct tcb *mapper)
{
return sys_shmdt(mapper, owner->shared_page);
}

View File

@@ -24,7 +24,6 @@
#include <vm_area.h>
#include <memory.h>
#include <file.h>
#include <utcb.h>
#include <task.h>
#include <exec.h>
#include <shm.h>
@@ -611,13 +610,13 @@ int vfs_send_task_data(struct tcb *vfs)
}
BUG_ON(!(self = find_task(self_tid())));
BUG_ON(!vfs->utcb);
BUG_ON(!vfs->shared_page);
/* Attach mm0 to vfs's utcb segment just like a normal task */
utcb_map_to_task(vfs, self, UTCB_PREFAULT);
shpage_map_to_task(vfs, self, SHPAGE_PREFAULT);
/* Write all requested task information to utcb's user buffer area */
tdata_head = (struct task_data_head *)vfs->utcb;
/* Write all requested task information to shared pages's user buffer area */
tdata_head = (struct task_data_head *)vfs->shared_page;
/* First word is total number of tcbs */
tdata_head->total = global_tasks.total;
@@ -625,7 +624,7 @@ int vfs_send_task_data(struct tcb *vfs)
/* Write per-task data for all tasks */
list_for_each_entry(t, &global_tasks.list, list) {
tdata_head->tdata[li].tid = t->tid;
tdata_head->tdata[li].utcb_address = (unsigned long)t->utcb;
tdata_head->tdata[li].utcb_address = (unsigned long)t->shared_page;
li++;
}

View File

@@ -1,107 +0,0 @@
/*
* utcb address allocation for user tasks.
*
* Copyright (C) 2008 Bahadir Balban
*/
#include <stdio.h>
#include <utcb.h>
#include <lib/addr.h>
#include <l4/macros.h>
#include <l4lib/arch/syscalls.h>
#include <l4lib/arch/syslib.h>
#include <task.h>
#include <shm.h>
#include <vm_area.h>
#include <syscalls.h>
#include INC_GLUE(memlayout.h)
static struct address_pool utcb_vaddr_pool;
int utcb_pool_init()
{
int err;
if ((err = address_pool_init(&utcb_vaddr_pool,
UTCB_AREA_START,
UTCB_AREA_END)) < 0) {
printf("UTCB address pool initialisation failed: %d\n", err);
return err;
}
return 0;
}
void *utcb_new_address(void)
{
return address_new(&utcb_vaddr_pool, 1);
}
int utcb_delete_address(void *utcb_addr)
{
return address_del(&utcb_vaddr_pool, utcb_addr, 1);
}
/*
* Sends utcb address information to requester task, allocates
* an address if it doesn't exist and the requester is asking
* for its own. The requester then uses this address as a shm key and
* maps its own utcb via shmget/shmat.
*/
void *task_send_utcb_address(struct tcb *sender, l4id_t taskid)
{
struct tcb *task = find_task(taskid);
/* Is the task asking for its own utcb address */
if (sender->tid == taskid) {
/* It hasn't got one allocated. */
BUG_ON(!task->utcb);
/* Return it to requester */
return task->utcb;
/* A task is asking for someone else's utcb */
} else {
/* Only vfs is allowed to do so yet, because its a server */
if (sender->tid == VFS_TID) {
/*
* Return utcb address to requester. Note if there's
* none allocated so far, requester gets 0. We don't
* allocate one here.
*/
return task->utcb;
}
}
return 0;
}
int utcb_map_to_task(struct tcb *owner, struct tcb *mapper, unsigned int flags)
{
struct vm_file *utcb_shm;
/* Allocate a new utcb address */
if (flags & UTCB_NEW_ADDRESS)
owner->utcb = utcb_new_address();
else if (!owner->utcb)
BUG();
/* Create a new shared memory segment for utcb */
if (flags & UTCB_NEW_SHM)
if (IS_ERR(utcb_shm = shm_new((key_t)owner->utcb,
__pfn(DEFAULT_UTCB_SIZE))))
return (int)utcb_shm;
/* Map the utcb to mapper */
if (IS_ERR(shmat_shmget_internal(mapper, (key_t)owner->utcb,
owner->utcb)))
BUG();
/* Prefault the owner's utcb to mapper's address space */
if (flags & UTCB_PREFAULT)
for (int i = 0; i < __pfn(DEFAULT_UTCB_SIZE); i++)
prefault_page(mapper, (unsigned long)owner->utcb +
__pfn_to_addr(i), VM_READ | VM_WRITE);
return 0;
}
int utcb_unmap_from_task(struct tcb *owner, struct tcb *mapper)
{
return sys_shmdt(mapper, owner->utcb);
}