mirror of
https://github.com/drasko/codezero.git
synced 2026-02-28 01:33:13 +01:00
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.
This commit is contained in:
@@ -78,9 +78,6 @@ struct kip {
|
|||||||
#define PAGER_TID 0
|
#define PAGER_TID 0
|
||||||
#define VFS_TID 1
|
#define VFS_TID 1
|
||||||
#define BLKDEV_TID 2
|
#define BLKDEV_TID 2
|
||||||
#define KERNEL_TID 3
|
|
||||||
#define MAX_PREDEFINED_TID KERNEL_TID
|
|
||||||
#define MIN_PREDEFINED_TID 0
|
|
||||||
|
|
||||||
#define __PAGERNAME__ "mm0"
|
#define __PAGERNAME__ "mm0"
|
||||||
#define __KERNELNAME__ "code0"
|
#define __KERNELNAME__ "code0"
|
||||||
|
|||||||
@@ -12,8 +12,7 @@
|
|||||||
|
|
||||||
/* Ticks per second, try ticks = 1000 + timeslice = 1 for regressed preemption test. */
|
/* Ticks per second, try ticks = 1000 + timeslice = 1 for regressed preemption test. */
|
||||||
#define HZ 100
|
#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)
|
static inline struct ktcb *current_task(void)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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,
|
* 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.
|
* pmds, and kernel stack. Therefore this should be defined per-arch.
|
||||||
*/
|
*/
|
||||||
typedef struct kmem_usage_per_grant {
|
typedef struct grant_kmem_usage {
|
||||||
int grant_size; /* The size of the grant given by pager */
|
unsigned long total_size;
|
||||||
int task_size_avg; /* Average memory a task occupies */
|
unsigned long total_tasks;
|
||||||
int tasks_per_kmem_grant; /* Num of tasks to allocate for, per grant */
|
unsigned long total_pgds;
|
||||||
int pg_total; /* Total size of page allocs needed per grant */
|
unsigned long total_pmds;
|
||||||
int pmd_total; /* Total size of pmd allocs needed per grant */
|
unsigned long total_tcbs;
|
||||||
int pgd_total; /* Total size of pgd allocs needed per grant */
|
unsigned long extra;
|
||||||
int extra; /* Extra unused space, left per grant */
|
} grant_kmem_usage_t;
|
||||||
} kmem_usage_per_grant_t;
|
|
||||||
|
|
||||||
void paging_init(void);
|
void paging_init(void);
|
||||||
void init_pmd_tables(void);
|
void init_pmd_tables(void);
|
||||||
|
|||||||
@@ -242,11 +242,11 @@ int sys_ipc(syscall_context_t *regs)
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
/* Check arguments */
|
/* Check arguments */
|
||||||
if (!((from >= L4_ANYTHREAD) && (from <= MAX_PREDEFINED_TID))) {
|
if (from < L4_ANYTHREAD) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (!((to >= L4_ANYTHREAD) && (to <= MAX_PREDEFINED_TID))) {
|
if (to < L4_ANYTHREAD) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,50 +33,60 @@ void pgalloc_add_new_cache(struct mem_cache *cache, int cidx)
|
|||||||
list_add(&cache->list, &pgalloc.cache_list[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 */
|
printk("Possible kmem usage on this memory grant:\n");
|
||||||
int pmds_per_task_avg = params->task_size_avg / PMD_MAP_SIZE;
|
printk("PGDs: %lu, PMDs: %lu, TCBs: %lu, Extra: %lu bytes.\n",
|
||||||
int pmds_per_kmem_grant = params->tasks_per_kmem_grant * pmds_per_task_avg;
|
params->total_pgds, params->total_pmds, params->total_tcbs,
|
||||||
int pgds_per_kmem_grant = params->tasks_per_kmem_grant * 1;
|
params->extra);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#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)
|
int pgalloc_add_new_grant(unsigned long pfn, int npages)
|
||||||
{
|
{
|
||||||
unsigned long physical = __pfn_to_addr(pfn);
|
unsigned long physical = __pfn_to_addr(pfn);
|
||||||
void *virtual = (void *)phys_to_virt(physical);
|
void *virtual = (void *)phys_to_virt(physical);
|
||||||
struct mem_cache *pgd_cache, *pmd_cache, *pg_cache;
|
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 */
|
/* First map the whole grant */
|
||||||
add_mapping(physical, phys_to_virt(physical), __pfn_to_addr(npages),
|
add_mapping(physical, phys_to_virt(physical), __pfn_to_addr(npages),
|
||||||
MAP_SVC_RW_FLAGS);
|
MAP_SVC_RW_FLAGS);
|
||||||
|
|
||||||
/* Calculate how to divide buffer into different caches */
|
/* Calculate how to divide buffer into different caches */
|
||||||
params.task_size_avg = TASK_AVERAGE_SIZE;
|
calc_grant_kmem_usage(¶ms, __pfn_to_addr(npages));
|
||||||
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);
|
|
||||||
|
|
||||||
/* Create the caches, least alignment-needing, most, then others. */
|
/* Create the caches, least alignment-needing, most, then others. */
|
||||||
pmd_cache = mem_cache_init(virtual, params.pmd_total, PMD_SIZE, 1);
|
pmd_cache = mem_cache_init(virtual, params.total_pmds * PMD_SIZE,
|
||||||
virtual += params.pmd_total;
|
PMD_SIZE, 1);
|
||||||
pgd_cache = mem_cache_init(virtual, params.pgd_total, PGD_SIZE, 1);
|
virtual += params.total_pmds * PMD_SIZE;
|
||||||
virtual += params.pgd_total;
|
|
||||||
pg_cache = mem_cache_init(virtual, params.pg_total + params.extra,
|
pgd_cache = mem_cache_init(virtual, params.total_pgds * PGD_SIZE,
|
||||||
PAGE_SIZE, 1);
|
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 */
|
/* Add the caches */
|
||||||
pgalloc_add_new_cache(pgd_cache, PGALLOC_PGD_CACHE);
|
pgalloc_add_new_cache(pgd_cache, PGALLOC_PGD_CACHE);
|
||||||
|
|||||||
@@ -300,8 +300,6 @@ void scheduler()
|
|||||||
|
|
||||||
sched_lock();
|
sched_lock();
|
||||||
need_resched = 0;
|
need_resched = 0;
|
||||||
BUG_ON(current->tid < MIN_PREDEFINED_TID ||
|
|
||||||
current->tid > MAX_PREDEFINED_TID);
|
|
||||||
BUG_ON(current->rq != rq_runnable);
|
BUG_ON(current->rq != rq_runnable);
|
||||||
|
|
||||||
/* Current task */
|
/* Current task */
|
||||||
@@ -309,8 +307,9 @@ void scheduler()
|
|||||||
sched_next_state(current);
|
sched_next_state(current);
|
||||||
|
|
||||||
if (current->state == TASK_RUNNABLE) {
|
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_add_task_behind(current, rq_expired);
|
||||||
}
|
}
|
||||||
sched_rq_swap_expired_runnable();
|
sched_rq_swap_expired_runnable();
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ void init_page_allocator(unsigned long start, unsigned long end);
|
|||||||
|
|
||||||
/* Page allocation functions */
|
/* Page allocation functions */
|
||||||
void *alloc_page(int quantity);
|
void *alloc_page(int quantity);
|
||||||
void *zalloc_page(int quantity);
|
|
||||||
int free_page(void *paddr);
|
int free_page(void *paddr);
|
||||||
|
|
||||||
#endif /* __ALLOC_PAGE_H__ */
|
#endif /* __ALLOC_PAGE_H__ */
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#define __TASKNAME__ "test0"
|
#define __TASKNAME__ "test0"
|
||||||
|
|
||||||
int shmtest(void);
|
int shmtest(void);
|
||||||
|
int forktest(void);
|
||||||
int mmaptest(void);
|
int mmaptest(void);
|
||||||
int dirtest(void);
|
int dirtest(void);
|
||||||
int fileio(void);
|
int fileio(void);
|
||||||
|
|||||||
@@ -38,13 +38,19 @@ void main(void)
|
|||||||
printf("Error forking...\n");
|
printf("Error forking...\n");
|
||||||
|
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
printf("File IO test 1, done by child:\n");
|
printf("Child: file IO test 1.\n");
|
||||||
if (fileio() == 0)
|
if (fileio() == 0)
|
||||||
printf("-- PASSED --\n");
|
printf("-- PASSED --\n");
|
||||||
else
|
else
|
||||||
printf("-- FAILED --\n");
|
printf("-- FAILED --\n");
|
||||||
|
|
||||||
|
printf("Child: forktest.\n");
|
||||||
|
if (forktest() == 0)
|
||||||
|
printf("-- PASSED -- \n");
|
||||||
|
else
|
||||||
|
printf("-- FAILED -- \n");
|
||||||
} else {
|
} 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)
|
if (fileio2() == 0)
|
||||||
printf("-- PASSED --\n");
|
printf("-- PASSED --\n");
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <tests.h>
|
#include <tests.h>
|
||||||
#include <l4lib/arch/syslib.h>
|
|
||||||
|
|
||||||
int fileio2(void)
|
int fileio2(void)
|
||||||
{
|
{
|
||||||
@@ -15,10 +14,10 @@ int fileio2(void)
|
|||||||
int err;
|
int err;
|
||||||
char buf[128];
|
char buf[128];
|
||||||
off_t offset;
|
off_t offset;
|
||||||
int tid = self_tid();
|
int tid = getpid();
|
||||||
|
|
||||||
char *str = "I WROTE TO THIS FILE\n";
|
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) {
|
if ((fd = open("/home/bahadir/newfile2.txt", O_RDWR | O_CREAT | O_TRUNC, S_IRWXU)) < 0) {
|
||||||
perror("OPEN");
|
perror("OPEN");
|
||||||
return -1;
|
return -1;
|
||||||
@@ -56,8 +55,12 @@ int fileio2(void)
|
|||||||
printf("%d: Read: %d bytes from file.\n", tid, cnt);
|
printf("%d: Read: %d bytes from file.\n", tid, cnt);
|
||||||
if (cnt) {
|
if (cnt) {
|
||||||
printf("%d: Read string: %s\n", tid, buf);
|
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;
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("%d: close.\n", tid);
|
printf("%d: close.\n", tid);
|
||||||
@@ -76,10 +79,10 @@ int fileio(void)
|
|||||||
int err;
|
int err;
|
||||||
char buf[128];
|
char buf[128];
|
||||||
off_t offset;
|
off_t offset;
|
||||||
int tid = self_tid();
|
int tid = getpid();
|
||||||
|
|
||||||
char *str = "I WROTE TO THIS FILE\n";
|
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) {
|
if ((fd = open("/home/bahadir/newfile.txt", O_RDWR | O_CREAT | O_TRUNC, S_IRWXU)) < 0) {
|
||||||
perror("OPEN");
|
perror("OPEN");
|
||||||
return -1;
|
return -1;
|
||||||
@@ -106,8 +109,12 @@ int fileio(void)
|
|||||||
printf("%d: Read: %d bytes from file.\n", tid, cnt);
|
printf("%d: Read: %d bytes from file.\n", tid, cnt);
|
||||||
if (cnt) {
|
if (cnt) {
|
||||||
printf("%d: Read string: %s\n", tid, buf);
|
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;
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("%d: close.\n", tid);
|
printf("%d: close.\n", tid);
|
||||||
@@ -115,7 +122,6 @@ int fileio(void)
|
|||||||
perror("CLOSE");
|
perror("CLOSE");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user