From 117e3482b6c8b4402c5425f50fcd48dbfc199075 Mon Sep 17 00:00:00 2001 From: Bahadir Balban Date: Sat, 22 Aug 2009 23:41:53 +0300 Subject: [PATCH] Capabilities for quantitative resources working. Status: - Capability initialization is a bit hacky with dummy current etc. - All container caps belong to the pager - Tasks refer to their pager's capabilities for mutex allocation - Hacky. - Kernel container keeps quantitative caps and memory caps in separate lists - Hacky. These will all evolve and get fixed. --- include/l4/generic/cap-types.h | 2 +- include/l4/generic/resource.h | 3 +- include/l4/generic/tcb.h | 1 - src/generic/capability.c | 5 ++- src/generic/container.c | 34 ++++++----------- src/generic/resource.c | 67 +++++++++++++++++++++++++--------- src/generic/tcb.c | 20 ---------- 7 files changed, 66 insertions(+), 66 deletions(-) diff --git a/include/l4/generic/cap-types.h b/include/l4/generic/cap-types.h index 944057c..692ae92 100644 --- a/include/l4/generic/cap-types.h +++ b/include/l4/generic/cap-types.h @@ -26,7 +26,7 @@ #define CAP_RTYPE_TGROUP (1 << 17) #define CAP_RTYPE_SPACE (1 << 18) #define CAP_RTYPE_CONTAINER (1 << 19) -#define CAP_RTYPE_UMUTEX (1 << 20) +#define CAP_RTYPE_UMUTEX (1 << 20) /* Don't mix with pool version */ #define CAP_RTYPE_VIRTMEM (1 << 21) #define CAP_RTYPE_PHYSMEM (1 << 22) #define CAP_RTYPE_CPUPOOL (1 << 23) diff --git a/include/l4/generic/resource.h b/include/l4/generic/resource.h index 8a40378..0f5f5d2 100644 --- a/include/l4/generic/resource.h +++ b/include/l4/generic/resource.h @@ -25,7 +25,6 @@ struct boot_resources { /* Kernel resource usage */ int nkpmds; int nkpgds; - int nkmemcaps; int nkcaps; }; @@ -73,7 +72,7 @@ struct kernel_container { struct cap_list devmem_free; /* All other caps that belong to the kernel */ - struct cap_list other_caps; + struct cap_list non_memory_caps; struct mem_cache *pgd_cache; struct mem_cache *pmd_cache; diff --git a/include/l4/generic/tcb.h b/include/l4/generic/tcb.h index 8f3dd46..8428dc9 100644 --- a/include/l4/generic/tcb.h +++ b/include/l4/generic/tcb.h @@ -158,7 +158,6 @@ void tcb_remove(struct ktcb *tcb); void tcb_init(struct ktcb *tcb); struct ktcb *tcb_alloc_init(void); -struct ktcb *tcb_alloc_init_use_capability(struct capability *cap); void tcb_delete(struct ktcb *tcb); void init_ktcb_list(struct ktcb_list *ktcb_list); diff --git a/src/generic/capability.c b/src/generic/capability.c index 64e61ac..24e226f 100644 --- a/src/generic/capability.c +++ b/src/generic/capability.c @@ -41,8 +41,9 @@ int capability_consume(struct capability *cap, int quantity) { if (cap->size < cap->used + quantity) return -ENOCAP; - else - cap->used += quantity; + + cap->used += quantity; + return 0; } diff --git a/src/generic/container.c b/src/generic/container.c index 535f2a9..b719fc3 100644 --- a/src/generic/container.c +++ b/src/generic/container.c @@ -256,17 +256,6 @@ int init_first_pager(struct pager *pager, { struct ktcb *task; struct address_space *space; - struct capability *ktcb_cap; - - /* - * Find capability from pager's list, since - * there is no ktcb, no standard path to check - * per-task capability list yet. - */ - ktcb_cap = capability_find_by_rtype(&pager->cap_list, - CAP_RTYPE_THREADPOOL); - /* Use it to allocate ktcb */ - task = tcb_alloc_init_use_capability(ktcb_cap); /* * Initialize dummy current capability list pointer @@ -274,6 +263,14 @@ int init_first_pager(struct pager *pager, */ current->cap_list_ptr = &pager->cap_list; + /* + * Find capability from pager's list, since + * there is no ktcb, no standard path to check + * per-task capability list yet. + */ + /* Use it to allocate ktcb */ + task = tcb_alloc_init(); + /* Initialize ktcb */ task_init_registers(task, pager->start_vma); task_setup_utcb(task, pager); @@ -331,18 +328,6 @@ int init_first_pager(struct pager *pager, int init_pager(struct pager *pager, struct container *cont) { struct ktcb *task; - struct capability *ktcb_cap; - - /* - * Find capability from pager's list, since - * there is no ktcb, no standard path to check - * per-task capability list yet. - */ - ktcb_cap = capability_find_by_rtype(&pager->cap_list, - CAP_RTYPE_THREADPOOL); - - /* Use it to allocate ktcb */ - task = tcb_alloc_init_use_capability(ktcb_cap); /* * Initialize dummy current capability list pointer @@ -350,6 +335,9 @@ int init_pager(struct pager *pager, struct container *cont) */ current->cap_list_ptr = &pager->cap_list; + /* Use it to allocate ktcb */ + task = tcb_alloc_init(); + task_init_registers(task, pager->start_vma); task_setup_utcb(task, pager); diff --git a/src/generic/resource.c b/src/generic/resource.c index b8a4ed5..881cec2 100644 --- a/src/generic/resource.c +++ b/src/generic/resource.c @@ -103,8 +103,8 @@ struct mutex_queue *alloc_user_mutex(void) { struct capability *cap; - if (!(cap = capability_find_by_rtype(current->cap_list_ptr, - CAP_RTYPE_UMUTEX))) + if (!(cap = capability_find_by_rtype(current->pager->tcb->cap_list_ptr, + CAP_RTYPE_MUTEXPOOL))) return 0; if (capability_consume(cap, 1) < 0) @@ -171,8 +171,8 @@ void free_user_mutex(void *addr) { struct capability *cap; - BUG_ON(!(cap = capability_find_by_rtype(current->cap_list_ptr, - CAP_RTYPE_UMUTEX))); + BUG_ON(!(cap = capability_find_by_rtype(current->pager->tcb->cap_list_ptr, + CAP_RTYPE_MUTEXPOOL))); capability_free(cap, 1); BUG_ON(mem_cache_free(kernel_container.mutex_cache, addr) < 0); @@ -372,7 +372,7 @@ void init_kernel_container(struct kernel_container *kcont) cap_list_init(&kcont->virtmem_free); cap_list_init(&kcont->devmem_used); cap_list_init(&kcont->devmem_free); - cap_list_init(&kcont->other_caps); + cap_list_init(&kcont->non_memory_caps); /* Set up total physical memory as single capability */ physmem = alloc_bootmem(sizeof(*physmem), 0); @@ -502,6 +502,7 @@ void setup_containers(struct boot_resources *bootres, * since we want to avoid allocating an uncertain * amount of memory from the boot allocators. */ + current_pgd = realloc_page_tables(); /* Create all containers but leave pagers */ for (int i = 0; i < bootres->nconts; i++) { @@ -514,7 +515,6 @@ void setup_containers(struct boot_resources *bootres, /* Add it to kernel container list */ kcont_insert_container(container, kcont); } - current_pgd = realloc_page_tables(); /* Initialize pagers */ container_init_pagers(kcont, current_pgd); @@ -559,6 +559,31 @@ void copy_boot_capabilities(struct cap_list *caplist) void kcont_setup_capabilities(struct boot_resources *bootres, struct kernel_container *kcont) { + struct capability *cap; + + /* First initialize the list of non-memory capabilities */ + cap = boot_capability_create(); + cap->type = CAP_TYPE_QUANTITY | CAP_RTYPE_MAPPOOL; + cap->size = bootres->nkpmds; + cap->owner = kcont->cid; + cap_list_insert(cap, &kcont->non_memory_caps); + + cap = boot_capability_create(); + cap->type = CAP_TYPE_QUANTITY | CAP_RTYPE_SPACEPOOL; + cap->size = bootres->nkpgds; + cap->owner = kcont->cid; + cap_list_insert(cap, &kcont->non_memory_caps); + + cap = boot_capability_create(); + cap->type = CAP_TYPE_QUANTITY | CAP_RTYPE_CAPPOOL; + cap->size = bootres->nkcaps; + cap->owner = kcont->cid; + cap->used = 3; + cap_list_insert(cap, &kcont->non_memory_caps); + + /* Set up dummy current cap-list for below functions to use */ + current->cap_list_ptr = &kcont->non_memory_caps; + copy_boot_capabilities(&kcont->physmem_used); copy_boot_capabilities(&kcont->physmem_free); copy_boot_capabilities(&kcont->virtmem_used); @@ -635,6 +660,7 @@ void init_resource_allocators(struct boot_resources *bootres, * in case all containers quit */ bootres->nspaces++; + bootres->nkpgds++; /* Initialise PGD cache */ kcont->pgd_cache = init_resource_cache(bootres->nspaces, @@ -660,13 +686,17 @@ void init_resource_allocators(struct boot_resources *bootres, kcont, 0); /* - * Add all caps used by the kernel + two extra in case - * more memcaps get split after cap cache init below. + * Add all caps used by the kernel + * Two extra in case more memcaps get split after cap cache init below. + * Three extra for quantitative kernel caps for pmds, pgds, caps. */ - bootres->ncaps += kcont->virtmem_used.ncaps + - kcont->virtmem_free.ncaps + - kcont->physmem_used.ncaps + - kcont->physmem_free.ncaps + 2; + bootres->nkcaps += kcont->virtmem_used.ncaps + + kcont->virtmem_free.ncaps + + kcont->physmem_used.ncaps + + kcont->physmem_free.ncaps + 2 + 3; + + /* Add that to all cap count */ + bootres->ncaps += bootres->nkcaps; /* Initialise capability cache */ kcont->cap_cache = init_resource_cache(bootres->ncaps, @@ -674,16 +704,19 @@ void init_resource_allocators(struct boot_resources *bootres, kcont, 0); /* Count boot pmds used so far and add them */ - bootres->npmds += pgd_count_pmds(&init_pgd); + bootres->nkpmds += pgd_count_pmds(&init_pgd); /* * Calculate maximum possible pmds * that may be used during this pmd * cache init and add them. */ - bootres->npmds += ((bootres->npmds * PMD_SIZE) / PMD_MAP_SIZE); + bootres->nkpmds += ((bootres->npmds * PMD_SIZE) / PMD_MAP_SIZE); if (!is_aligned(bootres->npmds * PMD_SIZE, PMD_MAP_SIZE)) - bootres->npmds++; + bootres->nkpmds++; + + /* Add kernel pmds to all pmd count */ + bootres->npmds += bootres->nkpmds; /* Initialise PMD cache */ kcont->pmd_cache = init_resource_cache(bootres->npmds, @@ -814,10 +847,10 @@ int init_system_resources(struct kernel_container *kcont) init_resource_allocators(&bootres, kcont); - setup_containers(&bootres, kcont); - kcont_setup_capabilities(&bootres, kcont); + setup_containers(&bootres, kcont); + return 0; } diff --git a/src/generic/tcb.c b/src/generic/tcb.c index 6010f82..44eaca7 100644 --- a/src/generic/tcb.c +++ b/src/generic/tcb.c @@ -42,26 +42,6 @@ void tcb_init(struct ktcb *new) waitqueue_head_init(&new->wqh_pager); } - -struct ktcb *tcb_alloc_init_use_capability(struct capability *cap) -{ - struct ktcb *tcb; - struct task_ids ids; - - if (!(tcb = alloc_ktcb_use_capability(cap))) - return 0; - - ids.tid = id_new(&kernel_container.ktcb_ids); - ids.tgid = L4_NILTHREAD; - ids.spid = L4_NILTHREAD; - - set_task_ids(tcb, &ids); - - tcb_init(tcb); - - return tcb; -} - struct ktcb *tcb_alloc_init(void) { struct ktcb *tcb;