From ecaf09a41b000630d1889349b32d8db44a7f2538 Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Thu, 30 Jan 2014 10:19:17 +0100 Subject: [PATCH] nova: extent ec_ctrl in kernel and base-nova The commit switches the kernel branch to r5 and updates the syscall bindings in base-nova accordingly. Beside some cleanups, r5 extents the ec_ctrl syscall to support following features: * An EC may yield its current timeslice. The timeslice gets enqueued at the end of the run queue without refreshing the left budget of the quantum. * An EC helps with the current SC another EC. Used in Genode to implement helping over a user-level lock to avoid live-lock situation. (Think of a limited priority-inheritance mechanism.) * An EC requests a new scheduler decision. Used in Genode to transfer back the potentially helping SC to the helper EC. Issue #986 --- base-nova/Makefile | 2 +- base-nova/include/32bit/nova/syscalls.h | 4 +- base-nova/include/64bit/nova/syscalls.h | 4 +- base-nova/include/nova/syscall-generic.h | 2 +- base-nova/patches/yield.patch | 116 ----------------------- 5 files changed, 6 insertions(+), 122 deletions(-) delete mode 100644 base-nova/patches/yield.patch diff --git a/base-nova/Makefile b/base-nova/Makefile index 54a839efa..f77c2aae7 100644 --- a/base-nova/Makefile +++ b/base-nova/Makefile @@ -9,7 +9,7 @@ VERBOSE ?= @ ECHO = @echo GIT_URL = https://github.com/alex-ab/NOVA.git GIT_REV = HEAD -GIT_BRANCH = r4 +GIT_BRANCH = r5 CONTRIB_DIR = contrib PATCHES = $(shell find patches -name '*.patch') diff --git a/base-nova/include/32bit/nova/syscalls.h b/base-nova/include/32bit/nova/syscalls.h index c0b9bc8d3..7cae332ed 100644 --- a/base-nova/include/32bit/nova/syscalls.h +++ b/base-nova/include/32bit/nova/syscalls.h @@ -210,9 +210,9 @@ namespace Nova { ALWAYS_INLINE - inline uint8_t ec_ctrl(Ec_op op, unsigned para = ~0UL) + inline uint8_t ec_ctrl(Ec_op op, mword_t ec = ~0UL, mword_t para = ~0UL) { - return syscall_0(NOVA_EC_CTRL, op, para); + return syscall_1(NOVA_EC_CTRL, op, ec, para); } diff --git a/base-nova/include/64bit/nova/syscalls.h b/base-nova/include/64bit/nova/syscalls.h index 0408c1e02..fb1c2ec0f 100644 --- a/base-nova/include/64bit/nova/syscalls.h +++ b/base-nova/include/64bit/nova/syscalls.h @@ -173,9 +173,9 @@ namespace Nova { ALWAYS_INLINE - inline uint8_t ec_ctrl(Ec_op op, mword_t ec = ~0UL) + inline uint8_t ec_ctrl(Ec_op op, mword_t ec = ~0UL, mword_t para = ~0UL) { - return syscall_0(NOVA_EC_CTRL, op, ec); + return syscall_1(NOVA_EC_CTRL, op, ec, para); } diff --git a/base-nova/include/nova/syscall-generic.h b/base-nova/include/nova/syscall-generic.h index 2f63dacfc..9f75a86ad 100644 --- a/base-nova/include/nova/syscall-generic.h +++ b/base-nova/include/nova/syscall-generic.h @@ -150,7 +150,7 @@ namespace Nova { /** * Ec operations */ - enum Ec_op { EC_RECALL = 0U, EC_YIELD = 1U }; + enum Ec_op { EC_RECALL = 0U, EC_YIELD = 1U, EC_DONATE_SC = 2U, EC_RESCHEDULE = 3U }; class Descriptor diff --git a/base-nova/patches/yield.patch b/base-nova/patches/yield.patch deleted file mode 100644 index 968e184c1..000000000 --- a/base-nova/patches/yield.patch +++ /dev/null @@ -1,116 +0,0 @@ -diff --git a/include/sc.hpp b/include/sc.hpp -index b849a1f..b480050 100644 ---- a/include/sc.hpp -+++ b/include/sc.hpp -@@ -54,7 +54,7 @@ class Sc : public Kobject, public Refcount - - static unsigned prio_top CPULOCAL; - -- void ready_enqueue (uint64); -+ void ready_enqueue (uint64, bool use_left = true); - void ready_dequeue (uint64); - - static void free (Rcu_elem * a) { -@@ -90,7 +90,7 @@ class Sc : public Kobject, public Refcount - static void rke_handler(); - - NORETURN -- static void schedule (bool = false); -+ static void schedule (bool = false, bool = true); - - ALWAYS_INLINE - static inline void *operator new (size_t) { return cache.alloc(); } -diff --git a/include/syscall.hpp b/include/syscall.hpp -index 59e4489..5d61f1e 100644 ---- a/include/syscall.hpp -+++ b/include/syscall.hpp -@@ -138,6 +138,9 @@ class Sys_ec_ctrl : public Sys_regs - public: - ALWAYS_INLINE - inline unsigned long ec() const { return ARG_1 >> 8; } -+ -+ ALWAYS_INLINE -+ inline unsigned op() const { return flags() & 0x3; } - }; - - class Sys_sc_ctrl : public Sys_regs -diff --git a/src/sc.cpp b/src/sc.cpp -index 53ff07b..bc4dfa2 100644 ---- a/src/sc.cpp -+++ b/src/sc.cpp -@@ -52,7 +52,7 @@ Sc::Sc (Pd *own, Ec *e, unsigned c, Sc *x) : Kobject (SC, static_castprev; - next->prev = prev->next = this; -- if (left) -+ if (use_left && left) - list[prio] = this; - } - - trace (TRACE_SCHEDULE, "ENQ:%p (%02u) PRIO:%#x TOP:%#x %s", this, left, prio, prio_top, prio > current->prio ? "reschedule" : ""); - -- if (prio > current->prio || (this != current && prio == current->prio && left)) -+ if (prio > current->prio || (this != current && prio == current->prio && (use_left && left))) - Cpu::hazard |= HZD_SCHED; - - if (!left) -@@ -106,7 +106,7 @@ void Sc::ready_dequeue (uint64 t) - tsc = t; - } - --void Sc::schedule (bool suspend) -+void Sc::schedule (bool suspend, bool use_left) - { - Counter::print<1,16> (++Counter::schedule, Console_vga::COLOR_LIGHT_CYAN, SPN_SCH); - -@@ -123,7 +123,7 @@ void Sc::schedule (bool suspend) - delete current; - else - if (EXPECT_TRUE (!suspend)) -- current->ready_enqueue (t); -+ current->ready_enqueue (t, use_left); - - Sc *sc = list[prio_top]; - assert (sc); -diff --git a/src/syscall.cpp b/src/syscall.cpp -index 975d4dc..6e792b0 100644 ---- a/src/syscall.cpp -+++ b/src/syscall.cpp -@@ -409,6 +412,9 @@ void Ec::sys_ec_ctrl() - { - Sys_ec_ctrl *r = static_cast(current->sys_regs()); - -+ switch (r->op()) { -+ case 0: -+{ - Capability cap = Space_obj::lookup (r->ec()); - if (EXPECT_FALSE (cap.obj()->type() != Kobject::EC || !(cap.prm() & 1UL << 0))) { - trace (TRACE_ERROR, "%s: Bad EC CAP (%#lx)", __func__, r->ec()); -@@ -423,6 +429,18 @@ void Ec::sys_ec_ctrl() - - if (Cpu::id != ec->cpu && Ec::remote (ec->cpu) == ec) - Lapic::send_ipi (ec->cpu, VEC_IPI_RKE); -+ -+ } -+} -+ break; -+ -+ case 1: -+ current->cont = sys_finish; -+ Sc::schedule (false, false); -+ break; -+ -+ default: -+ sys_finish(); - } - - sys_finish();