From 1ea21d84bd6d84b394191d6c4e64262fe638fa65 Mon Sep 17 00:00:00 2001 From: Bahadir Balban Date: Wed, 17 Sep 2008 15:19:37 +0300 Subject: [PATCH] Updated test0 with a forktest. Fixed timeslices. Updated kmem usage calculations. - test0 now forks 16 tasks that each modify a global variable. - scheduler now gives 1/10th of a second per task. It also does not increase timeslice of a task that has scheduled. - When a memory is granted to the kernel, the distribution of this memory to memcaches was calculated in a complicated way. This is now simplified. --- include/l4/api/kip.h | 3 -- include/l4/generic/scheduler.h | 3 +- include/l4/glue/arm/memory.h | 17 +++++---- src/api/ipc.c | 4 +-- src/generic/pgalloc.c | 66 +++++++++++++++++++--------------- src/generic/scheduler.c | 7 ++-- tasks/libmem/mm/alloc_page.h | 1 - tasks/test0/include/tests.h | 1 + tasks/test0/main.c | 10 ++++-- tasks/test0/src/fileio.c | 22 +++++++----- 10 files changed, 75 insertions(+), 59 deletions(-) diff --git a/include/l4/api/kip.h b/include/l4/api/kip.h index cb4777d..7d45fec 100644 --- a/include/l4/api/kip.h +++ b/include/l4/api/kip.h @@ -78,9 +78,6 @@ struct kip { #define PAGER_TID 0 #define VFS_TID 1 #define BLKDEV_TID 2 -#define KERNEL_TID 3 -#define MAX_PREDEFINED_TID KERNEL_TID -#define MIN_PREDEFINED_TID 0 #define __PAGERNAME__ "mm0" #define __KERNELNAME__ "code0" diff --git a/include/l4/generic/scheduler.h b/include/l4/generic/scheduler.h index 3fc55ba..01e7fb9 100644 --- a/include/l4/generic/scheduler.h +++ b/include/l4/generic/scheduler.h @@ -12,8 +12,7 @@ /* Ticks per second, try ticks = 1000 + timeslice = 1 for regressed preemption test. */ #define HZ 100 -#define TASK_TIMESLICE_DEFAULT 5000 -/* #define TASK_TIMESLICE_DEFAULT (HZ/100)*/ +#define TASK_TIMESLICE_DEFAULT HZ/100 static inline struct ktcb *current_task(void) { diff --git a/include/l4/glue/arm/memory.h b/include/l4/glue/arm/memory.h index eca3fb2..0d8d389 100644 --- a/include/l4/glue/arm/memory.h +++ b/include/l4/glue/arm/memory.h @@ -89,15 +89,14 @@ pmd_table_t *alloc_boot_pmd(void); * The granted memory is used in an architecture-specific way, e.g. for pgds, * pmds, and kernel stack. Therefore this should be defined per-arch. */ -typedef struct kmem_usage_per_grant { - int grant_size; /* The size of the grant given by pager */ - int task_size_avg; /* Average memory a task occupies */ - int tasks_per_kmem_grant; /* Num of tasks to allocate for, per grant */ - int pg_total; /* Total size of page allocs needed per grant */ - int pmd_total; /* Total size of pmd allocs needed per grant */ - int pgd_total; /* Total size of pgd allocs needed per grant */ - int extra; /* Extra unused space, left per grant */ -} kmem_usage_per_grant_t; +typedef struct grant_kmem_usage { + unsigned long total_size; + unsigned long total_tasks; + unsigned long total_pgds; + unsigned long total_pmds; + unsigned long total_tcbs; + unsigned long extra; +} grant_kmem_usage_t; void paging_init(void); void init_pmd_tables(void); diff --git a/src/api/ipc.c b/src/api/ipc.c index ebd35a9..cdc1368 100644 --- a/src/api/ipc.c +++ b/src/api/ipc.c @@ -242,11 +242,11 @@ int sys_ipc(syscall_context_t *regs) int ret = 0; /* Check arguments */ - if (!((from >= L4_ANYTHREAD) && (from <= MAX_PREDEFINED_TID))) { + if (from < L4_ANYTHREAD) { ret = -EINVAL; goto error; } - if (!((to >= L4_ANYTHREAD) && (to <= MAX_PREDEFINED_TID))) { + if (to < L4_ANYTHREAD) { ret = -EINVAL; goto error; } diff --git a/src/generic/pgalloc.c b/src/generic/pgalloc.c index 3883843..9b927c7 100644 --- a/src/generic/pgalloc.c +++ b/src/generic/pgalloc.c @@ -33,50 +33,60 @@ void pgalloc_add_new_cache(struct mem_cache *cache, int cidx) list_add(&cache->list, &pgalloc.cache_list[cidx]); } -void calc_kmem_usage_per_grant(kmem_usage_per_grant_t *params) +void print_kmem_grant_params(grant_kmem_usage_t *params) { - /* Pmds, pgds, pages in numbers, per grant */ - int pmds_per_task_avg = params->task_size_avg / PMD_MAP_SIZE; - int pmds_per_kmem_grant = params->tasks_per_kmem_grant * pmds_per_task_avg; - int pgds_per_kmem_grant = params->tasks_per_kmem_grant * 1; - int pgs_per_kmem_grant = params->tasks_per_kmem_grant * 1; - - /* Now everything in Kbs */ - params->pmd_total = pmds_per_kmem_grant * PMD_SIZE; - params->pgd_total = pgds_per_kmem_grant * PGD_SIZE; - params->pg_total = pgs_per_kmem_grant * PAGE_SIZE; - params->extra = params->grant_size - - (params->pgd_total + params->pmd_total + - params->pg_total); + printk("Possible kmem usage on this memory grant:\n"); + printk("PGDs: %lu, PMDs: %lu, TCBs: %lu, Extra: %lu bytes.\n", + params->total_pgds, params->total_pmds, params->total_tcbs, + params->extra); } +#define TASK_AVERAGE_SIZE SZ_16MB +#define TASK_AVERAGE_PMDS TASK_AVERAGE_SIZE / PMD_MAP_SIZE + +void calc_grant_kmem_usage(grant_kmem_usage_t *params, unsigned long total_size) +{ + /* Kmem usage per task */ + unsigned long task_avg_kmem_usage = PGD_SIZE + PMD_SIZE * 16 + PAGE_SIZE; + unsigned long total_tasks = total_size / task_avg_kmem_usage; + unsigned long extra = total_size - total_tasks * task_avg_kmem_usage; + + params->total_size = total_size; + params->total_tasks = total_tasks; + params->total_pgds = total_tasks; + params->total_pmds = total_tasks * 16; + params->total_tcbs = total_tasks; + params->extra = extra; + + print_kmem_grant_params(params); +} + + int pgalloc_add_new_grant(unsigned long pfn, int npages) { unsigned long physical = __pfn_to_addr(pfn); void *virtual = (void *)phys_to_virt(physical); struct mem_cache *pgd_cache, *pmd_cache, *pg_cache; - kmem_usage_per_grant_t params; + grant_kmem_usage_t params; /* First map the whole grant */ add_mapping(physical, phys_to_virt(physical), __pfn_to_addr(npages), MAP_SVC_RW_FLAGS); /* Calculate how to divide buffer into different caches */ - params.task_size_avg = TASK_AVERAGE_SIZE; - params.grant_size = npages * PAGE_SIZE; - - /* Calculate pools for how many tasks from this much grant */ - params.tasks_per_kmem_grant = (__pfn(SZ_1MB) * TASKS_PER_1MB_GRANT) / - __pfn(params.grant_size); - calc_kmem_usage_per_grant(¶ms); + calc_grant_kmem_usage(¶ms, __pfn_to_addr(npages)); /* Create the caches, least alignment-needing, most, then others. */ - pmd_cache = mem_cache_init(virtual, params.pmd_total, PMD_SIZE, 1); - virtual += params.pmd_total; - pgd_cache = mem_cache_init(virtual, params.pgd_total, PGD_SIZE, 1); - virtual += params.pgd_total; - pg_cache = mem_cache_init(virtual, params.pg_total + params.extra, - PAGE_SIZE, 1); + pmd_cache = mem_cache_init(virtual, params.total_pmds * PMD_SIZE, + PMD_SIZE, 1); + virtual += params.total_pmds * PMD_SIZE; + + pgd_cache = mem_cache_init(virtual, params.total_pgds * PGD_SIZE, + PGD_SIZE, 1); + virtual += params.total_pgds * PGD_SIZE; + + pg_cache = mem_cache_init(virtual, params.total_tcbs * PAGE_SIZE + + params.extra, PAGE_SIZE, 1); /* Add the caches */ pgalloc_add_new_cache(pgd_cache, PGALLOC_PGD_CACHE); diff --git a/src/generic/scheduler.c b/src/generic/scheduler.c index d37a58c..bed17b8 100644 --- a/src/generic/scheduler.c +++ b/src/generic/scheduler.c @@ -300,8 +300,6 @@ void scheduler() sched_lock(); need_resched = 0; - BUG_ON(current->tid < MIN_PREDEFINED_TID || - current->tid > MAX_PREDEFINED_TID); BUG_ON(current->rq != rq_runnable); /* Current task */ @@ -309,8 +307,9 @@ void scheduler() sched_next_state(current); if (current->state == TASK_RUNNABLE) { - current->ticks_left += TASK_TIMESLICE_DEFAULT; - BUG_ON(current->ticks_left <= 0); + BUG_ON(current->ticks_left < 0); + if (current->ticks_left == 0) + current->ticks_left = TASK_TIMESLICE_DEFAULT; sched_rq_add_task_behind(current, rq_expired); } sched_rq_swap_expired_runnable(); diff --git a/tasks/libmem/mm/alloc_page.h b/tasks/libmem/mm/alloc_page.h index d8a7bd7..c53ffbb 100644 --- a/tasks/libmem/mm/alloc_page.h +++ b/tasks/libmem/mm/alloc_page.h @@ -25,7 +25,6 @@ void init_page_allocator(unsigned long start, unsigned long end); /* Page allocation functions */ void *alloc_page(int quantity); -void *zalloc_page(int quantity); int free_page(void *paddr); #endif /* __ALLOC_PAGE_H__ */ diff --git a/tasks/test0/include/tests.h b/tasks/test0/include/tests.h index 054f9f0..3ab522b 100644 --- a/tasks/test0/include/tests.h +++ b/tasks/test0/include/tests.h @@ -4,6 +4,7 @@ #define __TASKNAME__ "test0" int shmtest(void); +int forktest(void); int mmaptest(void); int dirtest(void); int fileio(void); diff --git a/tasks/test0/main.c b/tasks/test0/main.c index a1d3304..9156193 100644 --- a/tasks/test0/main.c +++ b/tasks/test0/main.c @@ -38,13 +38,19 @@ void main(void) printf("Error forking...\n"); if (pid == 0) { - printf("File IO test 1, done by child:\n"); + printf("Child: file IO test 1.\n"); if (fileio() == 0) printf("-- PASSED --\n"); else printf("-- FAILED --\n"); + + printf("Child: forktest.\n"); + if (forktest() == 0) + printf("-- PASSED -- \n"); + else + printf("-- FAILED -- \n"); } else { - printf("File IO test 2, done by parent, with child pid %d:\n", pid); + printf("Parent: file IO test 2. child pid %d:\n", pid); if (fileio2() == 0) printf("-- PASSED --\n"); else diff --git a/tasks/test0/src/fileio.c b/tasks/test0/src/fileio.c index c0e6812..e54bd71 100644 --- a/tasks/test0/src/fileio.c +++ b/tasks/test0/src/fileio.c @@ -6,7 +6,6 @@ #include #include #include -#include int fileio2(void) { @@ -15,10 +14,10 @@ int fileio2(void) int err; char buf[128]; off_t offset; - int tid = self_tid(); - + int tid = getpid(); char *str = "I WROTE TO THIS FILE\n"; + memset(buf, 0, 128); if ((fd = open("/home/bahadir/newfile2.txt", O_RDWR | O_CREAT | O_TRUNC, S_IRWXU)) < 0) { perror("OPEN"); return -1; @@ -56,8 +55,12 @@ int fileio2(void) printf("%d: Read: %d bytes from file.\n", tid, cnt); if (cnt) { printf("%d: Read string: %s\n", tid, buf); - if (strcmp(buf, str)) + if (strcmp(buf, str)) { + printf("Error: strings not the same:\n"); + printf("str: %s\n", str); + printf("buf: %s\n", buf); return -1; + } } printf("%d: close.\n", tid); @@ -76,10 +79,10 @@ int fileio(void) int err; char buf[128]; off_t offset; - int tid = self_tid(); - + int tid = getpid(); char *str = "I WROTE TO THIS FILE\n"; + memset(buf, 0, 128); if ((fd = open("/home/bahadir/newfile.txt", O_RDWR | O_CREAT | O_TRUNC, S_IRWXU)) < 0) { perror("OPEN"); return -1; @@ -106,8 +109,12 @@ int fileio(void) printf("%d: Read: %d bytes from file.\n", tid, cnt); if (cnt) { printf("%d: Read string: %s\n", tid, buf); - if (strcmp(buf, str)) + if (strcmp(buf, str)) { + printf("Strings not the same:\n"); + printf("Str: %s\n", str); + printf("Buf: %s\n", buf); return -1; + } } printf("%d: close.\n", tid); @@ -115,7 +122,6 @@ int fileio(void) perror("CLOSE"); return -1; } - return 0; }