diff --git a/3rdparty/musl b/3rdparty/musl index 9680582a..790bd394 160000 --- a/3rdparty/musl +++ b/3rdparty/musl @@ -1 +1 @@ -Subproject commit 9680582a257de9d20b94ee26ddf6f9dc10df948e +Subproject commit 790bd3943e419933cf56366197b9f6668ae8c53e diff --git a/Makefile.user b/Makefile.user index bf438808..56127727 100644 --- a/Makefile.user +++ b/Makefile.user @@ -10,6 +10,7 @@ CPPFLAGS+= -DMLOG_PORTAL=FilterError CPPFLAGS+= -DMLOG_SCHED=FilterError CPPFLAGS+= -DMLOG_SYSCALL=FilterError CPPFLAGS+= -DMLOG_TASKLET=FilterError +CPPFLAGS+= -DMLOG_PROCESSORMGMT=FilterWarning #CPPFLAGS+= -DTRACE #CPPFLAGS+= -DNDEBUG diff --git a/kernel-amd64.config b/kernel-amd64.config index 76a8bc4f..d311f6d9 100644 --- a/kernel-amd64.config +++ b/kernel-amd64.config @@ -19,6 +19,7 @@ "plugin-rapl-driver-intel", "app-init-example", "test-synchronous-task", + "plugin-processor-allocator" ] [config.vars] diff --git a/kernel/app/init-example/app/init.cc b/kernel/app/init-example/app/init.cc index 5a009a4f..8b6045da 100644 --- a/kernel/app/init-example/app/init.cc +++ b/kernel/app/init-example/app/init.cc @@ -28,6 +28,7 @@ #include "mythos/invocation.hh" #include "mythos/protocol/CpuDriverKNC.hh" #include "mythos/PciMsgQueueMPSC.hh" +#include "mythos/InfoFrame.hh" #include "runtime/Portal.hh" #include "runtime/ExecutionContext.hh" #include "runtime/CapMap.hh" @@ -36,6 +37,7 @@ #include "runtime/PageMap.hh" #include "runtime/KernelMemory.hh" #include "runtime/SimpleCapAlloc.hh" +#include "runtime/ProcessorAllocator.hh" #include "runtime/tls.hh" #include "runtime/mlog.hh" #include "runtime/InterruptControl.hh" @@ -56,7 +58,7 @@ #include -mythos::InvocationBuf* msg_ptr asm("msg_ptr"); +mythos::InfoFrame* info_ptr asm("info_ptr"); int main() asm("main"); extern char process_test_image_start SYMBOL("process_test_image_start"); @@ -65,7 +67,7 @@ constexpr uint64_t stacksize = 4*4096; char initstack[stacksize]; char* initstack_top = initstack+stacksize; -mythos::Portal portal(mythos::init::PORTAL, msg_ptr); +mythos::Portal portal(mythos::init::PORTAL, info_ptr->getInvocationBuf()); mythos::CapMap myCS(mythos::init::CSPACE); mythos::PageMap myAS(mythos::init::PML4); mythos::KernelMemory kmem(mythos::init::KM); @@ -73,6 +75,7 @@ mythos::KObject device_memory(mythos::init::DEVICE_MEM); mythos::SimpleCapAlloc< mythos::init::APP_CAP_START , mythos::init::SIZE-mythos::init::APP_CAP_START> capAlloc(myCS); mythos::RaplDriverIntel rapl(mythos::init::RAPL_DRIVER_INTEL); +mythos::ProcessorAllocator pa(mythos::init::PROCESSOR_ALLOCATOR); char threadstack[stacksize]; char* thread1stack_top = threadstack+stacksize/2; @@ -103,7 +106,7 @@ void test_Portal() MLOG_ERROR(mlog::app, "test_Portal begin"); mythos::PortalLock pl(portal); // future access will fail if the portal is in use already MLOG_INFO(mlog::app, "test_Portal: allocate portal"); - uintptr_t vaddr = mythos::round_up(uintptr_t(msg_ptr) + 1, mythos::align2M); + uintptr_t vaddr = mythos::round_up(info_ptr->getInfoEnd(), mythos::align2M); // allocate a portal mythos::Portal p2(capAlloc(), (void*)vaddr); auto res1 = p2.create(pl, kmem).wait(); @@ -185,7 +188,9 @@ void test_tls() auto tls = mythos::setupNewTLS(); MLOG_INFO(mlog::app, "test_EC: create ec1 TLS", DVARhex(tls)); ASSERT(tls != nullptr); - auto res1 = ec1.create(kmem).as(myAS).cs(myCS).sched(mythos::init::SCHEDULERS_START + 1) + auto sc = pa.alloc(pl).wait(); + TEST(sc); + auto res1 = ec1.create(kmem).as(myAS).cs(myCS).sched(sc->cap) .prepareStack(thread1stack_top).startFun(threadFun, nullptr) .suspended(false).fs(tls) .invokeVia(pl).wait(); @@ -193,6 +198,7 @@ void test_tls() TEST(ec1.setFSGS(pl,(uint64_t) tls, 0).wait()); mythos::syscall_signal(ec1.cap()); MLOG_INFO(mlog::app, "End test tls"); + capAlloc.free(ec1.cap(), pl); } @@ -201,7 +207,7 @@ void test_heap() { mythos::PortalLock pl(portal); auto size = 4*1024*1024; // 2 MB auto align = 2*1024*1024; // 2 MB - uintptr_t vaddr = mythos::round_up(uintptr_t(msg_ptr) + 1, align); + uintptr_t vaddr = mythos::round_up(info_ptr->getInfoEnd() + align2M, align2M); // allocate a 2MiB frame mythos::Frame f(capAlloc()); auto res2 = f.create(pl, kmem, size, align).wait(); @@ -322,7 +328,9 @@ void test_ExecutionContext() auto tls1 = mythos::setupNewTLS(); ASSERT(tls1 != nullptr); - auto res1 = ec1.create(kmem).as(myAS).cs(myCS).sched(mythos::init::SCHEDULERS_START) + auto sc1 = pa.alloc(pl).wait(); + TEST(sc1); + auto res1 = ec1.create(kmem).as(myAS).cs(myCS).sched(sc1->cap) .prepareStack(thread1stack_top).startFun(&thread_main, nullptr) .suspended(false).fs(tls1) .invokeVia(pl).wait(); @@ -331,7 +339,9 @@ void test_ExecutionContext() MLOG_INFO(mlog::app, "test_EC: create ec2"); auto tls2 = mythos::setupNewTLS(); ASSERT(tls2 != nullptr); - auto res2 = ec2.create(kmem).as(myAS).cs(myCS).sched(mythos::init::SCHEDULERS_START+1) + auto sc2 = pa.alloc(pl).wait(); + TEST(sc2); + auto res2 = ec2.create(kmem).as(myAS).cs(myCS).sched(sc2->cap) .prepareStack(thread2stack_top).startFun(&thread_main, nullptr) .suspended(false).fs(tls2) .invokeVia(pl).wait(); @@ -345,6 +355,11 @@ void test_ExecutionContext() MLOG_INFO(mlog::app, "sending notifications"); mythos::syscall_signal(ec1.cap()); mythos::syscall_signal(ec2.cap()); + { + mythos::PortalLock pl(portal); + TEST(capAlloc.free(ec1, pl)); + TEST(capAlloc.free(ec2, pl)); + } MLOG_INFO(mlog::app, "End Test ExecutionContext"); } @@ -357,7 +372,9 @@ void test_InterruptControl() { mythos::ExecutionContext ec(capAlloc()); auto tls = mythos::setupNewTLS(); ASSERT(tls != nullptr); - auto res1 = ec.create(kmem).as(myAS).cs(myCS).sched(mythos::init::SCHEDULERS_START + 2) + auto sc = pa.alloc(pl).wait(); + TEST(sc); + auto res1 = ec.create(kmem).as(myAS).cs(myCS).sched(sc->cap) .prepareStack(thread3stack_top).startFun(&thread_main, nullptr) .suspended(false).fs(tls) .invokeVia(pl).wait(); @@ -480,21 +497,45 @@ void test_CgaScreen(){ MLOG_INFO(mlog::app, "Test CGA finished"); } +void test_processor_allocator(){ + MLOG_INFO(mlog::app, "Test processor allocator"); + mythos::PortalLock pl(portal); + auto sc = pa.alloc(pl).wait(); + TEST(sc); + auto res = pa.free(pl, sc->cap).wait(); + TEST(res); + MLOG_INFO(mlog::app, "Test processor allocator finished"); +} + void test_process(){ MLOG_INFO(mlog::app, "Test process"); mythos::PortalLock pl(portal); + Process p(&process_test_image_start); p.createProcess(pl); MLOG_INFO(mlog::app, "Test process finished"); } +void test_userMem(){ + MLOG_INFO(mlog::app, "Test user memory"); + auto ranges = &info_ptr->memRanges; + + // All memory that exceeds kernel memory address range (4G) will be provided directly to user. + // Run mythos (qemu/IHK) with more than 4G of memory to get some output + for(auto& r : *ranges){ + MLOG_INFO(mlog::app, "range", DMRANGE(r.getStart(), r.getSize())); + } + + MLOG_INFO(mlog::app, "Test user memory finished"); +}; + int main() { char const str[] = "Hello world!"; mythos::syscall_debug(str, sizeof(str)-1); - MLOG_ERROR(mlog::app, "application is starting :)", DVARhex(msg_ptr), DVARhex(initstack_top)); + MLOG_ERROR(mlog::app, "application is starting :)", DVARhex(info_ptr), DVARhex(initstack_top)); test_float(); test_Example(); @@ -506,7 +547,9 @@ int main() //test_HostChannel(portal, 24*1024*1024, 2*1024*1024); test_ExecutionContext(); test_pthreads(); - //test_Rapl(); + test_userMem(); + test_Rapl(); + test_processor_allocator(); test_process(); //test_CgaScreen(); diff --git a/kernel/app/process_test/process_test/process_test.cc b/kernel/app/process_test/process_test/process_test.cc index 10a09766..1a23ffa0 100644 --- a/kernel/app/process_test/process_test/process_test.cc +++ b/kernel/app/process_test/process_test/process_test.cc @@ -26,6 +26,7 @@ #include "mythos/init.hh" #include "mythos/invocation.hh" +#include "mythos/InfoFrame.hh" #include "runtime/Portal.hh" #include "runtime/ExecutionContext.hh" #include "runtime/CapMap.hh" @@ -34,6 +35,7 @@ #include "runtime/PageMap.hh" #include "runtime/KernelMemory.hh" #include "runtime/SimpleCapAlloc.hh" +#include "runtime/ProcessorAllocator.hh" #include "runtime/tls.hh" #include "runtime/mlog.hh" #include "runtime/InterruptControl.hh" @@ -43,14 +45,14 @@ #include "runtime/Mutex.hh" -mythos::InvocationBuf* msg_ptr asm("msg_ptr"); +mythos::InfoFrame* info_ptr asm("info_ptr"); int main() asm("main"); constexpr uint64_t stacksize = 4*4096; char initstack[stacksize]; char* initstack_top = initstack+stacksize; -mythos::Portal portal(mythos::init::PORTAL, msg_ptr); +mythos::Portal portal(mythos::init::PORTAL, info_ptr->getInvocationBuf()); mythos::CapMap myCS(mythos::init::CSPACE); mythos::PageMap myAS(mythos::init::PML4); mythos::KernelMemory kmem(mythos::init::KM); @@ -58,11 +60,13 @@ mythos::KObject device_memory(mythos::init::DEVICE_MEM); mythos::SimpleCapAlloc< mythos::init::APP_CAP_START , mythos::init::SIZE-mythos::init::APP_CAP_START> capAlloc(myCS); mythos::RaplDriverIntel rapl(mythos::init::RAPL_DRIVER_INTEL); +mythos::ProcessorAllocator pa(mythos::init::PROCESSOR_ALLOCATOR); int main() { MLOG_ERROR(mlog::app, "New process started :)"); + MLOG_INFO(mlog::app, "info frame", DVARhex(info_ptr), DVAR(info_ptr->getNumThreads()), DVAR(info_ptr->getPsPerTSC())); return 0; } diff --git a/kernel/async/monitor-common/async/Place.hh b/kernel/async/monitor-common/async/Place.hh index 571bbb8f..8b60fe9a 100644 --- a/kernel/async/monitor-common/async/Place.hh +++ b/kernel/async/monitor-common/async/Place.hh @@ -113,6 +113,8 @@ public: /** true if the hardware thread is currently in kernel mode and processing tasks. */ bool isActive() const { return nestingMonitor.load(std::memory_order_relaxed); } + cpu::ThreadID getThreadID(){ return threadID; } + protected: void pushPrivate(TaskletBase* msg) { ASSERT(isLocal()); diff --git a/kernel/boot/init-loader-amd64/boot/load_init.cc b/kernel/boot/init-loader-amd64/boot/load_init.cc index 5e00f6f3..26c81c7a 100644 --- a/kernel/boot/init-loader-amd64/boot/load_init.cc +++ b/kernel/boot/init-loader-amd64/boot/load_init.cc @@ -44,11 +44,14 @@ #include "boot/mlog.hh" #include "boot/memory-root.hh" #include "boot/DeployHWThread.hh" +#include "mythos/InfoFrame.hh" namespace mythos { Event event::initLoader; +Event event::initLoaderEarly; +Event event::initInfoFrame; namespace boot { @@ -59,6 +62,9 @@ InitLoader::InitLoader(char* image) , capAlloc(init::CAP_ALLOC_START, init::CAP_ALLOC_END-init::CAP_ALLOC_START) , memMapper(&capAlloc, mythos::init::KM) + // default: no processor allocator present + , processorAllocatorPresent(false) + , initSC(init::SCHEDULERS_START) { MLOG_INFO(mlog::boot, "found init application image at", (void*)image); } @@ -69,13 +75,17 @@ optional InitLoader::load() { if (!_img.isValid()) RETURN(Error::GENERIC_ERROR); + event::initLoaderEarly.emit(*this); + // order matters here optional res(Error::SUCCESS); if (res) res = initCSpace(); auto ipc_vaddr = loadImage(); res = ipc_vaddr; - if (res) MLOG_INFO(mlog::boot, "init invokation buffer", DVARhex(*ipc_vaddr)); - if (res) res = createPortal(*ipc_vaddr, init::PORTAL); + if (res) MLOG_INFO(mlog::boot, "init info frame/invokation buffer", DVARhex(*ipc_vaddr)); + auto infoFramePtr = createInfoFrame(*ipc_vaddr); + res = infoFramePtr; + if (res) res = createPortal(*infoFramePtr, init::PORTAL); if (res) res = createEC(*ipc_vaddr); RETURN(res); } @@ -157,12 +167,14 @@ optional InitLoader::initCSpace() if (!res) RETHROW(res); } - ASSERT(cpu::getNumThreads() <= init::SCHEDULERS_START - init::APP_CAP_START); - MLOG_INFO(mlog::boot, "... create scheduling context caps in caps", - init::SCHEDULERS_START, "till", init::SCHEDULERS_START+cpu::getNumThreads()-1); - for (cpu::ThreadID id = 0; id < cpu::getNumThreads(); ++id) { - auto res = csSet(init::SCHEDULERS_START+id, boot::getScheduler(id)); - if (!res) RETHROW(res); + if(!processorAllocatorPresent){ + ASSERT(cpu::getNumThreads() <= init::SCHEDULERS_START - init::APP_CAP_START); + MLOG_INFO(mlog::boot, "... create scheduling context caps in caps", + init::SCHEDULERS_START, "till", init::SCHEDULERS_START+cpu::getNumThreads()-1); + for (cpu::ThreadID id = 0; id < cpu::getNumThreads(); ++id) { + auto res = csSet(init::SCHEDULERS_START+id, boot::getScheduler(id)); + if (!res) RETHROW(res); + } } ASSERT(cpu::getNumThreads() <= init::INTERRUPT_CONTROL_START - init::APP_CAP_START); @@ -178,20 +190,39 @@ optional InitLoader::initCSpace() RETURN(Error::SUCCESS); } +optional InitLoader::createInfoFrame(uintptr_t ipc_vaddr) +{ + auto size = round_up(sizeof(InfoFrame), align2M); + MLOG_INFO(mlog::boot, "... create info frame"); + auto frameCap = memMapper.createFrame(init::INFO_FRAME, size, align2M); + if (!frameCap) RETHROW(frameCap); + MLOG_INFO(mlog::boot, "... map info frame", + DVAR(*frameCap), DVARhex(ipc_vaddr)); + memMapper.mmap(ipc_vaddr, size, true, false, *frameCap, 0); + + auto frameEntry = capAlloc.get(*frameCap); + if (!frameEntry) RETHROW(frameEntry); + TypedCap