From ff676995f24462393c413d635a2a5a318c7c3194 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Mon, 16 Jul 2012 13:19:06 +0200 Subject: [PATCH 1/4] update of the version number --- include/metalsvm/config.h.example | 2 +- include/metalsvm/config.h.scc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/metalsvm/config.h.example b/include/metalsvm/config.h.example index d76ac297..c9f4b31d 100644 --- a/include/metalsvm/config.h.example +++ b/include/metalsvm/config.h.example @@ -24,7 +24,7 @@ extern "C" { #endif -#define METALSVM_VERSION "0.1" +#define METALSVM_VERSION "0.9" #define MAX_TASKS 16 #define MAX_CORES 1 #define MAX_FNAME 128 diff --git a/include/metalsvm/config.h.scc b/include/metalsvm/config.h.scc index c99b530b..2da874af 100644 --- a/include/metalsvm/config.h.scc +++ b/include/metalsvm/config.h.scc @@ -24,7 +24,7 @@ extern "C" { #endif -#define METALSVM_VERSION "0.1" +#define METALSVM_VERSION "0.9" #define MAX_TASKS 16 #define MAX_CORES 1 #define MAX_FNAME 128 From 7082d0650f8d36db9d434670899a449c8cd821d9 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Mon, 16 Jul 2012 21:53:41 +0200 Subject: [PATCH 2/4] add new functions to start tasks on a specific core --- include/metalsvm/tasks.h | 49 ++++++++++++++++++++++++++++++++++++++-- kernel/tasks.c | 38 +++++++++++++++++++++---------- 2 files changed, 73 insertions(+), 14 deletions(-) diff --git a/include/metalsvm/tasks.h b/include/metalsvm/tasks.h index ac83e112..47c3c3f5 100644 --- a/include/metalsvm/tasks.h +++ b/include/metalsvm/tasks.h @@ -61,12 +61,48 @@ int multitasking_init(void); * @param ep Pointer to the entry function for the new task * @param arg Arguments the task shall start with * @param prio Desired priority of the new kernel task + * @param core_id Start the new task on the core with this id * * @return * - 0 on success * - -EINVAL (-22) on failure */ -int create_kernel_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio); +int create_kernel_task_on_core(tid_t* id, entry_point_t ep, void* arg, uint8_t prio, uint32_t core_id); + +/** @brief create a kernel task. + * + * @param id The value behind this pointer will be set to the new task's id + * @param ep Pointer to the entry function for the new task + * @param arg Arguments the task shall start with + * @param prio Desired priority of the new kernel task + * + * @return + * - 0 on success + * - -EINVAL (-22) on failure + */ +static inline int create_kernel_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio) +{ + uint32_t core_id, flags; + + flags = irq_nested_disable(); + core_id = CORE_ID; + irq_nested_enable(flags); + + return create_kernel_task_on_core(id, ep, arg, prio, core_id); +} + +/** @brief Create a user level task. + * + * @param id The value behind this pointer will be set to the new task's id + * @param fname Filename of the executable to start the task with + * @param argv Pointer to arguments array + * @param core_id Start the new task on the core with this id + * + * @return + * - 0 on success + * - -EINVAL (-22) or -ENOMEM (-12)on failure + */ +int create_user_task_on_core(tid_t* id, const char* fame, char** argv, uint32_t core_id); /** @brief Create a user level task. * @@ -78,7 +114,16 @@ int create_kernel_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio); * - 0 on success * - -EINVAL (-22) or -ENOMEM (-12)on failure */ -int create_user_task(tid_t* id, const char* fame, char** argv); +static inline int create_user_task(tid_t* id, const char* fame, char** argv) +{ + uint32_t core_id, flags; + + flags = irq_nested_disable(); + core_id = CORE_ID; + irq_nested_enable(flags); + + return create_user_task_on_core(id, fame, argv, core_id); +} /** @brief Block current task until the child task is terminated * @param result The terminated child's return value diff --git a/kernel/tasks.c b/kernel/tasks.c index 3dbaba08..1f82c7b5 100644 --- a/kernel/tasks.c +++ b/kernel/tasks.c @@ -70,6 +70,10 @@ static runqueue_t runqueues[1] = { \ #endif #endif +#if MAX_CORES > 1 +extern atomic_int32_t cpu_online; +#endif + DEFINE_PER_CORE(task_t*, current_task, task_table+0); /** @brief helper function for the assembly code to determine the current task @@ -206,10 +210,12 @@ static void NORETURN do_exit(int arg) { spinlock_unlock(&curr_task->vma_lock); drop_pgd(); // delete page directory and its page tables - + +#if 0 if (atomic_int32_read(&curr_task->user_usage)) kprintf("Memory leak! Task %d did not release %d pages\n", curr_task->id, atomic_int32_read(&curr_task->user_usage)); +#endif curr_task->status = TASK_FINISHED; // decrease the number of active tasks @@ -252,15 +258,17 @@ void NORETURN abort(void) { * @param ep Pointer to the function the task shall start with * @param arg Arguments list * @param prio Desired priority of the new task + * @param core_id Start the new task on the core with this id + * * @return * - 0 on success * - -ENOMEM (-12) or -EINVAL (-22) on failure */ -static int create_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio) +static int create_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio, uint32_t core_id) { task_t* curr_task; int ret = -ENOMEM; - unsigned int i, core_id; + uint32_t i; if (BUILTIN_EXPECT(!ep, 0)) return -EINVAL; @@ -271,7 +279,15 @@ static int create_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio) spinlock_irqsave_lock(&table_lock); - core_id = CORE_ID; +#if MAX_CORES > 1 + if (core_id >= atomic_int32_read(&cpu_online)) +#else + if (core_id > 0) +#endif + { + core_id = CORE_ID; + kprintf("Inavlid core id! Set id to %u!\n", core_id); + } curr_task = per_core(current_task); for(i=0; i MAX_PRIO) prio = NORMAL_PRIO; - return create_task(id, kernel_entry, kernel_args, prio); + return create_task(id, kernel_entry, kernel_args, prio, core_id); } #define MAX_ARGS (PAGE_SIZE - 2*sizeof(int) - sizeof(vfs_node_t*)) @@ -755,11 +771,13 @@ static int user_entry(void* arg) * @param id Pointer to the tid_t structure which shall be filles * @param fname Executable's path and filename * @param argv Arguments list + * @param core_id Start the new task on the core with this id + * * @return * - 0 on success * - -ENOMEM (-12) or -EINVAL (-22) on failure */ -int create_user_task(tid_t* id, const char* fname, char** argv) +int create_user_task_on_core(tid_t* id, const char* fname, char** argv, uint32_t core_id) { vfs_node_t* node; int argc = 0; @@ -797,7 +815,7 @@ int create_user_task(tid_t* id, const char* fname, char** argv) } /* create new task */ - return create_task(id, user_entry, load_args, NORMAL_PRIO); + return create_task(id, user_entry, load_args, NORMAL_PRIO, core_id); } /** @brief Used by the execve-Systemcall */ @@ -1129,10 +1147,6 @@ void update_load(void) } } -#if MAX_CORES > 1 -extern atomic_int32_t cpu_online; -#endif - void dump_load(void) { uint32_t i; From 837bc3ebe13242cebdb97e294f90fdb6dd361f05 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Mon, 16 Jul 2012 21:55:42 +0200 Subject: [PATCH 3/4] add config file tests.h, which specifies the starting apps --- apps/echo.c | 4 +- apps/gfx_client.c | 4 ++ apps/gfx_client.h | 4 +- apps/gfx_generic.c | 2 +- apps/gfx_generic.h | 2 +- apps/jacobi.c | 4 +- apps/laplace.c | 4 +- apps/netio.c | 4 +- apps/tests.c | 174 ++++++++++++++++++++++++++++++--------------- apps/tests.h | 49 +++++++++++++ kernel/init.c | 5 -- 11 files changed, 185 insertions(+), 71 deletions(-) create mode 100644 apps/tests.h diff --git a/apps/echo.c b/apps/echo.c index 4b637613..0aa62ad4 100644 --- a/apps/echo.c +++ b/apps/echo.c @@ -32,7 +32,9 @@ #include -#ifdef CONFIG_LWIP +#include "tests.h" + +#if defined(CONFIG_LWIP) && defined(START_ECHO) #include diff --git a/apps/gfx_client.c b/apps/gfx_client.c index 3c4f1a17..c07026a4 100644 --- a/apps/gfx_client.c +++ b/apps/gfx_client.c @@ -24,6 +24,8 @@ #include "gfx_client.h" #include +#ifdef CONFIG_GFX + static int myrank; static int sockfd; @@ -146,3 +148,5 @@ int gfx_finalize(){ } #endif + +#endif diff --git a/apps/gfx_client.h b/apps/gfx_client.h index c36743c7..77da7c6c 100644 --- a/apps/gfx_client.h +++ b/apps/gfx_client.h @@ -23,8 +23,10 @@ #include #include #include +#include "tests.h" -#ifdef CONFIG_LWIP + +#if defined(CONFIG_GFX) && defined(CONFIG_LWIP) && LWIP_SOCKET #define BUFSIZE 1024 diff --git a/apps/gfx_generic.c b/apps/gfx_generic.c index ad9842a2..69ef0ece 100644 --- a/apps/gfx_generic.c +++ b/apps/gfx_generic.c @@ -20,7 +20,7 @@ #include "gfx_client.h" #include "gfx_generic.h" -#if defined(CONFIG_LWIP) && LWIP_SOCKET +#if defined(CONFIG_GFX) && defined(CONFIG_LWIP) && LWIP_SOCKET int GFX_update() { diff --git a/apps/gfx_generic.h b/apps/gfx_generic.h index 37750f78..1b1ded4c 100644 --- a/apps/gfx_generic.h +++ b/apps/gfx_generic.h @@ -22,7 +22,7 @@ #include "gfx_client.h" -#ifdef CONFIG_LWIP +#if defined(CONFIG_LWIP) && defined(CONFIG_GFX) && LWIP_SOCKET #define GFX_init(ip_str, port_str, rank) gfx_init(ip_str, port_str, rank) #define GFX_send(buf, size, tag) gfx_send(buf, size, tag) diff --git a/apps/jacobi.c b/apps/jacobi.c index 96fca71a..c111c495 100644 --- a/apps/jacobi.c +++ b/apps/jacobi.c @@ -26,7 +26,9 @@ #include #include -#ifdef CONFIG_ROCKCREEK +#include "tests.h" + +#ifdef START_KERNEL_JACOBI #define MATRIX_SIZE 256 #define MAXVALUE 1337 diff --git a/apps/laplace.c b/apps/laplace.c index cb78ade5..83a5182f 100644 --- a/apps/laplace.c +++ b/apps/laplace.c @@ -22,7 +22,9 @@ #include #include -#ifdef CONFIG_ROCKCREEK +#include "tests.h" + +#ifdef START_KERNEL_LAPLACE #include #include diff --git a/apps/netio.c b/apps/netio.c index 7e6e207a..9649e665 100644 --- a/apps/netio.c +++ b/apps/netio.c @@ -24,6 +24,8 @@ #include #include +#include "tests.h" + #ifdef CONFIG_ROCKCREEK #include #include @@ -46,7 +48,7 @@ /* See http://www.nwlab.net/art/netio/netio.html to get the netio tool */ -#if defined(CONFIG_LWIP) && LWIP_SOCKET +#if defined(START_NETIO) && defined(CONFIG_LWIP) #ifdef CONFIG_ROCKCREEK #if USE_SOCKET_BYPASSING // for socket bypassing #include diff --git a/apps/tests.c b/apps/tests.c index 1fbe957a..3f5a67d1 100644 --- a/apps/tests.c +++ b/apps/tests.c @@ -39,12 +39,17 @@ #include #endif -static sem_t consuming, producing; -static mailbox_int32_t mbox; -static int val = 0; +#include "tests.h" int laplace(void* arg); int jacobi(void* arg); +void echo_init(void); +void netio_init(void); + +#ifdef START_CONSUMER_PRODUCER +static sem_t consuming, producing; +static mailbox_int32_t mbox; +static int val = 0; static int consumer(void* arg) { @@ -52,10 +57,10 @@ static int consumer(void* arg) for(i=0; i<5; i++) { sem_wait(&consuming, 0); - kprintf("Consumer got %d\n", val); - val = 0; - sem_post(&producing); - } + kprintf("Consumer got %d\n", val); + val = 0; + sem_post(&producing); + } for(i=0; i<5; i++) { mailbox_int32_fetch(&mbox, &m, 0); @@ -84,7 +89,9 @@ static int producer(void* arg) return 0; } +#endif +#if defined(START_FOO) || defined(START_JOIN_TEST) static int foo(void* arg) { int i; @@ -93,14 +100,15 @@ static int foo(void* arg) return 0; for(i=0; i<5; i++) { - kprintf("%s\n", (char*) arg); + kprintf("Message from core %u: %s\n", CORE_ID, (char*) arg); sleep(1); } return 42; } +#endif -#ifdef CONFIG_ROCKCREEK +#ifdef START_MAIL_PING static int mail_ping(void* arg) { int i; @@ -115,19 +123,22 @@ static int mail_ping(void* arg) { return 0; } +#endif - +#ifdef START_MAIL_NOISE static int mail_noise(void*arg) { icc_mail_noise(); // generate noise in the mesh return 0; } +#endif + +#ifdef START_SVM_TEST /* N has to be multiple of UEs */ #define N 1024 //#define N 512 //#define N 128 -//#define L2_ENABLE //#define SVM_TYPE SVM_STRONG #define SVM_TYPE SVM_LAZYRELEASE @@ -210,11 +221,6 @@ static int svm_test(void *arg) else kputs("Use Strong Release consistency!\n"); -#ifdef L2_ENABLE - kputs("Use Level 2 Cache!\n"); - svm_flags |= SVM_L2; -#endif - A[0] = (int*) svm_malloc(3*N*N*sizeof(int), svm_flags); #if 1 @@ -299,7 +305,9 @@ static int svm_test(void *arg) return 0; } +#endif +#ifdef START_SVM_BENCH static int svm_bench(void *arg) { volatile uint32_t* array = NULL; @@ -374,6 +382,7 @@ static int svm_bench(void *arg) } #endif +#ifdef START_JOIN_TEST static int join_test(void* arg) { tid_t id, ret; @@ -390,7 +399,9 @@ static int join_test(void* arg) return 0; } +#endif +#ifdef START_PI #ifndef M_PI #define M_PI 3.14159265358979323846264338327950288 /* pi */ #endif @@ -415,7 +426,9 @@ static int pi(void* arg) return 0; } +#endif +#ifdef START_MEASURE_CTX_SWITCH #define REPS 10000 volatile uint64_t t1, t2; @@ -438,30 +451,30 @@ static int measure_ctx_switch(void* arg) kprintf("Measuring SW task switching.\n"); for (i=0; i < REPS && stop == 0; i++) { - while(id == sid && stop == 0) { - t2 = rdtsc(); - cpuid(0,&a,&b,&c,&d); - } + while(id == sid && stop == 0) { + t2 = rdtsc(); + cpuid(0,&a,&b,&c,&d); + } - cpuid(0,&a,&b,&c,&d); - diff = rdtsc() -t2; + cpuid(0,&a,&b,&c,&d); + diff = rdtsc() -t2; - // The last measurement is garbage - if (stop) break; - // The first ones are garbage, too - if (i < 5) goto next_try; - if (diff >= timeslice) { - i--; - goto next_try; - } + // The last measurement is garbage + if (stop) break; + // The first ones are garbage, too + if (i < 5) goto next_try; + if (diff >= timeslice) { + i--; + goto next_try; + } - kprintf("%i: diff= %llu, i= %i\n", id, diff, i); - if (diff > max) max = diff; - if (diff < min) min = diff; - avg += diff; + kprintf("%i: diff= %llu, i= %i\n", id, diff, i); + if (diff > max) max = diff; + if (diff < min) min = diff; + avg += diff; next_try: - sid = id; + sid = id; } avg /= i-5; @@ -474,38 +487,81 @@ next_try: return 0; } +#endif int test_init(void) { -// char* argv[] = {"/bin/mshell", NULL}; - char* argv[] = {"/bin/tests", NULL}; +#ifdef START_HELLO + char* hello_argv[] = {"/bin/hello", NULL}; +#endif +#ifdef START_TESTS + char* tests_argv[] = {"/bin/tests", NULL}; +#endif +#ifdef START_JACOBI + char* jacobi_argv[] = {"/bin/jacobi", NULL}; +#endif +#ifdef START_MMNIF_TEST char* server_argv[] = {"/bin/server", "6789", NULL}; char* client_argv[] = {"/bin/client", "192.168.0.1", "6789", NULL}; +#endif - //sem_init(&producing, 1); - //sem_init(&consuming, 0); - //mailbox_int32_init(&mbox); +#ifdef START_ECHO + echo_init(); +#endif +#ifdef START_NETIO + netio_init(); +#endif +#ifdef START_CONSUMER_PRODUCER + sem_init(&producing, 1); + sem_init(&consuming, 0); + mailbox_int32_init(&mbox); - //create_kernel_task(NULL, measure_ctx_switch, (int)0, NORMAL_PRIO); - //create_kernel_task(NULL, measure_ctx_switch, (int)1, NORMAL_PRIO); + create_kernel_task(NULL, producer, NULL, NORMAL_PRIO); + create_kernel_task(NULL, consumer, NULL, NORMAL_PRIO); +#endif +#ifdef START_MEASURE_CTX_SWITCH + create_kernel_task(NULL, measure_ctx_switch, (int)0, NORMAL_PRIO); + create_kernel_task(NULL, measure_ctx_switch, (int)1, NORMAL_PRIO); +#endif +#ifdef START_FOO create_kernel_task(NULL, foo, "Hello from foo1", NORMAL_PRIO); - //create_kernel_task(NULL, foo, "Hello from foo2", NORMAL_PRIO); - //create_kernel_task(NULL, join_test, NULL, NORMAL_PRIO); - //create_kernel_task(NULL, producer, , NORMAL_PRIO); - //create_kernel_task(NULL, consumer, NULL, NORMAL_PRIO); - //create_kernel_task(NULL, mail_ping, NULL, NORMAL_PRIO); - //create_kernel_task(NULL, mail_noise, NULL, NORMAL_PRIO); - //create_kernel_task(NULL, svm_test, NULL, NORMAL_PRIO); - //create_kernel_task(NULL, svm_bench, NULL, NORMAL_PRIO); - //create_kernel_task(NULL, pi, NULL, NORMAL_PRIO); - //create_kernel_task(NULL, laplace, NULL, NORMAL_PRIO); - //create_kernel_task(NULL, jacobi, NULL, NORMAL_PRIO); - //create_user_task(NULL, "/bin/hello", argv); - create_user_task(NULL, "/bin/tests", argv); - //create_user_task(NULL, "/bin/jacobi", argv); - //create_user_task(NULL, "/bin/mshell", argv); - //create_user_task(NULL, "/bin/jacobi", argv); -#ifdef CONFIG_ROCKCREEK + //create_kernel_task_on_core(NULL, foo, "Hello from foo2", NORMAL_PRIO, 1); +#endif +#ifdef START_JOIN_TEST + create_kernel_task(NULL, join_test, NULL, NORMAL_PRIO); +#endif +#ifdef START_MAIL_PING + create_kernel_task(NULL, mail_ping, NULL, NORMAL_PRIO); +#endif +#ifdef START_MAIL_NOISE + create_kernel_task(NULL, mail_noise, NULL, NORMAL_PRIO); +#endif +#ifdef START_SVM_TEST + create_kernel_task(NULL, svm_test, NULL, NORMAL_PRIO); +#endif +#ifdef START_SVM_BENCH + create_kernel_task(NULL, svm_bench, NULL, NORMAL_PRIO); +#endif +#ifdef START_PI + create_kernel_task(NULL, pi, NULL, NORMAL_PRIO); +#endif +#ifdef START_KERNEL_LAPLACE + create_kernel_task(NULL, laplace, NULL, NORMAL_PRIO); +#endif +#ifdef START_KERNEL_JACOBI + create_kernel_task(NULL, jacobi, NULL, NORMAL_PRIO); +#endif +#ifdef START_HELLO + create_user_task(NULL, "/bin/hello", hello_argv); +#endif +#ifdef START_TESTS + create_user_task(NULL, "/bin/tests", tests_argv); +#endif +#ifdef START_JACOBI + create_user_task(NULL, "/bin/jacobi", jacobi_argv); + //create_user_task_on_core(NULL, "/bin/jacobi", jacobi_argv, 1); +#endif +#ifdef START_MMNIF_TEST #if defined(CONFIG_LWIP) && LWIP_SOCKET if (RCCE_ue() == 0) { kprintf("Start /bin/server...\n"); diff --git a/apps/tests.h b/apps/tests.h new file mode 100644 index 00000000..7e431b87 --- /dev/null +++ b/apps/tests.h @@ -0,0 +1,49 @@ +/* + * Copyright 2010 Stefan Lankes, Chair for Operating Systems, + * RWTH Aachen University + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of MetalSVM. + */ + +#ifndef CONFIG_TEST_H +#define CONFIG_TEST_H + +#include + +// define test applications, which will be started +#ifdef CONFIG_ROCKCREEK +//#define START_SVM_TEST +//#define START_SVM_BENCH +//#define START_MAIL_PING +//#define START_MAIL_NOISE +//#define START_KERNEL_LAPLACE +//#define START_KERNEL_JACOBI +#define START_MMNIF_TEST +#endif +#define START_ECHO +//#define START_NETIO +//#define START_CONSUMER_PRODUCER +#define START_FOO +//#define START_JOIN_TEST +//#define START_PI +//#define START_MEASURE_CTX_SWITCH +//#define START_HELLO +#define START_TESTS +//#define START_JACOBI + +// does our demos require GFX support? +//#define CONFIG_GFX + +#endif diff --git a/kernel/init.c b/kernel/init.c index f8deaed2..ba1774d7 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -50,8 +50,6 @@ #include #endif -void echo_init(void); -void netio_init(void); int test_init(void); /* @@ -302,13 +300,10 @@ int initd(void* arg) } #endif - // start echo, netio and rlogind - echo_init(); #if !NO_SYS create_user_task(&id, "/bin/rlogind", argv); kprintf("Create rlogind with id %u\n", id); #endif - //netio_init(); #endif // list_root(); From 6013c2ec4d0bf36ef346626e3242bbde0e774a89 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Mon, 16 Jul 2012 23:05:46 +0200 Subject: [PATCH 4/4] add memory barriers to seralize load and store operations => required to clone a task --- arch/x86/kernel/gdt.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/kernel/gdt.c b/arch/x86/kernel/gdt.c index 5861a978..384d9cb8 100644 --- a/arch/x86/kernel/gdt.c +++ b/arch/x86/kernel/gdt.c @@ -67,7 +67,9 @@ int arch_fork(task_t* task) id = task->id; // copy kernel stack of the current task + mb(); memcpy(kstacks[id], kstacks[curr_task->id], KERNEL_STACK_SIZE); + mb(); #ifdef CONFIG_X86_32 asm volatile ("mov %%esp, %0" : "=r"(esp));