From dd95266235f2bd2b200bb4394a6b04b8710e44ce Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Thu, 30 Jan 2014 10:19:17 +0100 Subject: [PATCH] nova: add feature to yield a thread used by virtualbox intensively --- base-nova/include/32bit/nova/syscalls.h | 4 +- base-nova/include/64bit/nova/syscalls.h | 4 +- base-nova/include/nova/syscall-generic.h | 5 + base-nova/patches/yield.patch | 116 +++++++++++++++++++++++ base-nova/src/base/lock/lock_helper.h | 2 +- base-nova/src/base/pager/pager.cc | 2 +- ports/src/vancouver/main.cc | 2 +- 7 files changed, 128 insertions(+), 7 deletions(-) create mode 100644 base-nova/patches/yield.patch diff --git a/base-nova/include/32bit/nova/syscalls.h b/base-nova/include/32bit/nova/syscalls.h index 63aed3dd25..c0b9bc8d37 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(unsigned ec) + inline uint8_t ec_ctrl(Ec_op op, unsigned para = ~0UL) { - return syscall_0(NOVA_EC_CTRL, 0, ec); + return syscall_0(NOVA_EC_CTRL, op, para); } diff --git a/base-nova/include/64bit/nova/syscalls.h b/base-nova/include/64bit/nova/syscalls.h index 9cea3e01dc..0408c1e02c 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(mword_t ec) + inline uint8_t ec_ctrl(Ec_op op, mword_t ec = ~0UL) { - return syscall_0(NOVA_EC_CTRL, 0, ec); + return syscall_0(NOVA_EC_CTRL, op, ec); } diff --git a/base-nova/include/nova/syscall-generic.h b/base-nova/include/nova/syscall-generic.h index a50c0d59e9..3af054f8a6 100644 --- a/base-nova/include/nova/syscall-generic.h +++ b/base-nova/include/nova/syscall-generic.h @@ -147,6 +147,11 @@ namespace Nova { */ enum Sem_op { SEMAPHORE_UP = 0U, SEMAPHORE_DOWN = 1U, SEMAPHORE_DOWNZERO = 0x3U }; + /** + * Ec operations + */ + enum Ec_op { EC_RECALL = 0U, EC_YIELD = 1U }; + class Descriptor { diff --git a/base-nova/patches/yield.patch b/base-nova/patches/yield.patch new file mode 100644 index 0000000000..968e184c11 --- /dev/null +++ b/base-nova/patches/yield.patch @@ -0,0 +1,116 @@ +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(); diff --git a/base-nova/src/base/lock/lock_helper.h b/base-nova/src/base/lock/lock_helper.h index 8af4a1c0a9..779f38bf25 100644 --- a/base-nova/src/base/lock/lock_helper.h +++ b/base-nova/src/base/lock/lock_helper.h @@ -41,7 +41,7 @@ Genode::Thread_base * __attribute__((weak)) Genode::Thread_base::myself() } -static inline void thread_yield() { } +static inline void thread_yield() { Nova::ec_ctrl(Nova::EC_YIELD); } static inline bool thread_check_stopped_and_restart(Genode::Thread_base *thread_base) diff --git a/base-nova/src/base/pager/pager.cc b/base-nova/src/base/pager/pager.cc index 0b55e4e829..1d921aad7e 100644 --- a/base-nova/src/base/pager/pager.cc +++ b/base-nova/src/base/pager/pager.cc @@ -296,7 +296,7 @@ void Pager_object::client_cancel_blocking() uint8_t Pager_object::client_recall() { - return ec_ctrl(_state.sel_client_ec); + return ec_ctrl(EC_RECALL, _state.sel_client_ec); } diff --git a/ports/src/vancouver/main.cc b/ports/src/vancouver/main.cc index b23254ca60..1e02545d68 100644 --- a/ports/src/vancouver/main.cc +++ b/ports/src/vancouver/main.cc @@ -940,7 +940,7 @@ class Machine : public StaticReceiver return false; } } - return (Nova::ec_ctrl(msg.value + 1) == 0); + return (Nova::ec_ctrl(Nova::EC_RECALL, msg.value + 1) == 0); case MessageHostOp::OP_VCPU_BLOCK: {